aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.md.md5
-rw-r--r--INSTALL.md10
-rw-r--r--MeTaDaTa.md4
-rw-r--r--README12
-rw-r--r--README.md.md1
-rwxr-xr-xSuckIt162
-rwxr-xr-xSuckItClean13
-rwxr-xr-xSuckItCron4
-rwxr-xr-xSuckItFos60
-rwxr-xr-xSuckItPm63
-rw-r--r--TODO.md101
-rw-r--r--about/index.md8
-rw-r--r--default.template137
-rw-r--r--empty.md1
-rwxr-xr-xfeed-icon-14x14.pngbin0 -> 689 bytes
-rwxr-xr-xfeed-icon-28x28.pngbin0 -> 1737 bytes
-rw-r--r--help.md43
-rw-r--r--menu.template2
-rw-r--r--nYAW.pngbin12273 -> 16624 bytes
-rw-r--r--nYAW.xcfbin20267 -> 25929 bytes
-rwxr-xr-xnotYetAnotherWiki.lua1018
-rw-r--r--testing/.md.md1
-rw-r--r--testing/MeTaDaTa.md3
-rw-r--r--testing/index.md114
-rw-r--r--testing/index.md.md1
25 files changed, 1349 insertions, 414 deletions
diff --git a/.md.md b/.md.md
new file mode 100644
index 0000000..4a55e50
--- /dev/null
+++ b/.md.md
@@ -0,0 +1,5 @@
1favicon=nYAW_icon.png
2logo=nYAW.png
3sourcecode=https://sledjhamr.org/cgit/notYetAnotherWiki/
4pagehistory=https://sledjhamr.org/cgit/notYetAnotherWiki/log
5feedatom=https://sledjhamr.org/cgit/notYetAnotherWiki/atom
diff --git a/INSTALL.md b/INSTALL.md
index 2d01caf..a2b2842 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,13 +1,7 @@
1--- 1# Install
2pagetitle: "INSTALL"
3author: onefang
4pagehistory: https://sledjhamr.org/cgit/notYetAnotherWiki/log/INSTALL.md
5---
6 2
7notYetAnotherWiki uses [lcmark](https://github.com/jgm/lcmark) to parse [CommonMark](https://commonmark.org/) into HTML. You can probably install it using luarocks. lua-yaml is the YAML parsing library I test with. 3notYetAnotherWiki uses [lunamark](https://github.com/jgm/lunamark) to parse [CommonMark](https://commonmark.org/) into HTML. You can probably install it using luarocks. lua-yaml is the YAML parsing library I test with.
8 4
9You also need luajit installed. 5You also need luajit installed.
10 6
11Copy the notYetAnotherWiki.lua script to some place where you can run it from, /usr/local/bin is good. Make sure it is executable. 7Copy the notYetAnotherWiki.lua script to some place where you can run it from, /usr/local/bin is good. Make sure it is executable.
12
13Similar with the dumpTable.lua script, only it's a Lua library, so put it some place Lua can find it. /usr/local/share/lua is good. No need to be executable.
diff --git a/MeTaDaTa.md b/MeTaDaTa.md
deleted file mode 100644
index ab7b673..0000000
--- a/MeTaDaTa.md
+++ /dev/null
@@ -1,4 +0,0 @@
1---
2feedatom: https://sledjhamr.org/cgit/notYetAnotherWiki/atom
3sourcecode: https://sledjhamr.org/cgit/notYetAnotherWiki/
4---
diff --git a/README b/README
index 444578e..954bc7a 100644
--- a/README
+++ b/README
@@ -1,8 +1,4 @@
1--- 1# notYetAnotherWiki
2pagetitle: "notYetAnotherWiki"
3author: onefang
4pagehistory: https://sledjhamr.org/cgit/notYetAnotherWiki/log/index.md
5---
6 2
7notYetAnotherWiki is not another wiki, at least not yet. It'll be much 3notYetAnotherWiki is not another wiki, at least not yet. It'll be much
8more than that, eventually. 4more than that, eventually.
@@ -63,13 +59,13 @@ the one system. They can chat about it, on the one system.
63 59
64## What does it do already? 60## What does it do already?
65 61
66Currently it'll scan the current directory and subdirectories looking for 62Currently it'll scan the current folder and sub folders looking for
67.md files in CommonMark syntax. This should cover some MarkDown 63.md files in CommonMark syntax. This should cover some MarkDown
68variations. Then it produces .HTML files converted from these .md files, 64variations. Then it produces .HTML files converted from these .md files,
69and links them all together into a web site. 65and links them all together into a web site.
70 66
71Any .md file that is just the beginning metadata block doesn't get 67Any .md file that is just the beginning metadata block doesn't get
72rendered into HTML, but is global metadata for this directory and subs, 68rendered into HTML, but is global metadata for this folder and subs,
73though the subs can override this with their own metadata.md files. 69though the subs can override this with their own metadata.md files.
74 70
75git is used to store the .md files, and provides edit history. Added on 71git is used to store the .md files, and provides edit history. Added on
@@ -77,7 +73,7 @@ the footer is links to cgit, which is used to store the files in git on
77your server. This provides acces to the source code, history, and ATOM 73your server. This provides acces to the source code, history, and ATOM
78feed for the site. 74feed for the site.
79 75
80It can also scan an external directory and merge that with the current 76It can also scan an external folder and merge that with the current
81one, but this isn't tested yet. 77one, but this isn't tested yet.
82 78
83## other stuff 79## other stuff
diff --git a/README.md.md b/README.md.md
new file mode 100644
index 0000000..31ea1e7
--- /dev/null
+++ b/README.md.md
@@ -0,0 +1 @@
title=nYAW
diff --git a/SuckIt b/SuckIt
new file mode 100755
index 0000000..38fe18e
--- /dev/null
+++ b/SuckIt
@@ -0,0 +1,162 @@
1#!/bin/bash
2
3TIMEFORMAT=" took %lR using %P%% CPU"
4time {
5pushd /opt/nyaw
6
7#rm -fr Foswiki/*
8cp -r /opt/nyaw_EMPTY/Foswiki .
9#rm -fr PmWiki/*
10cp -r /opt/nyaw_EMPTY/PmWiki .
11#rm -fr unsorted
12mkdir -p unsorted
13cp -r /opt/nyaw_EMPTY/unsorted .
14#rm -fr users/*
15mkdir -p users
16cp -r /opt/nyaw_EMPTY/users .
17
18# Copy across things like images that where uploaded.
19mkdir -p /opt/nyaw/Foswiki/pub/
20# TODO - Should rsync this instead.
21cp -r /opt/Foswiki/pub/Main /opt/nyaw/Foswiki/pub/
22filter="
23 -name _default -prune -o \
24 -name _empty -prune -o \
25 -name System -prune -o \
26 -name Trash -prune -o \
27 -name TWiki -prune -o \
28"
29ogURL="https://fos.wiki.devuan.org"
30ogWiki="Foswiki"
31time find /opt/Foswiki/data ${filter} \
32-name "*.txt" -type f,l -printf "%P\n" | while read line
33do
34 base=`echo "${line}" | cut -d '/' -f 1`
35 file=`echo "${line}" | cut -d '/' -f 2- | rev | cut -b 5- | rev`
36 if [[ ! ${file} =~ (AdminGroup|AdminUser|AdminUserLeftBar|CommentPluginExamples|EditorGroup|GroupTemplate|GroupViewTemplate|NobodyGroup|PatternSkinUserViewTemplate|ProjectContributor|RegistrationAgent|SitePreferences|UnprocessedRegistrations|UnprocessedRegistrationsLog|UserHomepageHeader|UserList|UserListByDateJoined|UserListByLocation|UserList|UserListHeader|WebAtom|WebChanges|WebCreateNewTopic|WebHome|WebIndex|WebLeftBar|WebLeftBarExample|WebNotify|WebPreferences|WebRss|WebSearch|WebSearchAdvanced|WebTopicList|WikiGroups|WikiUsers)$ ]]; then
37 doit='false'
38 if [ ! -s ${ogWiki}/${base}/${file}.HTM ]; then
39 echo "NEW /opt/Foswiki/data/${base}/${file}.txt"
40 doit='true'
41 elif [ /opt/Foswiki/data/${base}/${file}.txt -nt ${ogWiki}/${base}/${file}.HTM ]; then
42 echo "NEWER /opt/Foswiki/data/${base}/${file}.txt"
43 date --rfc-3339=seconds -ur /opt/Foswiki/data/${base}/${file}.txt
44 date --rfc-3339=seconds -ur ${ogWiki}/${base}/${file}.HTM
45 doit='true'
46 fi
47 if [[ ${doit} == "true" ]]; then
48 realURL=${ogWiki}/${base}/${file}
49 time=`date --rfc-3339=seconds -ur /opt/Foswiki/data/${base}/${file}.txt | cut -d '+' -f 1`
50 mkdir -p ${ogWiki}/${base}
51 mkdir -p ${ogWiki}/${base}/`dirname ${file}`
52 echo -e "ogWiki=${ogWiki}\nogURL=${ogURL}\nrealURL=${realURL}\nogBase=${base}\nogFile=${file}\ntimestamp=${time}\n" > ${ogWiki}/${base}/${file}.md.md
53 echo "downloading ${ogURL}/${base}/${file}?cover=print"
54 # Doesn't help with redownloads, coz natch a dynamic site isn't cached. But I can at least comment out the curl command during testing to save time.
55 curl --silent --no-progress-meter ${ogURL}/${base}/${file}?cover=print -o ${ogWiki}/${base}/${file}.HTM
56 # Attempt to separate user profiles from user content. Doesn't work when people turn their profiles into content.
57 dest=""
58 if [[ "${base}" == "Main" ]]; then
59 dest="unsorted"
60 if [ -L users/${file}_fos.md ]; then
61 dest='users'
62 fi
63 mkdir -p `dirname users/${file}`
64 sed -i -E ${ogWiki}/${base}/${file}.HTM -e "s%<a href=\"/System/UserForm\">UserForm</a>%%w users/${file}_fos.SED"
65 if [ -s users/${file}_fos.SED ]; then
66 dest="users"
67 fi
68 rm users/${file}_fos.SED >/dev/null 2>&1
69 rm -d `dirname users/${file}` >/dev/null 2>&1
70 fi
71 # "Devuan" is only two pages that get sorted. "Sandbox" is a mixture of standard examples, stuff that was copied to PmWiki, and other things that should get unsorted.
72 # Skipping anything with "<a href="/Main/UnknownUser">UnknownUser</a></span></div>".
73 if [[ "${base}" == "Sandbox" ]]; then
74 dest="unsorted"
75 mkdir -p `dirname users/${file}`
76 sed -i -E ${ogWiki}/${base}/${file}.HTM -e "s%<a href=\"/Main/UnknownUser\">UnknownUser</a></span></div>%%w users/${file}_fos.SED"
77 if [ -s users/${file}_fos.SED ]; then
78 dest=""
79 fi
80 rm users/${file}_fos.SED >/dev/null 2>&1
81 rm -d `dirname users/${file}` >/dev/null 2>&1
82 fi
83
84 if [[ "${dest}" != "" ]]; then
85 mkdir -p `dirname ${dest}/${file}`
86 realURL=${dest}/${file}
87 echo -e "ogWiki=${ogWiki}\nogURL=${ogURL}\nrealURL=${realURL}_fos\nogBase=${base}\nogFile=${file}\ntimestamp=${time}\n" > ${ogWiki}/${base}/${file}.md.md
88 touch ${ogWiki}/${base}/${file}.md
89 ln -sfr ${ogWiki}/${base}/${file}.md ${dest}/${file}_fos.md
90 ln -sfr ${ogWiki}/${base}/${file}.md.md ${dest}/${file}_fos.md.md
91 rm ${ogWiki}/${base}/${file}.md
92 fi
93 fi
94 fi
95done
96
97
98# Copy across things like images that where uploaded.
99cp -r /opt/pmwiki/uploads /opt/nyaw/PmWiki/
100filter="
101 -not -name "*~" -a \
102 -not -name ".flock" -a \
103 -not -name ".htaccess" -a \
104 -not -name ".lastmod" -a \
105 -not -name ".pageindex" -a \
106"
107ogURL="https://wiki.devuan.org"
108ogWiki="PmWiki"
109time find /opt/pmwiki/wiki.d ${filter} \
110-name "*.*" -type f,l -printf "%P\n" | while read line
111do
112 base=`echo "${line}" | cut -d '.' -f 1`
113 file=`echo "${line}" | cut -d '.' -f 2`
114 if [[ "${base}" != "Site" ]]; then
115 doit='false'
116 if [ ! -s ${ogWiki}/${base}/${file}.HTM ]; then
117 echo "NEW /opt/pmwiki/wiki.d/${base}.${file} ${ogWiki}/${base}/${file}.HTM"
118 doit='true'
119 elif [ /opt/pmwiki/wiki.d/${base}.${file} -nt ${ogWiki}/${base}/${file}.HTM ]; then
120 echo "NEWER /opt/pmwiki/wiki.d/${base}.${file}"
121 date --rfc-3339=seconds -ur /opt/pmwiki/wiki.d/${base}.${file}
122 date --rfc-3339=seconds -ur ${ogWiki}/${base}/${file}.HTM
123 doit='true'
124 fi
125 if [[ ${doit} == "true" ]]; then
126 realURL=${ogWiki}/${base}/${file}
127 time=`date --rfc-3339=seconds -ur /opt/pmwiki/wiki.d/${base}.${file} | cut -d '+' -f 1`
128 mkdir -p ${ogWiki}/${base}
129 echo -e "ogWiki=${ogWiki}\nogURL=${ogURL}\nrealURL=${realURL}\nogBase=${base}\nogFile=${file}\ntimestamp=${time}\n" > ${ogWiki}/${base}/${file}.md.md
130# echo "downloading ${ogURL}/?n=${base}.${file}?action=markdown"
131# curl --no-progress-meter ${ogURL}/?n=${base}.${file}?action=markdown -o ${ogWiki}/${base}/${file}.MARKDOWN
132 echo "downloading ${ogURL}/?n=${base}.${file}?action=print"
133 curl --no-progress-meter ${ogURL}/?n=${base}.${file}?action=print -o ${ogWiki}/${base}/${file}.HTM
134 # Seems there's no way to tell user profiles apart from user content. Unless I can find a list of users somewhere. Don't think there is one.
135 if [[ "${base}" == "Profiles" ]]; then
136 dest="unsorted"
137 if [ -L users/${file}_pm.md ]; then
138 dest='users'
139 fi
140 realURL=${dest}/${file}
141 echo -e "ogWiki=${ogWiki}\nogURL=${ogURL}\nrealURL=${realURL}_pm\nogBase=${base}\nogFile=${file}\ntimestamp=${time}\n" > ${ogWiki}/${base}/${file}.md.md
142 touch ${ogWiki}/${base}/${file}.md
143 ln -sfr ${ogWiki}/${base}/${file}.md ${dest}/${file}_pm.md
144 ln -sfr ${ogWiki}/${base}/${file}.md.md ${dest}/${file}_pm.md.md
145 rm ${ogWiki}/${base}/${file}.md
146 fi
147 fi
148
149# TODO - groups are PmWiki/Onefang and PmWiki/Tiki
150
151# pandoc -f markdown -t commonmark_x --self-contained ${ogWiki}//${base}/${file}.MD >${ogWiki}/${base}/${file}.md
152# pandoc -f html -t commonmark_x --self-contained ${ogWiki}//${base}/${file}.HTM >${ogWiki}/${base}/${file}.md
153 fi
154done
155
156
157time notYetAnotherWiki.lua
158# No idea why yet, but needs a second run to sort out everything. Shouldn't take long anyway.
159time notYetAnotherWiki.lua
160
161popd
162}
diff --git a/SuckItClean b/SuckItClean
new file mode 100755
index 0000000..1b8a025
--- /dev/null
+++ b/SuckItClean
@@ -0,0 +1,13 @@
1#!/bin/bash
2
3TIMEFORMAT=" took %lR using %P%% CPU"
4time {
5pushd /opt/nyaw
6
7rm -fr Foswiki/*
8rm -fr PmWiki/*
9rm -fr unsorted
10rm -fr users/*
11popd
12./SuckIt
13}
diff --git a/SuckItCron b/SuckItCron
new file mode 100755
index 0000000..e817948
--- /dev/null
+++ b/SuckItCron
@@ -0,0 +1,4 @@
1#!/bin/sh
2
3cd /opt/notYetAnotherWiki
4./SuckIt >/dev/null 2>&1
diff --git a/SuckItFos b/SuckItFos
deleted file mode 100755
index f21decc..0000000
--- a/SuckItFos
+++ /dev/null
@@ -1,60 +0,0 @@
1#!/bin/bash
2
3URL="https://fos.wiki.devuan.org"
4
5filter="
6 -name _default -prune -o \
7 -name _empty -prune -o \
8 -name System -prune -o \
9 -name Trash -prune -o \
10 -name TWiki -prune -o \
11"
12
13pushd /opt/merged
14
15find /opt/Foswiki/data ${filter} \
16-name "*.txt" -type f,l -printf "%P\n" | while read line
17do
18 base=`echo "${line}" | cut -d '/' -f 1`
19 file=`echo "${line}" | cut -d '/' -f 2- | rev | cut -b 5- | rev`
20 mkdir -p Foswiki/$base
21 mkdir -p Foswiki/${base}/`dirname ${file}`
22 mkdir -p combined/$base
23 mkdir -p combined/${base}/`dirname ${file}`
24 echo "Converting ${URL}/${base}/${file} -> Foswiki/${base}/${file}.md"
25# pandoc -f html -t markdown --self-contained ${URL}/${base}/${file} >Foswiki/${base}/${file}.md
26 # TODO - try curl, to see what is actually downloaded, and maybe not download unchanged pages. curl to .HTM
27 # Doesn't help with redownloads, coz natch a dynamic site isn't cached. But I can at least comment out the curl command during testing to save time.
28 curl --silent --no-progress-meter ${URL}/${base}/${file} -o Foswiki/${base}/${file}.HTM
29 pandoc -f html -t commonmark_x --self-contained Foswiki//${base}/${file}.HTM >Foswiki/${base}/${file}.md
30 ln -frs Foswiki/${base}/${file}.md combined/${base}/${file}.md
31 cp Foswiki/${base}/${file}.md Foswiki/${base}/${file}.md_ORIGINAL
32
33# csplit -ks Foswiki/${base}/${file}.md '%::: foswikiTopic%' '/::: foswikiContentFooter/'
34# if [ -f xx00 ]; then
35# rm Foswiki/${base}/${file}.md
36# mv xx00 Foswiki/${base}/${file}.md
37# fi
38
39 # Attempt to clean things up, badly.
40 sed -i -E Foswiki/${base}/${file}.md \
41 -e 's/\$/\$dlr\$/g' \
42 -e 's/\{#.*\}//g' \
43 -e 's/\{\.foswiki.*\}//g' \
44 -e 's/\{\.foswiki.*//g' \
45 -e 's/\{\.foswikiNewLink rel=“nofollow”\}//g' \
46 -e 's/\{\.foswikiNewLink$//g' \
47 -e 's/^\.foswiki.*\}//g' \
48 -e 's/\{\.pattern.*\}//g' \
49 -e 's/\{\.pattern.*//g' \
50 -e 's/\{rel="nofollow"\}//g' \
51 -e 's/^rel="nofollow"\}//g' \
52 -e 's/rel=“nofollow”\}$//g' \
53 -e '/^:::/d'
54
55 echo "<hr/><p><a href=\"${URL}/${base}/${file}\">Original page</a> where you can edit it.</p>" >> Foswiki/${base}/${file}.md
56done
57
58notYetAnotherWiki.lua
59
60popd
diff --git a/SuckItPm b/SuckItPm
deleted file mode 100755
index 6a30373..0000000
--- a/SuckItPm
+++ /dev/null
@@ -1,63 +0,0 @@
1#!/bin/bash
2
3URL="https://wiki.devuan.org"
4
5filter="
6 -not -name "*~" -a \
7 -not -name ".flock" -a \
8 -not -name ".htaccess" -a \
9 -not -name ".lastmod" -a \
10 -not -name ".pageindex" -a \
11"
12
13pushd /opt/merged
14
15find /opt/pmwiki/wiki.d ${filter} \
16-name "*.*" -type f,l -printf "%P\n" | while read line
17do
18 base=`echo "${line}" | cut -d '.' -f 1`
19 file=`echo "${line}" | cut -d '.' -f 2`
20 mkdir -p PmWiki/$base
21 mkdir -p combined/$base
22 echo "Converting ${URL}/?n=${base}.${file} -> PmWiki/${base}/${file}.md"
23# pandoc -f html -t markdown --self-contained ${URL}/?n=${base}.${file} >PmWiki/${base}/${file}.md
24 # TODO - try curl, to see what is actually downloaded, and maybe not download unchanged pages. curl to .HTM
25 # Doesn't help with redownloads, coz natch a dynamic site isn't cached. But I can at least comment out the curl command during testing to save time.
26 curl --no-progress-meter ${URL}/?n=${base}.${file} -o PmWiki/${base}/${file}.HTM
27 pandoc -f html -t commonmark_x --self-contained PmWiki//${base}/${file}.HTM >PmWiki/${base}/${file}.md
28 ln -frs PmWiki/${base}/${file}.md combined/${base}/${file}.md
29 cp PmWiki/${base}/${file}.md PmWiki/${base}/${file}.md_ORIGINAL
30
31# csplit -ks PmWiki/${base}/${file}.md '/trailstart/' '/trailend/'
32 csplit -ks PmWiki/${base}/${file}.md '%::: {#wikitext}%'
33 if [ -f xx00 ]; then
34 rm PmWiki/${base}/${file}.md
35 mv xx00 PmWiki/${base}/${file}.md
36 fi
37
38 # Attempt to clean things up, badly.
39 sed -i -E PmWiki/${base}/${file}.md \
40 -e 's/\$/\$dlr\$/g' \
41 -e 's/\{#.*\}//g' \
42 -e '/\{\.wikilink\}/d' \
43 -e '/\[Site$/d' \
44 -e '/^:::/d' \
45 -e '/^Page last modified on /d' \
46 -e '/^\[\]/d' \
47 -e 's/\{rel=".*\}//g' \
48 -e 's/\{rel="nofollow"$//g' \
49 -e 's/^rel="nofollow"\}//g' \
50 -e 's/^target="_blank"\}//g' \
51 -e 's/\{\.createlinktext.*\}//g' \
52 -e 's/\{\.createlinktext$//g' \
53 -e 's/\{\.createlink.*\}//g' \
54 -e 's/\{\.createlink$//g' \
55 -e 's/\{\.urllink.*\}//g' \
56 -e 's/\{\.urllink$//g'
57
58echo "<hr/><p><a href=\"${URL}/?n=${base}.${file}\">Original page</a> where you can edit it.</p>" >> PmWiki/${base}/${file}.md
59done
60
61notYetAnotherWiki.lua
62
63popd
diff --git a/TODO.md b/TODO.md
index e93b4aa..3453ba0 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,37 +1,100 @@
1--- 1# TODO
2pagetitle: "TODO" 2
3author: onefang 3Make it perphekd!
4pagehistory: https://sledjhamr.org/cgit/notYetAnotherWiki/log/TODO.md 4
5---
6## Do these 5## Do these
7 6
8Deal with complex directory trees. 7Convert it to polygLua.
9- /testing/even should display as even/deeper on the testing page, coz even/ has no files, but even/deeper does. 8
10- Scanning /usr/share/doc on my super desktop with looots of software installed will be fun. 9It's all a bit too fragile, fix what I can. Too many messes colliding.
10
11Flock it.
12
13Some sort of search system.
14
15A member system, and edit / manage system for their pages.
16
17Fix up linky conversion. DONE, mostly.
18
19- Need to deal with real file name versus title. Also symlink name not matching what it points to.
20
21Use the default.template that comes with nYAW if none is availaable.
22
23"collapsing headings" I guess that means click on a heading to hide / show the content under that heading.
24
25- 🙈
26- Should do that for the main content and the menu TOC.
27- Also allow editing just a section, a section being the bits between one heading and the next.
28- + 📝 ✒️✏️🖊️🖋 🖌️🖍️
29- + When someone starts editing, create pagename_draft.md and .HTML, and update those when they want to see a preview.
30- + Or pagename-heading_draft.md
31- + Use that draft.md file as a lock on editing that file / section.
32- + Have the hourly cron job remove any stale ones.
33
34Add ATOM feed for single page. Alas cgit only seems to have ATOM feed on the whole repo, not individual files.
35
36- However, once timestamps are sorted, I can use that code to generate RSS and ATOM feeds, and create page histories using diffs.
37- Instead of an hourly cron job to update everything, see if I can hook
38into Fos and Pm edit form's save function. So when they save in the
39original wiki, the nyaw version gets updated, diffed, and ATOMed / RSSed.
40- + Actually a BFI method might do the trick, stick with doing a full scan
41and only updating the stuff that needs it, likely that's only the page that just got saved.
42- git commit can have an arbitrary author / committer, so I can use that to make sure the person that actually made the change gets author / committer.
43- + There's also the email thing, but I don't want to spread email addresses around, not even sure we have them anyway.
44- Should also see if gitea can handle that, and if they want wiki content saved to git.
45
46Syntax highlighting in code blocks. The highlight package looks promising, already had it installed on my desktop.
11 47
12Check the timestamps on the files, only update if source is newer than destination. Meh, it's already 600 times faster than the pandoc version. 48## Some ideas
13- One quirk to watch for is if a URL path changes, the docs that have that URL need to be redone.
14- pandoc is a lot slower though, so do this for sure when dealing with that.
15- When scraping the web sites, they tend to be dynamically generated with no useful timestamp on them.
16 49
17Add atom feed for single page. Alas cgit only seems to have ATOM feed on the whole repo, not individual files. 50Mostly from something chomwitt wrote -
18 51
52- "validation", not sure exactly what that would validate.
53- I'll just quote some of the rest -
54
55~~~
56 !!! co-editing
57 The toolbar should contain tools that facilitate :
58 * intergration (to other workflows)
59 ** for example search-completion to other workflows names-tags.
60~~~
61
62- Allow default.template files in sub folders.
63- Might be useful to automatically convert anything looking like a URL into a linky.
64
65Automate symlinks.
66
67- any .md.md file should be linked along with it's matching .md file if it's outside of Foswiki/ and PmWiki/.
19 68
20 69
21## Try out 70## Try out
22 71
23htmx 72lua-lpeg-patterns might be useful
73
74lua-luxio might be the wheel I'm reinventing?
75
76lua-wsapi-fcgi
24 77
25pandoc replacements 78https://inclusive-components.design/tooltips-toggletips/ has some ideas about the "tooltip" HTML attribute, and what to do about it. A rabbit hole that ends in javascript, but might be useful up to that point.
26- cmark-gfm 79
80htmx
27 81
28cgit has Lua 82cgit has Lua
29 83
84lua-gall for git stuff
85
86lua-lace for access control
87
88lua-unbound
30 89
31 90
32## User system 91## Member system
92
93Reuse the member system from SledjChisl.
33 94
34levels - 95levels -
96
97- everyone
35- banned 98- banned
36- reader 99- reader
37- member 100- member
@@ -41,6 +104,8 @@ levels -
41- shell 104- shell
42- root 105- root
43 106
107Everyone can read the pages, no need for an account.
108
44Banned people can't do squat, except maybe pester an admin once to start the unbanning process. 109Banned people can't do squat, except maybe pester an admin once to start the unbanning process.
45 110
46When first registered, accounts are set to reader level. 111When first registered, accounts are set to reader level.
@@ -67,6 +132,6 @@ site, including configuration and modules. Likely this is the person
67that set the system up in the first place. 132that set the system up in the first place.
68 133
69Admin should have access to everything that shell level has, but there's always things need tweaking at some lower level. 134Admin should have access to everything that shell level has, but there's always things need tweaking at some lower level.
70Built in file browser might do the trick. Would be useful for content creators to to organise the content. Naturally should obey the permisisons. 135Built in file browser might do the trick. Would be useful for content creators to organise the content. Naturally should obey the permissions.
71 136
72root level is whoever controls the server things are running on. They can do anything at all. 137root level is whoever controls the server things are running on. They can do anything at all.
diff --git a/about/index.md b/about/index.md
index aa3be9f..3f15be7 100644
--- a/about/index.md
+++ b/about/index.md
@@ -1,9 +1,5 @@
1--- 1# notYetAnotherWiki is not another wiki, at least not yet. It'll be much more than that, eventually.
2pagetitle: "notYetAnotherWiki is not another wiki, at least not yet. It'll be much more than that, eventually."
3author: onefang
4pagehistory: https://sledjhamr.org/cgit/notYetAnotherWiki/log/About/index.md
5---
6 2
7This is a new directory, an entire PR department can hang out here. 3This is a new folder, an entire PR department can hang out here.
8 4
9This would just be a duplicate of README, but for testing purposes. 5This would just be a duplicate of README, but for testing purposes.
diff --git a/default.template b/default.template
index eed4c59..baefad1 100644
--- a/default.template
+++ b/default.template
@@ -2,49 +2,118 @@
2<html> 2<html>
3 <head> 3 <head>
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" contents="lcmark">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>$pagetitle$</title> 6 <title>$title$</title>
8 <link rel="icon" type="image/png" href="$favicon$" /> 7 <link rel="icon" type="image/png" href="$favicon$" />
9 <style> 8 <style>
10 html {font-family: sans-serif;} 9 a:hover {color: red;}
11 10 body {
11 height: 100vh; width: 100vw;
12 margin: 0; padding: 0; border: none;
13 background-image: linear-gradient($onefangPurple$, $karenPurple$);
14 color: white;
15 font-family: sans-serif;
16 }
17 menu {list-style-type: none;}
12 pre { 18 pre {
13 background-color: $onefangPurple$; 19 background-image: linear-gradient(to right, $PinkFloyd$, $onefangPurple$);
14 overflow-x: auto; 20 width: fit-content; max-width: 99%; overflow-x: auto;
15 width: 92vw; 21 margin: 2px; border: 2px solid grey;
16 margin: 1px; 22 }
23 table, td, th {border-collapse: collapse; border: 2px solid grey;}
24
25 .toolTip {background: darkcyan; font-size: 1.42em;}
26
27 .boxWrapper {
28 height: 100%; width: 100%;
29 margin: 0; padding: 0; border: none;
30 display: grid;
31// grid-template-areas:
32// "logo tools tools tools"
33// "logo head head head"
34// "menu body body body"
35// "history foot foot foot"
36// "nyaw nyaw nyaw nyaw";
37 grid-template-columns: 1.4fr 8fr auto auto;
38 grid-template-rows: auto auto 1fr auto auto;
39 overflow-x: auto; overflow-y: auto;
17 } 40 }
41 .boxLogo {grid-area: logo; grid-column: 1 / 1; grid-row: 1 / 2; height: min-content;}
42 .boxTools {grid-area: tools; grid-column: 2 / 4; grid-row: 1 / 1; height: min-content;}
43 .boxHead {grid-area: head; grid-column: 2 / 4; grid-row: 2 / 2; height: min-content; text-align: right;}
18 44
19 menu { 45 .boxMenu {grid-area: menu; grid-column: 1 / 1; grid-row: 3 / 3; height: min-content; vertical-align: top; padding: 4px; overflow-x: auto; overflow-y: auto;}
20 list-style-type: none; 46 .boxBody {grid-area: body; grid-column: 2 / 4; grid-row: 3 / 3; vertical-align: top;
47 height: 100%; width: 100%;
48 background: black; color: white;
21 } 49 }
50 .boxBody a:active {color: red;}
51 .boxBody a:link {color: orange;}
52 .boxBody a:visited {color: $onefangGreen$;}
53 .boxBody a:hover {color: red;}
54
55 .boxHistory {grid-area: history; grid-column: 1 / 1; grid-row: 4 / 4; height: min-content;}
56 .boxFoot {grid-area: foot; grid-column: 2 / 4; grid-row: 4 / 4; height: min-content; text-align: right;}
57 .boxnyaw {grid-area: nyaw; grid-column: 1 / 4; grid-row: 5 / 5; height: min-content; text-align: right; font-size: 0.55em;}
22 58
59 #modeToggleBody {display: none;}
60 #modeToggleMenu {display: none;}
61 #modeBtn {color: white; display: inline-block;}
62 #modeToggleBody:checked ~ .modeBtn {color: black;}
63// #modeToggleBody:checked ~ body background-image: linear-gradient($karenPurple$, $onefangPurple$);{}
64// #modeToggleBody:checked ~ pre {background-image: linear-gradient(to right, $onefangPurple$, $PinkFloyd$);}
65
66 #modeToggleMenu:checked ~ .boxLogo {display: none;}
67 #modeToggleMenu:checked ~ .boxHead {display: none;}
68// #modeToggleMenu:checked ~ .boxTools {display: none;}
69// #modeToggleMenu:checked ~ .boxMenu {display: none; width: 0px; max-width: 0px; }
70
71 #modeToggleBody:checked ~ .boxBody {background: white; color: black;}
72 #modeToggleBody:checked ~ .boxBody a:active {color: $devuanDevuanalink$;}
73 #modeToggleBody:checked ~ .boxBody a:link {color: $devuanDevuanlink$;}
74 #modeToggleBody:checked ~ .boxBody a:visited {color: $devuanDevuanvlink$;}
75 #modeToggleBody:checked ~ .boxBody a:hover {color: $devuanDevuanhlink$;}
76
77 #modeToggleMenu:checked ~ .boxHistory {display: none;}
78 #modeToggleMenu:checked ~ .boxFoot {display: none;}
79 #modeToggleMenu:checked ~ .boxnyaw {display: none;}
23 </style> 80 </style>
24 </head> 81 </head>
25 <body bgcolor="black" text="white" alink="yellow" link="yellowgreen" vlink="red"> 82 <body alink="red" link="orange" vlink="$onefangGreen$">
26 <table style="background-color: $karenPurple$; width: 98vw; margin: 1; line-style: none; border-style: none; border-spacing: 0;"> 83 <div class="boxWrapper">
27 <tr> 84 <input type="checkbox" id="modeToggleMenu"/>
28 <td><img src="$logo$" alt="alt text" title="Not (Yet) (Another / A) Wiki."/></td> 85 <input type="checkbox" id="modeToggleBody"/>
29 <td style="text-align: right;">$header$ &nbsp; plus login and register buttons &nbsp;</td> 86 <div class="boxLogo" id="top"><header><nav>
30 </tr> 87 <a href="$home$"><img src="$logo$" alt="not (Yet) (Another / A) Wiki."/></a>
31 <tr> 88 </nav></header></div>
32 <td rowspan=2 style="white-space:nowrap; vertical-align:top;">$menu$</td> 89 <div class="boxTools"><header><nav>
33 <td><p>&#x1f463; $trail$</p></td> 90 &nbsp; <a href="/help.HTML"><b class="toolTip" title="🍔 hides / shows non content, reverse hamburger menu.
34 </tr> 91🕶 switches between dark and light themes.
35 <tr> 92📚 shows the list of all pages.
36 <td style="background-color: black; width: fit-content;"> 93🔮 a folder of unsorted pages.
37 <main class="contentBox" style="overflow-y: auto; overflow-x: hidden;"> 94👥 shows the list of users.
38 <h1>$pagetitle$</h1> 95🪵 will be for logging in, when I have written that bit.
39 Author: $author$ 96🔍 will be the search, when I have written that bit.
40 $body$ 97👣 is a trail of the steps to get here.">❓</b></a>
41 </main> 98 &nbsp; <b class="toolTip"><label for="modeToggleMenu" class='modeBtn'>&#127828;</label></b>
42 </td> 99 &nbsp; <b class="toolTip"><label for="modeToggleBody" class='modeBtn'>&#x1F576;</label></b>
43 </tr> 100 &nbsp; <a href="/everything.HTML"><b class="toolTip">&#128218;</b></a>
44 <tr> 101 &nbsp; <a href="/unsorted/" ><b class="toolTip">&#128302;</b></a>
45 <td>$history$</td> 102 &nbsp; <a href="/users/" ><b class="toolTip">&#128101;</b></a>
46 <td style="text-align: right;">$footer$</td> 103 &nbsp; <b class="toolTip">&#129717;</b>
47 </tr> 104 &nbsp; <b class="toolTip">&#128269;</b>
48 </table> 105 <b> &nbsp; &#x1f463; $trail$ </b>
106 </nav></header></div>
107 <div class="boxHead"><header><nav><b>$header$</b> &nbsp; </nav></header></div>
108
109 <div class="boxMenu"><nav><p><b>$menu$</b></p></nav></div>
110 <div class="boxBody"><main>$body$<br/></main></div>
111
112 <div class="boxHistory"><footer>$history$</footer></div>
113 <div class="boxFoot"><footer>$footer$</footer></div>
114 <div class="boxnyaw"><footer>
115 <p>Powered&nbsp;by&nbsp;<a href="https://sledjhamr.org/notYetAnotherWiki/">notYetAnotherWiki</a>&nbsp;v&nbsp;0.0 &nbsp; No cookies or scripts where harmed in the making of this web site. &nbsp; May contain low fat CSS.</p>
116 </footer></div>
117 </div>
49 </body> 118 </body>
50</html> 119</html>
diff --git a/empty.md b/empty.md
new file mode 100644
index 0000000..b68450f
--- /dev/null
+++ b/empty.md
@@ -0,0 +1 @@
Nothing to see here, yet.
diff --git a/feed-icon-14x14.png b/feed-icon-14x14.png
new file mode 100755
index 0000000..b3c949d
--- /dev/null
+++ b/feed-icon-14x14.png
Binary files differ
diff --git a/feed-icon-28x28.png b/feed-icon-28x28.png
new file mode 100755
index 0000000..d64c669
--- /dev/null
+++ b/feed-icon-28x28.png
Binary files differ
diff --git a/help.md b/help.md
new file mode 100644
index 0000000..bc4cc46
--- /dev/null
+++ b/help.md
@@ -0,0 +1,43 @@
1# How to use this wiki
2
3On the top left, is the logo, beside that is a toolbar of icons -
4
5- ❓ hover over this for help.
6- 🍔 hides or shows everything but the content and these icons, the reverse hamburger menu.
7- 🕶 switches between dark and light themes.
8- 📚 shows the list of all pages.
9- 🔮 a folder of unsorted pages.
10- 👥 shows the list of users.
11- 🪵 will be for logging in, when I have written that bit.
12- 🔍 will be the search, when I have written that bit.
13
14&#x1f463; is a trail of breadcrumbs, though I'm using a footsteps icon
15for this. Showing the footsteps you have followed to get to the current
16folder.
17
18On the top right of the pages is links to the sub folders of the current
19folder the current page is in.
20
21Down the left side is links to the pages in the current folder. Most of
22them will be symlinks to the converted pages from the Foswiki and PmWiki
23sub folders. Some will be links &#9757; to external sites. For the
24current page, links to the headings are also shown, those headings have
25their own icon 🔼to go back to the top.
26
27The bit you are reading is the badly converted content of the current
28page. At the bottom of each converted page is a link to the original,
29and if you are logged into that other system, you might be able to edit
30the page. Note that unconverted pages don't have these links to the
31originals.
32
33At the bottom is links to things like page history, web site source code,
34and the software I'm writing to do all of this. Or should be some day.
35
36
37
38# Under the hood
39
40Internally this wiki is made of the root folder and it's sub folders
41representing the structure of the wiki content. Each folder has it's own
42pages. Symlinks are used to copy or move pages around, with special
43folders for the original stuff from the other wikis.
diff --git a/menu.template b/menu.template
index 7cf0ba2..3abcd81 100644
--- a/menu.template
+++ b/menu.template
@@ -4,7 +4,7 @@
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="generator" contents="lcmark"> 5 <meta name="generator" contents="lcmark">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
7 <title>$pagetitle$</title> 7 <title>$title$</title>
8 <link rel="icon" type="image/png" href="$favicon$" /> 8 <link rel="icon" type="image/png" href="$favicon$" />
9 <style> 9 <style>
10html { 10html {
diff --git a/nYAW.png b/nYAW.png
index a843126..3d756a0 100644
--- a/nYAW.png
+++ b/nYAW.png
Binary files differ
diff --git a/nYAW.xcf b/nYAW.xcf
index 50f6400..369f57e 100644
--- a/nYAW.xcf
+++ b/nYAW.xcf
Binary files differ
diff --git a/notYetAnotherWiki.lua b/notYetAnotherWiki.lua
index da88a52..f53691b 100755
--- a/notYetAnotherWiki.lua
+++ b/notYetAnotherWiki.lua
@@ -1,37 +1,74 @@
1#!/usr/bin/env luajit 1#!/usr/bin/env luajit
2 2
3-- Read the README file for what this is all about. If there is no README or similar, then you can find the link to the source below. 3--[[ Read the README file for what this is all about.
4 If there is no README or similar, then you can find the link to the source below.
4 5
5local lcmark = require("lcmark") -- https://github.com/jgm/lcmark 6 Normally I define functions and globals at the top, but here I'm interleaving them.
7]]
6 8
9local Lunamark = require("lunamark") -- https://github.com/jgm/lunamark
10local Lpeg = require("lpeg") -- https://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html Lunamark uses this, so we can to.
11local RE = require("re") -- Part of lpeg. https://www.inf.puc-rio.br/~roberto/lpeg/re.html
7 12
8 13
14---------------------------------------------------------------------------------
9-- Some global data. 15-- Some global data.
10local globalData = { 16
11 ['_'] = '&nbsp;', ['dlr'] = '&dollar;', 17local GlobalMetaData = {
12 ['devuanCinnabarDark'] = '#310202', ['devuanCinnabarLight'] = '#510505', 18 dlr = '&dollar;', perc = '%', dot = '.',
13 ['devuanDarkPurpyDark'] = '#33313b', ['devuanDarkPurpyLight'] = '#3c3a45', 19 devuanCinnabarDark = '#310202', devuanCinnabarLight = '#510505',
14 ['devuanDeepSeaDark'] = '#132f40', ['devuanDeepSeaLight'] = '#1a4562', 20 devuanDarkPurpyDark = '#33313b', devuanDarkPurpyLight = '#3c3a45',
15 ['devuanSaphireDark'] = '#004489', ['devuanSaphireLight'] = '#00509f', 21 devuanDeepSeaDark = '#132f40', devuanDeepSeaLight = '#1a4562',
16 ['karenPurple'] = '#8800ff', ['onefangPurple'] = '#cc00ff', 22 devuanSaphireDark = '#004489', devuanSaphireLight = '#00509f',
17 favicon = 'nYAW_icon.png', logo = 'nYAW.png', header = '', --menu = '', 23 devuanDevuanDark = '#000000', devuanDevuanLight = '#ffffff',
18 history = '', footer = 'Powered by <a href="https://sledjhamr.org/cgit/notYetAnotherWiki/about/">notYetAnotherWiki</a> version 0.0. &nbsp;', 24 -- HTML link colours. Naturally HTML5 deprecated the simple version, replacing it with less simple CSS.
25 -- <body> has alink, link, vlink; CSS has active, link, visited, and hover.
26 devuanDevuanalink = '#03a4ff', devuanDevuanlink = '#0076b6', devuanDevuanvlink = '#6aa4db', devuanDevuanhlink = '#03a4ff',
27 devuanSDevuanalink = '#98c3db', devuanSDevuanlink = '#ffffff', devuanSDevuanvlink = '#ffffff', devuanSDevuanhlink = '#98c3db',
28 karenPurple = '#8800ff', onefangPurple = '#cc00ff', onefangGreen = '#42ff00',
29 PinkFloyd = '#AA00AA', DeepPurple = '#220022', -- From an ancient site of mine, which went from PinkFloyd to DeepPurple as a background gradient.
30 favicon = 'nYAW_icon.png', logo = 'nYAW.png',
19} 31}
20local Sites, Files, Subs = {}, {}, {}
21 32
33local Files, Subs, xLinks = {}, {}, {}
34local Context = {} -- Coz can't otherwise pass context through to the deeper Lunamark functions I'm overriding.
35
36local Template = ''
37local h = io.open("default.template", 'r')
38if nil ~= h then
39 Template = h:read('*a')
40 h:close()
41else
42 print('oops! No such file ' .. 'default.template')
43end
22 44
23 45
46---------------------------------------------------------------------------------
24-- Useful functions, part 0. 47-- Useful functions, part 0.
25 48
26-- A simple table.subtable = subtable wont work, you end up with a reference so that changes to the later get applaid to the former. 49-- A simple table.subtable = subtable wont work, you end up with a reference so that changes to the later get applied to the former.
27local copyTable = function(t, strip) 50local derefiTable = function(t, strip)
28 local argh = {} 51 local argh = {}
29 for l, y in ipairs(t) do if (l ~= y.name) and strip then table.insert(argh, y) end end 52 for l, y in ipairs(t) do if (l ~= y.name) and strip then table.insert(argh, y) end end
30 return argh 53 return argh
31end 54end
55local derefTable = function(t, strip)
56 local argh = {}
57 for l, y in pairs(t) do argh[l] = y end
58 return argh
59end
32 60
33 61
34-- String together the bits array into a path string. 62local writeString = function(base, body)
63 local a, e = io.open(base, 'w')
64 if nil == a then print('Could not open ' .. base .. ' - ' .. e) else
65 a:write(body)
66 a:close()
67 end
68end
69
70
71-- String together the bits array into a path string. Or the other way around. lol
35local stringBits = function(l) 72local stringBits = function(l)
36 local bits = {} 73 local bits = {}
37 local last = 1 74 local last = 1
@@ -45,258 +82,885 @@ local stringBits = function(l)
45end 82end
46 83
47 84
85-- Put a value into the Files or Subs table, creating things if needed.
86local toFile = function(name, key, value)
87 if nil == Files[name] then
88 local bits, bit = stringBits(name)
89 local path = ''
90 Files[name] = {}
91 Files[name].headers = {}
92 Files[name].bits = bits
93 Files[name].bit = bit
94 for i, d in ipairs(bits) do
95 if '' ~= path then path = path .. '/' end
96 path = path .. d
97 end
98 Files[name].path = path
99-- Files[name].body = ''
100 if ("Foswiki" == bits[1]) or ("PmWiki" == bits[1]) then Files[name].ogWiki = bits[1] end
101 end
102 if nil ~= key then Files[name][key] = value end
103 for i, v in ipairs{'metadata', 'bits', } do
104 if nil == Files[name][v] then Files[name][v] = {} end
105 end
106 -- Open the files and do the initial cleanups.
107 local body = ''
108 if '.md' ~= string.sub(name, -3, -1) then
109 h = io.open(name .. '.md', 'r')
110 if nil ~= h then
111-- print('Parsing ' .. name .. '.md')
112 Context = Files[name]
113 body = h:read('*a') ; h:close()
114 -- Deal with my typical double spaced sentence endings, and other things.
115 local result = RE.compile( [=[{~
116 (
117 {[.?!]{" "}} -> '%1&nbsp;' / -- '&nbsp;' gets turned into hex 0xA0 by parse(). So feed it another metadata token that gets translated to &nbsp;. Seems we now skip this issue.
118 {[\\]{['"|$]}} -> '%2' / -- Do the same for fixing the \' \" \| etc mess pandoc left.
119 {"[ ]{.foswikiGrayFG}" } -> '' / -- Coz Foswiki sucks. No idea why the next thing didn't catch it.
120 {"[" {([^]])+} "]{.foswiki" {([^FG}])+} "FG}" } -> "<span style='color: %3;'>%2</span>" /
121 {"::: {."[A-Za-z_. ]+"}"} -> '' /
122 {":::"} -> '' /
123 {"-noComment-"} -> ' -- ' /
124 {"| bgcolor=#" {([^ ])+} " " } -> "| <span style='background: #%2;'> bgcolor=#%2 </span> " / -- Deal with debdog's color table.
125 {"[" {([^]])+} ']{style="color: ' {([^}])+} "}" } -> "<span style='color: %3;'>%2</span>" /
126 {"[" {([^]])+} "]{style='color: " {([^}])+} "}" } -> "<span style='color: %3;'>%2</span>" /
127 {"{#"[A-Za-z_]+"}"} -> '' /
128 {"### [[edit](/bin/edit/Main/" {([^%nl])+} } -> '' /
129 {"#"+ " " {([^%nl])+} } -> header /
130 .
131 )* ~}]=], { header = function(a) table.insert(Context.headers, a); return a end } ):match(body)
132 body = result
133-- {"<!--".*"-->"} -> '' /
134-- {"[$]"} -> '$dlr$' / -- Replace $, coz otherwise it confuses things later.
135 body = RE.gsub(body, '{[$]}', '$dlr$')
136-- {"[%]"} -> '$perc$' / -- Gotta be done after the %1's above. otherwise screws things up when included above.
137-- body = RE.gsub(body, '{[%]}', '$perc$') -- Coz otherwise stray % trip up the capture part.
138 end
139 Files[name].body = body
140 end
141end
142local toSub = function(name, key, value)
143 if nil == Subs[name] then
144 local bits, bit = stringBits(name)
145 local path = ''
146 Subs[name] = {}
147 table.insert(bits, bit)
148 Subs[name].bits = bits
149 Subs[name].bit = bit
150 for i, d in ipairs(bits) do
151 if '' ~= path then path = path .. '/' end
152 path = path .. d
153 end
154 Subs[name].path = path
155 end
156 if nil ~= key then Subs[name][key] = value end
157 for i, v in ipairs{'metadata', 'bits', 'files', 'subs'} do
158 if nil == Subs[name][v] then Subs[name][v] = {} end
159 end
160end
161
162
48 163
164local readMdMd = function(name, metadata)
165 local h1 = io.open(name .. '.md')
166 if nil == h1 then
167-- print('Could not open ' .. name .. '.md')
168 return {}
169 else
170 for l in h1:lines() do
171 for k, v in string.gmatch(l, "(%w+)%s*=%s*(.+)") do
172 if nil == v then
173 print(name .. ' ' .. k)
174 else
175 metadata[k] = v
176 end
177 end
178 end
179 end
180 return metadata
181end
182
183
184
185local commonLinky = function(l, body, u, url, beg, en, beg0, en0, bump)
186 if nil == url then
187-- print('OOPS! unknown linky - @' .. l .. '\t\t\t' .. string.sub(body, beg - 9, en) .. ' ' .. string.sub(body, en + 1, en0))
188 else
189 local md = readMdMd(url, {})
190-- if nil ~= md then
191 if nil ~= md.realURL then url = md.realURL end
192-- end
193 body = string.sub(body, 1, beg - bump) .. url .. string.sub(body, en0 + 1)
194 here = here + string.len(url)
195 end
196 if 1 == bump then
197 here = here + 1
198 beg, en = RE.find(body, [['https://fos.wiki.devuan.org/']], here)
199 else
200 beg, en = RE.find(body, [["'https://wiki.devuan.org/"]], here)
201 end
202 return beg, en, body, here
203end
204
205
206
207---------------------------------------------------------------------------------
49-- Actually start doing things. 208-- Actually start doing things.
50 209
51-- Scan the subdirectories looking for .md files. 210-- Create the base of everything.md here, so it gets picked up as usual in the file scan.
52local directory = arg[1] 211h = io.open('everything.md', 'w')
53if nil == directory then directory = '.' end 212if nil ~= h then
54if '.' ~= directory then 213 h:close()
55 for l in io.popen('find . -name "*.md" -type f,l -printf "%P\n"'):lines() do 214else
56 Files[string.gsub(l, '%.md$', '')] = {} 215 print("Can't open everything.md for writing.")
216end
217
218-- Scan the sub folders looking for our files.
219local Folder = arg[1]
220toSub('')
221if nil == Folder then Folder = '.' end
222--GlobalMetaData.root = Folder
223
224--[[ Sort out realURL for symlinked .md.md files.
225 realURL is the generic URL part for this page. By policy it points to whatever is the latest copy / symlink of the original download .md.md.
226 realURL starts out being the path to the downloaded file and friends.
227 If we make a symlink during SuckIt, then that gets updated to point to the place the symlink is in.
228 below we compare timestamps and select the latest version if there's more than one symlink.
229 For the "page symlinked" problem, this should work if realURL is kept updated.
230 For the "page copied" problem, this should work if realURL is kept updated, same as symlinked really, coz that's just another copy.
231 For the "page moved" problem, that'll be the most recent symlink, the old one still has it's symlink pointing to the download .md.md, which gets updated with the current realURL.
232 So when some external old URL points to someplace a page used to be, it's old symlink points to the up to date download .md.md, and we know where to go to find the page now.
233 A left over .md.md file should have a redirect .HTML page created for it.
234]]
235for l in io.popen('find -L ' .. Folder .. ' -name unsorted -prune -o -name "*.md.md" -xtype l -printf "%P\n"'):lines() do
236 local metadata = readMdMd(string.sub(l, 1, -4), {})
237 if nil == metadata.realURL then
238 metadata.realURL = string.sub(l, 1, -7)
239 else
240 if metadata.realURL ~= string.sub(l, 1, -7) then
241 metadata.realURL = string.sub(l, 1, -7)
242 -- If this already exists, compare the timestamps, most recent wins.
243 local time0 = io.popen('ls -l --time-style=+%s "' .. metadata.realURL .. '.md.md" | cut -d \' \' -f 6'):read('l')
244 local time1 = io.popen('ls -l --time-style=+%s "' .. l .. '" | cut -d \' \' -f 6'):read('l')
245 if time0 > time1 then metadata = nil end
246 else metadata = nil end
247 end
248
249 if nil ~= metadata then
250-- DUNNO if this writes to the original file, or overwrites the symlink.
251 local a, e = io.open(l, 'w')
252 if nil == a then print('Could not open ' .. l .. ' - ' .. e) else
253 for k, v in pairs(metadata) do
254 a:write(k .. '=' .. v .. '\n')
255 end
256 a:close()
257 end
57 end 258 end
58end 259end
59-- Can add in a distant directory to, for putting it's results in the current directory. 260
60for l in io.popen('find ' .. directory .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do 261-- Clean up unsorted.
262for l in io.popen('find -L ' .. Folder .. ' -name unsorted -prune -o -name "*.md" -a -not -name "*.md.md" -xtype l -printf "%P\n"'):lines() do
263 local tp = '_fos'
264 local metadata = readMdMd(l, {})
265 if nil ~= metadata then
266 if "PmWiki" == metadata.ogWiki then tp = '_pm' end
267 if nil ~= metadata.ogFile then
268 local unsort = 'unsorted/' .. metadata.ogFile
269 local a, e = io.open(unsort .. tp .. '.md' , 'r')
270 if nil ~= a then
271 a:close()
272 -- Keep the .md.md symlink, delete the rest.
273 os.execute('rm ' .. unsort .. tp .. '.HTML')
274 os.execute('rm ' .. unsort .. tp .. '.md')
275 a, e = io.open(unsort .. tp .. '.HTML', 'w')
276 if nil == a then print('Could not open ' .. unsort .. tp .. '.HTML' .. ' - ' .. e) else
277 local dst = string.sub(l, 1, -4) .. '.HTML'
278 local cnt = 1
279 for j = 1, #metadata.ogFile do
280 if '/' == string.sub(metadata.ogFile, j, j) then cnt = cnt + 1 end
281 end
282 dst = string.rep('../', cnt) .. dst
283 a:write(
284[=[<!DOCTYPE html>
285<html>
286 <head><meta http-equiv="refresh" content="0; url=]=] .. dst .. '"' .. [=[/></head>
287 <body><p>Click this if you don't get redirected to the real page - <a href="]=] .. dst .. '"' .. [=[>Redirect</a></p></body>
288</html>
289]=])
290 a:close()
291 print('REDIRECT ' .. unsort .. tp .. '.HTML \t-> ' .. dst)
292 end
293
294 end
295 end
296 end
297end
298
299-- Look for copied pages from the other wikis.
300for l in io.popen('find -L ' .. Folder .. ' -name "*.HTM" -type f,l -printf "%P\n"'):lines() do
301-- Only do this if .HTM is newer than .md, or .md doesn't exist.
302 local htime = io.popen("date -ur " .. l .. " +%s"):read('l')
303 local mtime = io.popen("date -ur " .. string.sub(l, 1, -4) .. "md +%s 2>/dev/null"):read('l')
304 if (nil == mtime) or (htime > mtime) then
305 print('pandoc converting ' .. l .. ' -> ' .. string.sub(l, 1, -4) .. 'md')
306os.execute('cp ' .. l .. ' ' .. l .. '_ORIGINAL0')
307 -- Open the HTM files and do the initial cleanups, then pandoc them.
308 h = io.open(l, 'r')
309 if nil ~= h then
310 local body = h:read('*a') ; h:close()
311writeString(l .. '_ORIGINAL1', body)
312 if 'Foswiki' == string.sub(l, 1, 7) then
313 -- Strip out the actual content.
314 local beg, en = RE.find(body, [['<div id="patternMainContents">']]) if nil ~= beg then body = string.sub(body, en + 1) end
315 beg, en = RE.find(body, [['<div class="patternContent">']]) if nil ~= beg then body = string.sub(body, en + 1) end
316 beg, en = RE.find(body, [['<div class="foswikiTopic">']]) if nil ~= beg then
317 if ' -- ' == string.sub(body, en + 1, en + 4) then
318 beg, en = RE.find(body, '[%nl]', en + 4)
319 body = string.sub(body, en + 1)
320 end
321 end
322 beg, en = RE.find(body, [['<div class="patternInfo">']]) if nil ~= beg then body = string.sub(body, 1, beg - 1) end
323-- beg, en = RE.find(body, [['<div class="foswikiForm foswikiFormStep">']]) if nil ~= beg then body = string.sub(body, 1, en + 1) end
324 beg, en = RE.find(body, [['<div class="foswikiAttachments foswikiFormStep" style="overflow:auto">']]) if nil ~= beg then body = string.sub(body, 1, beg - 1) end
325 beg, en = RE.find(body, [['<div class="foswikiSearchResultsPager">']]) if nil ~= beg then body = string.sub(body, 1, beg - 1) end
326 -- Some clean ups.
327 local result = RE.compile( [[{~
328 (
329 {'class="foswikiCurrentTopicLink"'} -> blank /
330 {'class="foswikiNewLink"'} -> blank /
331 {"<span class='foswikiSmall'><a href='/bin/edit/Main/" ([^;action=form])* ";action=form'>edit</a></span>"} -> blank /
332 {" -- "} -> '-noComment-' /
333-- {"-- " ([^%nl])* } -> blank /
334 {'<div class="foswikiTopic">'} -> blank /
335 {'rel="nofollow"'} -> blank / {"rel='nofollow'"} -> blank /
336 {"target='_blank'"} -> blank /
337 {"</div>" ([%nl])* } -> blank /
338-- {'style="' ([^"])+ '"'} -> blank / {"style='" ([^'])+ "'"} -> blank /
339 .
340 )* ~}]], { blank = function(a) return '' end } ):match(body)
341 body = result
342-- body = RE.gsub(body, [=[{"<!-- ".*"-->"}]=], '') -- FIXME
343 local here = 1
344 beg, en = RE.find(body, [['https://fos.wiki.devuan.org/']], here)
345 while nil ~= beg do
346 here = beg + 1
347 local beg0, en0
348 local url = nil
349 if '"' == string.sub(body, beg - 1, beg - 1) then
350 beg0, en0 = RE.find(body, [['"']], en)
351 url = string.sub(body, en + 1, en0 - 1)
352 end
353 if "'" == string.sub(body, beg - 1, beg - 1) then
354 beg0, en0 = RE.find(body, [["'"]], en)
355 url = string.sub(body, en + 1, en0)
356 end
357
358 if nil ~= url then
359 if ('pub/' == string.sub(url, 1, 4)) then
360-- FIXME? - evil hack?
361 url = 'Foswiki/' .. url
362--print('FOSWIKI HTM ' .. url)
363 else
364 url = nil
365 end
366 end
367--print('HTM0 ' .. string.sub(body, beg, en + 84) .. ' \t\t')
368 beg, en, body, here = commonLinky(l, body, 'https://fos.wiki.devuan.org/', url, beg, en, beg0, en0, 1)
369--if nil ~= en then print('HTM1 ' .. string.sub(body, beg, en + 84) .. ' \t\t') end
370--[=[
371 if nil == url then
372 print('OOPS! unknown linky - @' .. l .. '\t\t\t' .. string.sub(body, beg - 9, en) .. ' ' .. string.sub(body, en + 1, en0))
373 else
374-- print(' linky - @' .. l .. '\t\t\t' .. string.sub(body, beg - 9, en) .. ' ' .. string.sub(body, en + 1, en0) .. ' -> ' .. url)
375 local md = readMdMd(url, {})
376-- if nil ~= md then
377 if nil ~= md.realURL then url = md.realURL end
378-- end
379 body = string.sub(body, 1, beg - 1) .. url .. string.sub(body, en0 + 1)
380 here = here + #url
381 end
382 beg, en = RE.find(body, [['https://fos.wiki.devuan.org/']], here)
383]=]
384 end
385
386 writeString(l .. '_NEW', body)
387 elseif 'PmWiki' == string.sub(l, 1, 6) then
388 local beg, en = RE.find(body, [['<!--PageText-->']]) if nil ~= beg then body = string.sub(body, en + 2) end
389 beg, en = RE.find(body, [["div id='wikitext'>"]]) if nil ~= beg then body = string.sub(body, en + 2) end
390 beg, en = RE.find(body, [["<div id='printfoot'>"]]) if nil ~= beg then body = string.sub(body, 1, beg - (2 + 9)) end -- There's a </div> to get rid of to.
391 beg, en = RE.find(body, [['<!--HTMLFooter-->']]) if nil ~= beg then body = string.sub(body, 1, beg - 2) end
392 local result = RE.compile( [[{~
393 (
394 {"class='categorylink'"} -> blank /
395 {"class='createlink'"} -> blank /
396 {"class='createlinktext'"} -> blank /
397 {"class='escaped'"} -> blank /
398 {"class='diffmarkup'"} -> blank /
399 {"class='selflink'"} -> blank /
400 {"class='urllink'"} -> blank /
401 {"<div class='vspace'></div><hr /> <a class='wikilink' href='https://wiki.devuan.org?n=Profiles." .* ([%nl])* } -> blank /
402 {"<a class='selflink' href='https://wiki.devuan.org?n=Profiles." .* ([%nl])* } -> blank /
403 {"<div class='vspace'></div><hr />"} -> blank /
404 {"<div class='vspace'></div>"} -> blank /
405 {"class='wikilink'"} -> blank /
406 {'rel="nofollow"'} -> blank / {"rel='nofollow'"} -> blank /
407 {"target='_blank'"} -> blank /
408-- {'style="' ([^"])+ '"'} -> blank / {"style='" ([^'])+ "'"} -> blank /
409 {"<span class='hlt " {([a-z])+} "'></span><pre" } -> "<pre class='%2'" /
410 .
411 )* ~}]], { blank = function(a) return '' end } ):match(body)
412 body = result
413-- body = RE.gsub(body, [=["<a " {([^ >])+} " >"]=], "<a %1>")
414-- DONE? - <span class='hlt html'></span><pre style='background-color: #cc00ff;' class='escaped'> ... lines of HTML code ... </pre>
415-- most of the time I'll see <pre class='escaped'>
416-- My own looking glass has several.
417-- Foswiki <pre class='bash'>
418-- CommonMark->HTML ---lua <pre><code class="language-lua"> .............................. </code></pre>
419-- Seems to be the spec way of doing it.
420-- most of the time I'll see <pre><code>
421
422 here = 1
423 beg, en = RE.find(body, [["'https://wiki.devuan.org/"]], here)
424 while nil ~= beg do
425 here = beg + 1
426 local beg0, en0 = RE.find(body, [["'"]], en)
427-- FIXME? - This might be working around a bug elsewhere.
428 if "'" == string.sub(body, en0, en0) then en0 = en0 - 1 end
429 local url = string.sub(body, en + 1, en0)
430 if '?n=' == string.sub(url, 1, 3) then
431 url = string.sub(url, 4):gsub('[%a]+%.([%a-]+)', '%1_pm.HTML')
432 elseif ("'" == url) or ('uploads/' == string.sub(url, 1, 8)) then
433-- FIXME - evil hack? Yep, evil hack, need to know the depth of the source, which isn't here.
434 url = 'PmWiki/' .. url
435 else
436 url = nil
437 end
438--print('HTM0 ' .. string.sub(body, beg, en + 84) .. ' \t\t')
439 beg, en, body, here = commonLinky(l, body, "'https://wiki.devuan.org/", url, beg, en, beg0, en0, 0)
440--if nil ~= en then print('HTM1 ' .. string.sub(body, beg, en + 84) .. ' \t\t') end
441 end
442
443 writeString(l .. '_NEW', body)
444 end
445 end
446
447 ok, rslt, status = os.execute('pandoc --wrap=preserve -f html -t commonmark_x --self-contained ' .. l .. '_NEW' .. ' >' .. string.sub(l, 1, -4) .. 'md')
448 end
449end
450
451if '.' ~= Folder then
452 for l in io.popen('find -L . -name "*.md" -type f,l -printf "%P\n"'):lines() do
453 toFile(string.gsub(l, '%.md$', ''))
454 end
455end
456
457-- Can add in a distant folder to, for putting it's results in the current folder.
458for l in io.popen('find -L ' .. Folder .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do
61 local n = string.gsub(l, '%.md$', '') 459 local n = string.gsub(l, '%.md$', '')
62 if nil == Files[n] then Files[n] = {} end 460 if nil == Files[n] then toFile(n) end
63end 461end
64 462
65-- Gotta figure out all the files and subs first. File and sub metadata comes along for the ride. 463
66Subs[''] = {files = {}, subs = {}, bits = {}} 464-- Gotta figure out all the files and subs first. File and sub metadata comes along for the ride, coz we need them later.
465local NewMeta = {}
67for name, file in pairs(Files) do 466for name, file in pairs(Files) do
68 local bitter, path = '', '' 467 local bitter, path = '', ''
69 local bits, bit = stringBits(name) 468 local bits, bit = file.bits, file.bit
70 local ln = #bits 469 local ln = #bits
470 local body, metadata = '', {}
71 471
72 -- Go through our bits, construct Subs with bits. 472 -- Go through our bits, construct Subs with bits.
73 Files[name].bits = bits
74 Files[name].bit = bit
75 if ln > 0 then bitter = bits[1] end 473 if ln > 0 then bitter = bits[1] end
76 if '' ~= bitter then Subs[''].subs[bitter] = bitter end -- "bitter end" was entirely by accident, I'm keeping it. B-) 474 if '' ~= bitter then Subs[''].subs[bitter] = bitter end -- "bitter end" was entirely by accident, I'm keeping it. B-)
77 for i, d in ipairs(bits) do 475 for i, d in ipairs(bits) do
78 if '' ~= path then path = path .. '/' end 476 if '' ~= path then path = path .. '/' end
79 path = path .. d 477 path = path .. d
80 if nil == Subs[path] then Subs[path] = {files = {}, subs = {}} end 478 toSub(path)
81 if i < ln then Subs[path].subs[bits[i + 1]] = bits[i + 1] end 479 if i < ln then
82 Subs[path].bits = copyTable(bits, true) 480 Subs[path].subs[bits[i + 1]] = bits[i + 1]
83 if i < ln then table.remove(Subs[path].bits, #bits) end 481 table.remove(Subs[path].bits, #bits)
482 end
84 end 483 end
85 484
86 -- Start the file parsing here, coz we need it's metadata. 485 if '.md' == string.sub(name, -3, -1) then
87 print('Parsing ' .. name .. '.md') 486 -- This is a metadata only file, no content, stash the matadata.
88 local h = io.open(name .. '.md', 'r') 487
89-- TODO - should bail here on error? 488 metadata = readMdMd(name, metadata)
90 if nil ~= h then file.cm = h:read('*a') ; h:close() else print('oops! No such name ' .. name) end 489 if '.md' == name then toSub(path, 'metadata', metadata)
91 -- Convert the CommonMark to HTML, including the metadata. 490 elseif '/.md' == string.sub(name, -4, -1) then toSub(path, 'metadata', metadata)
92 local body, metadata, err = lcmark.convert(file.cm, "html", {smart = true, yaml_metadata = true, columns = 0}) 491-- else toFile(string.sub(name, 1, -4), 'metadata', metadata)
93 if nil == body then print('oops! ' .. err) 492 else NewMeta[string.sub(name, 1, -4)] = metadata -- Coz we can't add to Files here.
94 elseif '' == body then 493 end
95 -- This is a metadata only file, no content, stash the matadata in it's directory.
96 Subs[path].metadata = metadata
97 Files[name] = nil 494 Files[name] = nil
98 else
99 -- Ordinary md file, stash it's metadata and parsed body.
100 file.metadata = metadata
101 file.body = body
102 table.insert(Subs[path].files, bit)
103 end 495 end
104end 496end
105 497
498-- FIXED - Lua doesn't like modifying the thing you are pair()ing, like we want to do in the last loop.
499for name, file in pairs(NewMeta) do
500 if nil == Files[name] then toFile(name) end
501 for k, v in pairs(file) do
502 if nil == Files[name].metadata[k] then Files[name].metadata[k] = v end
503 end
504end
505
506-- Fix up subs now we have all the file bits.
507for name, file in pairs(Files) do
508 if '.md' ~= string.sub(name, -3, -1) then
509 table.insert(Subs[file.path].files, file.bit)
510 end
511end
512
513-- Find empty subs.
514for name, sub in pairs(Subs) do
515 if 0 == #sub.files then
516 print("EMPTY " .. name)
517 h = io.open(name .. '/index.md', 'w')
518 if nil ~= h then
519 h:write('This folder has no files.')
520 h:close()
521 else
522 print("Can't open " .. name .. '/index.md for writing.')
523 end
524 end
525end
106 526
107 527
528---------------------------------------------------------------------------------
108-- These functions assume the above file and sub scan has completed. 529-- These functions assume the above file and sub scan has completed.
109 530
110-- Which page in this directory should we show? 531-- Which page in this folder should we show?
111-- NOTE - only looking for the .md files we scanned for before, any stray HTML, html, HTM, atd htm files will get ignored. 532-- NOTE - only looking for the .md files we scanned for before, any stray HTML, html, HTM, and htm files will get ignored.
112local whichPage = function(f) 533local whichPage = function(f)
113 local fl = '' 534 local fl = ''
114 if (nil ~= Subs[f]) and (nil ~= Subs[f].files) then 535 if nil ~= Subs[f] then
115 if 1 == #(Subs[f].files) then fl = Subs[f].files[1] .. '.HTML' else 536 if nil ~= Subs[f].whichPage then return Subs[f].whichPage end
116 -- Standard files to search for. 537 if nil ~= Subs[f].files then
117 for i, v in ipairs{'about', 'readme', 'index', 'homepage', 'mainpage', 'webhome'} do 538 if 1 == #(Subs[f].files) then fl = Subs[f].files[1] else
118 for j, w in ipairs(Subs[f].files) do 539 -- Standard files to search for.
119 if v == string.lower(w) then 540 for i, v in ipairs{'about', 'readme', 'index', 'homepage', 'mainpage', 'webhome'} do
120 fl = v .. '.HTML' 541 for j, w in ipairs(Subs[f].files) do
121 break 542 if v == string.lower(w) then
543 fl = w
544 break
545 end
122 end 546 end
547 if '' ~= fl then break end
123 end 548 end
124 if '' ~= fl then break end 549 -- If nothing else, just grab the first one.
550 if ('' == fl) and (nil ~= Subs[f].files[1]) then fl = Subs[f].files[1] end
125 end 551 end
126 -- If nothing else, just grab the first one.
127 if ('' == fl) and (nil ~= Subs[f].files[1]) then fl = Subs[f].files[1] end
128 end 552 end
129 end 553 end
554 if '' ~= fl then fl = fl .. '.HTML' ; Subs[f].whichPage = fl end
130 return fl 555 return fl
131end 556end
132 557
133 558
134-- Calculate a link from the source directory to the destination directory. 559-- Figure out the original title and link for the original wiki.
560local whichWiki = function(metadata)
561 local title, link = '', ''
562 if 'PmWiki' == metadata.ogWiki then
563 title = metadata.ogBase .. '.' .. metadata.ogFile
564 link = metadata.ogURL .. '/?n=' .. metadata.ogBase .. '.' .. metadata.ogFile
565 end
566 if 'Foswiki' == metadata.ogWiki then
567 title = metadata.ogBase .. '/' .. metadata.ogFile
568 link = metadata.ogURL .. '/' .. metadata.ogBase .. '/' .. metadata.ogFile
569 end
570 return title, link
571end
572
573
574-- Calculate a link from the source folder to the destination folder.
135local linkFrom = function(source, dest) 575local linkFrom = function(source, dest)
576 -- Evil hacks!
577 if 'Profiles' == dest then dest = 'PmWiki/Profiles' end
578 if 'Onefang' == dest then dest = 'PmWiki/Onefang' end
579 if 'Tiki' == dest then dest = 'PmWiki/Tiki' end
580
581 if source == dest then return '' end
136 local depth = 0 582 local depth = 0
137 local link = '' 583 local lnk = ''
138 if source ~= dest then 584 if source ~= dest then
139 for i, v in ipairs(Subs[source].bits) do 585 if nil == Subs[source] then
140 if v ~= Subs[dest].bits[i] then 586-- print('!!!! No idea where to find source ' .. source)
141 depth = i 587 return 'DUNNO'
142 break 588 end
589 if nil == Subs[dest] then
590 if dest == Subs[source].bit then
591 return ''
592 else
593-- print('!!!! No idea where to find dest ' .. dest .. ' from ' .. Subs[source].path .. ' / ' .. Subs[source].bit)
594 return 'DUNNO'
143 end 595 end
144 end 596 end
145 depth = #(Subs[source].bits) - depth 597 local s = Subs[source].bits
146 depth = depth + 1 598 local d = Subs[dest].bits
147 link = string.rep('../', depth) 599 local sl = #s
148 if (0 == depth) or (depth > #(Subs[dest].bits)) then 600 local dl = #d
149 for i, v in ipairs(Subs[dest].bits) do 601
150 if i >= depth then 602 if 0 == dl then
151 if '' ~= link then link = link .. '/' end 603 depth = sl
152 link = link .. Subs[dest].bits[i] 604 else
605 for i, v in ipairs(s) do
606 if (nil == d[i]) or (v ~= d[i]) then
607 depth = i
608 break
153 end 609 end
154 end 610 end
155 end 611 end
612 -- depth is where they DON'T match.
613 local m = depth - 1
614 if 0 > m then m = 0 end
615 lnk = string.rep('../', sl - m)
616 if 0 ~= (m + 1) then lnk = lnk .. table.concat(d, '/', m + 1, dl) end
156 end 617 end
157 return link 618 return lnk
158end 619end
159 620
160 621
161 622
623---------------------------------------------------------------------------------
162-- More of this actually doing things nonsense. 624-- More of this actually doing things nonsense.
163 625
164-- Loop through the files we found and actually create their HTML files. 626-- Create an "everything" page, for URL links to every file.HTML.
627local Bdy = '# All the pages\n\n| page | original page | last edited UTC | \n| --------- | ------- | --------------- | '
628Pages = {}
165for name, file in pairs(Files) do 629for name, file in pairs(Files) do
166 local path, result = '', '' 630 local metadata = derefTable(Files[name].metadata, true)
167 local body, metadata = Files[name].body, Files[name].metadata 631 if ('everything' ~= name) then
168 local bits, bit = Files[name].bits, Files[name].bit 632 local ln, fw, pw, ts = 'DUNNO', '', '', ''
169 local ln = #bits 633 local title, link = whichWiki(metadata)
170 634 link = string.gsub(link, 'https://', 'HTTPS://') -- Prevent this one from being converted.
171 path = table.concat(bits, '/', 1, ln) 635 if 'PmWiki' == metadata.ogWiki then pw = 'PmWiki [' .. title .. '](' .. link .. ')' end
636 if 'Foswiki' == metadata.ogWiki then fw = 'Foswiki [' .. title .. '](' .. link .. ')' end
637 if nil ~= metadata.timestamp then ts = metadata.timestamp end
638 if nil ~= file.bit then ln = file.bit
639 end
640 table.insert(Pages, '\n| [' .. name .. '](<' .. name .. '.HTML>) | ' .. fw .. ' ' .. pw .. ' | ' .. ts .. ' |')
172 641
173 if '' ~= body then 642 -- Track our external links.
174 -- Continue the parsing and conversion. Start by turning our parsed body into something the lcmark template system can grock. 643 if (nil ~= metadata.ogBase) and (nil ~= metadata.ogFile) then
175 local bod, err = lcmark.compile_template(body) 644 local n = metadata.ogBase
176 if nil == bod then print('oops! ' .. err) else 645 if 'PmWiki' == metadata.ogWiki then n = n .. '.' else n = n .. '/' end
177 local templateFile = metadata.template 646 xLinks[n .. metadata.ogFile] = file.path
178 if nil == templateFile then templateFile = 'default' end
179 file.template = templateFile .. '.template'
180 end 647 end
648 end
649end
650table.sort(Pages, function(a, b) return (string.lower(a) < string.lower(b)) end)
651for i, f in ipairs(Pages) do
652 Bdy = Bdy .. f
653end
654h = io.open('everything.md', 'a+')
655if nil ~= h then
656 h:write(Bdy)
657 h:close()
658else
659 print("Can't open everything.md for writing.")
660end
661toFile('everything', 'body', Bdy)
181 662
182 -- Copy any metadata found in parent directories. 663
183 local pth = '' 664-- Loop through Subs, doing whichPage and inheritance.
184 for i, d in ipairs(bits) do 665-- It gets to testing/even/deeper BEFORE it gets to testing/even sometimes. So sort them.
185 if '' ~= pth then pth = pth .. '/' end 666SUBS = {}
186 pth = pth .. d 667for name, sub in pairs(Subs) do
187 if nil ~= Subs[pth] then 668 table.insert(SUBS, sub)
188 if nil ~= Subs[pth].metadata then 669end
189 for m, x in pairs(Subs[pth].metadata) do 670table.sort(SUBS, function(a, b) return (string.lower(a.path) < string.lower(b.path)) end)
190 if nil == metadata[m] then 671for n, sub in pairs(SUBS) do
191 metadata[m] = x 672 local name = sub.path
192 end 673 sub.whichPage = whichPage(name)
674 local metadata = sub.metadata
675 for i, s in pairs(sub.subs) do
676 local nm = i
677 if '' ~= name then nm = name .. '/' .. i end
678 for k, v in pairs(metadata) do
679 if nil == Subs[nm].metadata[k] then
680 if ('favicon' == k) or ('logo' == k) then
681 Subs[nm].metadata[k] = linkFrom(nm, name) .. v
682 else
683 if 'hidden' ~= k then -- Don't inherit hidden.
684 Subs[nm].metadata[k] = v
193 end 685 end
194 end 686 end
195 end 687 end
196 end 688 end
197 -- Root directory needs to be handled separately, for now. 689 end
198 if nil ~= Subs[''].metadata then 690end
199 for m, x in pairs(Subs[''].metadata) do if nil == metadata[m] then metadata[m] = x end end 691
692-- Files inheritance.
693for name, file in pairs(Files) do
694 if '' ~= file.body then
695 local mdata = Subs[file.path].metadata
696 for k, v in pairs(mdata) do
697 if nil == file.metadata[k] then
698 Files[name].metadata[k] = v
699 end
200 end 700 end
701 end
702end
201 703
202 for m, x in pairs(globalData) do if nil == metadata[m] then metadata[m] = x end end
203 704
204 -- Inherit these images from most recent parent directory that defines them. 705---------------------------------------------------------------------------------
205 for n, y in ipairs{'favicon', 'logo'} do 706-- Setup the lunarmark stuff.
206 local pith = '' 707local LunamarkOpts = {
207 if nil ~= metadata[y] then 708 layout='compact',
208 local pth = '' 709-- This list is copied from the lunamark source code, until I discover a way to discover it. The descriptions are useful to.
209 for m, x in ipairs(bits) do 710 containers=false, -- Put sections in containers (e.g. div or section tags)
210 if '' ~= pth then pth = pth .. '/' end 711 slides=false, -- Like containers, but do not nest them
211 pth = pth .. x 712 startnum=true, -- Start number of an ordered list is significant
212 if (nil ~= Subs[pth].metadata) and (nil ~= Subs[pth].metadata[y]) then pith = pth end 713 smart=false, -- Smart typography (quotes, dashes, ellipses)
714 preserve_tabs=true, -- Don't expand tabs to spaces
715 notes=true, -- Footnotes
716 inline_notes=true, -- Inline footnotes
717 definition_lists=true, -- Definition lists
718 citations=true, -- Citations
719 citation_nbsps=true, -- Turn spacing into non-breaking spaces in citations
720 fenced_code_blocks=true, -- Fenced code blocks
721 lua_metadata=true, -- Lua metadata
722 pandoc_title_blocks=true, -- Pandoc style title blocks
723 hash_enumerators=true, -- may be used as ordered list enumerator
724 require_blank_before_blockquote=false,
725 require_blank_before_header=false,
726 require_blank_before_fenced_code_block=false,
727 fancy_lists=true, -- Pandoc style fancy lists
728 task_list=true, -- GitHub-Flavored Markdown task list
729 strikeout=true, -- Strike-through with double tildes
730 mark=true, -- Highlight with double equals
731 subscript=true, -- Subscripted text between tildes
732 superscript=true, -- Superscripted text between circumflexes
733 bracketed_spans=true, -- Spans with attributes
734 fenced_divs=true, -- Divs with attributes
735 raw_attribute=true, -- Raw pass-through on code elements
736 fenced_code_attributes=true, -- Fenced code block attributes
737 link_attributes=true, -- Link attributes
738 pipe_tables=true, -- PHP Markdown Extra pipe table support
739 table_captions=true, -- Table caption syntax extension
740 header_attributes=true, -- Header attributes
741 line_blocks=true, -- Line blocks
742 escaped_line_breaks=true, -- Pandoc-style escaped hard line breaks
743}
744local Writer = Lunamark.writer.html5.new(LunamarkOpts)
745-- Can override the various writer functions, there's something for each of the basic HTML elements.
746local lunaLinky = function(url) -- Fix up the links.
747 if ('https://wiki.devuan.org/' ~= url) and ('https://fos.wiki.devuan.org/' ~= url) then
748 -- TODO - This might be covering up a bug elsewhere.
749 if '/Main/' == string.sub(url, 1, 6) then
750 local link = linkFrom(Context.path, 'Foswiki/Main')
751 if '' == link then
752 url = string.sub(url, 7) .. '.HTML'
753 else
754 url = link .. '/' .. string.sub(url, 7) .. '.HTML'
755 end
756 end
757 if '/System/' == string.sub(url, 1, 8) then
758 url = 'https://fos.wiki.devuan.org' .. url
759 end
760 for i, p in ipairs{'https://wiki.devuan.org/?n=', 'https://wiki.devuan.org?n=', 'PmWiki/uploads/', 'Foswiki/pub/', 'https://fos.wiki.devuan.org/'} do
761 if p == string.sub(url, 1, #p) then
762 local ur = string.sub(url, #p + 1)
763-- TODO - could probably replace some of this mess with RE.gsub() and friends. Meh, it works.
764 local f4, f5, tk1 = string.find(ur, '?', 1, true)
765 if fail ~= f4 then
766 local u = string.sub(ur, 1, f4 - 1)
767 ur = u
213 end 768 end
214 if ('' == pith) and (nil ~= Subs[''].metadata) and (nil ~= Subs[''].metadata[y]) then pith = pth end 769 local md
215 if '' == pith then metadata[y] = linkFrom(path, pith) .. globalData[y] 770 if ('fos' == string.sub(p, 9, 11)) or ('Fos' == string.sub(p, 1, 3)) then
216 else metadata[y] = linkFrom(path, pith) .. metadata[y] 771 md = readMdMd('Foswiki/' .. ur .. '.md', {})
772 else
773 md = readMdMd('PmWiki/' .. string.gsub(ur, '%.', '/', 1) .. '.md', {})
774 end
775 if (nil ~= md) and (nil ~= md.realURL) then url = md.realURL end
776
777 if ('https://fos.wiki.devuan.org/bin/' ~= string.sub(url, 1, 32)) and ('https://fos.wiki.devuan.org/System/' ~= string.sub(url, 1, 35)) then
778 local xlnk = xLinks[string.gsub(ur, '%..*', '', 1)]
779 if nil == Context.path then
780 url = string.gsub(ur, '%.', '/', 1)
781 else
782 if nil == xlnk then xlnk = string.gsub(string.gsub(ur, '%..*', '', 1), '/.*', '', 1) end
783 if '' ~= Context.path then xlnk = linkFrom(Context.path, xlnk) end
784 if '/' == string.sub(xlnk, 1, 1) then xlnk = string.sub(xlnk, 2) end
785 if ('' ~= xlnk) and ('/' ~= string.sub(xlnk, -1)) then xlnk = xlnk .. '/' end
786 if 'DUNNO/' == xlnk then print('OOPS! page not found - @' .. Context.path .. ' / ' .. Context.bit .. '\t' .. url .. ' -> ' .. xlnk .. ' ' .. string.gsub(ur, '.*%.', '', 1) .. '.HTML') end
787 end
788-- if (nil ~= md) and (nil ~= md.realURL) then url = md.realURL
789-- else
790 url = xlnk .. string.gsub(ur, '.*%.', '', 1)
791-- end
792 if 'PmWiki/uploads/' == p then
793 url = '../../' .. p .. string.gsub(ur, '%.', '.', 1)
794 elseif 'Foswiki/pub/' == p then
795 url = '../../' .. p .. ur
796 else
797 url = url .. '.HTML'
798 end
217 end 799 end
218 end 800 end
219 end 801 end
802 end
803 return url
804end
220 805
221 -- Figure out this pages header links. 806function Writer.header(s, level)
222 metadata.header = '' 807 local text = Lunamark.util.rope_to_string(s)
223 for i, f in pairs(Subs[path].subs) do 808-- FIXME - Work around a bug in Lunamark?
224 local pth = path 809 text = RE.gsub(text, "{[\\]}", "")
225 if '' ~= path then pth = path .. '/' end 810 return '<h' .. level .. ' id="' .. RE.gsub(text, '{[ ]}', '_') .. '">' .. text .. ' <a style="font-size: 0.42em;" href="#top">🔼</a></h' .. level .. '>'
226 local fl = whichPage(pth .. f) 811end
227-- if '' == fl then 812local OgWriterLink = Writer.link -- So we can call the original from within mine, we are just changing the URL.
228-- metadata.header = metadata.header .. f .. ' &nbsp; ' 813function Writer.link(lab, url, tit)
229-- else 814 return OgWriterLink(lab, lunaLinky(url), tit)
230 metadata.header = metadata.header .. '<a href="' .. f .. '/' .. fl .. '">' .. f .. '</a> &nbsp; ' 815end
231-- end 816local OgWriterImage = Writer.image
232 end 817function Writer.image(lab, url, tit)
818 return OgWriterImage(lab, lunaLinky(url), tit)
819end
820
821local Parse = Lunamark.reader.markdown.new(Writer, LunamarkOpts)
233 822
234 -- Figure out this pages menu links.
235 metadata.menu = ''
236 if nil ~= Subs[path].files then table.sort(Subs[path].files) end
237 for i, f in ipairs(Subs[path].files) do
238 if name == f then
239 metadata.menu = metadata.menu .. '<p>' .. f .. '</p>'
240 else
241 metadata.menu = metadata.menu .. '<p><a href="' .. f .. '.HTML">' .. f .. '</a></p>'
242 end
243 end
244 823
824---------------------------------------------------------------------------------
825-- Loop through the files we found and actually create their HTML files.
826for name, file in pairs(Files) do
827 local body, metadata = Files[name].body, derefTable(Files[name].metadata, true)
828 local bits, bit = Files[name].bits, Files[name].bit
829 local ln = #bits
830 local result = ''
831
832 if '' ~= body then
245 -- Figure out this pages trail links. 833 -- Figure out this pages trail links.
834 metadata.home = linkFrom(file.path, '') .. Subs[''].whichPage
246 metadata.trail = '' 835 metadata.trail = ''
247 for i, b in ipairs(bits) do 836 for i, b in ipairs(bits) do
837 local p = table.concat(bits, '/', 1, i)
248 if i < #bits then 838 if i < #bits then
249 metadata.trail = metadata.trail .. '<a href="' .. linkFrom(path, table.concat(bits, '/', 1, i)) .. whichPage(b) .. '">' .. b .. '</a> &nbsp; ' 839 metadata.trail = metadata.trail .. '<a href="' .. linkFrom(file.path, p) .. Subs[p].whichPage .. '">' .. b .. '</a> &nbsp; &#x1f463; '
250 linkFrom(path, table.concat(bits, '/', 1, i)) 840 linkFrom(file.path, table.concat(bits, '/', 1, i))
251 else 841 else
252 metadata.trail = metadata.trail .. b .. ' &nbsp; ' 842 metadata.trail = metadata.trail .. ' ' .. b
253 end 843 end
254 end 844 end
255-- if '' == metadata.trail then metadata.trail = '<a href="' .. string.rep('../', ln) .. '/' .. whichPage('') .. '">home</a> &nbsp; ' end
256
257 -- Figure out this pages footer links.
258 if nil ~= metadata.pagehistory then metadata.history = '<p>Page&nbsp;<a href="' .. metadata.pagehistory .. '">history</a></p>' end
259 if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a> &nbsp; &nbsp; ' .. metadata.footer end
260 if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed</a> &nbsp; &nbsp; ' .. metadata.footer end
261 if metadata.footer ~= globalData.footer then metadata.footer = 'Web site ' .. metadata.footer end
262 metadata.footer = '<p>' .. metadata.footer .. '</p>'
263 845
264 -- Apply the template to the body. 846 -- Figure out this pages header links.
265 metadata.body = lcmark.apply_template(bod, metadata) 847 metadata.header = ''
848 subs = {}
849 for i, f in pairs(Subs[file.path].subs) do
850 table.insert(subs, f)
851 end
852 table.sort(subs, function(a, b) return (string.lower(a) < string.lower(b)) end)
853 for i, f in ipairs(subs) do
854 local pth = file.path
855 if '' ~= file.path then pth = file.path .. '/' end
856 if 'true' ~= Subs[pth .. f].metadata.hidden then
857 metadata.header = metadata.header .. '<a href="' .. f .. '/' .. whichPage(pth .. f) .. '">' .. f .. '</a> &nbsp; &#128194; '
858 end
859 end
266 860
267 -- Put it all in the template. 861 -- Figure out this pages menu links.
268 local tm = '' 862 metadata.menu = ''
269 if nil ~= file.template then 863 if nil == metadata.title then metadata.title = bit end
270 local h = io.open(file.template, 'r') 864 if nil ~= Subs[file.path].files then table.sort(Subs[file.path].files, function(a, b) return (string.lower(a) < string.lower(b)) end) end
271 if nil ~= h then 865 for i, f in ipairs(Subs[file.path].files) do
272 tm = tm .. h:read('*a') 866 local title, url = nil, nil
273 h:close() 867 if '' == file.path then
868 title = Files[f].metadata.title
869 url = Files[f].metadata.URL
274 else 870 else
275 print('oops! No such file ' .. file.template) 871 title = Files[file.path .. '/' .. f].metadata.title
872 url = Files[file.path .. '/' .. f].metadata.URL
276 end 873 end
277 874 if nil == title then title = f end
278-- TODO - Um not sure why this is here AND at the top of the loop. Here makes more sense. 875 if bit == f then
279 local template, err = lcmark.compile_template(tm) 876 metadata.menu = metadata.menu .. '<p>' .. title .. '</p>'
280 if nil == template then print('oops! ' .. err) else 877 for j, g in ipairs(file.headers) do
281 result = lcmark.apply_template(template, metadata) 878 local beg, en = RE.find(g, [['{']])
879 if nil ~= beg then
880 g = string.sub(g, 1, beg - 2)
881 end
882 local h = string.sub(RE.gsub(g, '{[#]}', ''), 2)
883 local l = string.len(g) - string.len(h)
884 g = h
885 h = RE.gsub(h, '{[ ]}', '&nbsp;')
886-- FIXME - Work around a bug in Lunamark?
887 g = RE.gsub(g, '{[\\]}', '')
888 h = RE.gsub(h, '{[\\]}', '')
889-- FIXME - if it's a linky, strip off the URL part. The Wiki audit has such things.
890 metadata.menu = metadata.menu .. '<p>' .. string.rep('&nbsp;', l) .. '<a style="font-size: 0.80em;" href="#' .. RE.gsub(g, '{[ ]}', '_') .. '">' .. h .. '</a></p>'
891 end
892 else
893 if nil ~= url then metadata.menu = metadata.menu .. '<p><a href="' .. url .. '">' .. title .. ' &#9757;</a></p>'
894 else
895 local pth = file.path
896 if '' ~= pth then pth = pth .. '/' end
897 -- Don't include any left over .md.md files, so don't do this if f.md doesn't exist.
898 local a, e = io.open(pth .. f .. '.md' , 'r')
899 if nil ~= a then
900 a:close()
901 metadata.menu = metadata.menu .. '<p><a href="' .. f .. '.HTML">' .. title .. '</a></p>'
902 end
903 end
282 end 904 end
905 end
906
907 -- Figure out this pages footer links.
908 local temp = ''
909 metadata.footer = ''
910 if nil == metadata.pagehistory then
911 if 'Foswiki' == metadata.ogWiki then metadata.pagehistory = metadata.ogURL .. '/bin/oops/' .. metadata.ogBase .. '/' .. metadata.ogFile .. '?template=oopshistory' end
912 if 'PmWiki' == metadata.ogWiki then metadata.pagehistory = metadata.ogURL .. '/?n=' .. metadata.ogBase .. '.' .. metadata.ogFile .. '?action=diff' end
283 else 913 else
284 result = body 914 temp = '/' .. name .. '.md'
285 end 915 end
916 if nil ~= metadata.pagehistory then metadata.history = '<p>Page&nbsp;<a href="' .. metadata.pagehistory .. temp .. '">history</a></p>' else
917 metadata.history = ''
918 end
919 if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a>' end
920 if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed<img src="feed-icon-14x14.png"></img></a> &nbsp; &nbsp; ' .. metadata.footer end
921 if metadata.footer ~= '' then metadata.footer = 'Web site ' .. metadata.footer end
922 -- Add a link to the original page.
923 if nil ~= metadata.ogURL then
924 local title, link = whichWiki(metadata)
925 link = string.gsub(link, 'https://', 'HTTPS://') -- Prevent this one from being converted.
926-- TODO - wrap "edit" in a link to actually edit it. PmWiki "?action=edit" Foswiki "https://fos.wiki.devuan.org/bit/edit/" .. page .. "?t=" .. 10 digit random number?
927 local edit = 'T'
928 if 'PmWiki' == metadata.ogWiki then edit = 'Maybe you can <a href="' .. link .. '?action=edit">edit</a> t' end
929-- if 'Foswiki' == metadata.ogWiki then edit = '' end
930 metadata.footer = edit .. 'he <a href="' .. link .. '">original page</a>. &nbsp; ' .. metadata.footer
931 end
932 metadata.footer = '<p>' .. metadata.footer .. '</p>'
933
934 -- Do our own metadata replacement, it's simple and works better.
935 local temp = Template
936 -- Toss the body in first, so the scan can deal with it to.
937 -- NOTE - this is where we actually parse the markup into HTML.
938 Context = file
939 body = RE.gsub(body, '{[%nl]^1[%a]+}[.]^1 ', '%1$dot$ ') -- Coz otherwise stray . trip up the list detection.
940 local bd, md = Parse(body) -- The md is a table of extracted metadata, not likely to be any, and we wont do anything with it.
941 bd = RE.gsub(bd, '{[%]}', '$perc$') -- Coz otherwise stray % trip up the capture part.
942 temp = RE.gsub(temp, '"$body$"', bd)
943 -- The actual metadata replacement.
944 result = RE.compile ('{~ ({[$][A-Za-z_]+[$]} -> meta / .)* ~}',
945 {
946 meta = function(a)
947 a = string.sub(a, 2, -2)
948 local md = metadata[a]
949 if nil == md then
950 md = GlobalMetaData[a]
951 if nil == md then
952 md = a
953 end
954 end
955 return md
956 end
957 } ):match(temp)
286 958
287 -- Write the file. 959 -- Write the file.
288 if '' ~= result then 960 if '' ~= result then
289 local base = name .. '.HTML' 961-- print('From ' .. name .. '.md -> ' .. base)
290 print('From ' .. name .. '.md -> ' .. base) 962 writeString(name .. '.HTML', result)
291 local a, e = io.open(base, 'w')
292 if nil == a then print('Could not open ' .. base .. ' - ' .. e) else
293 a:write(result)
294 a:close()
295 end
296 end 963 end
297
298 else
299 print('')
300 end 964 end
301end 965end
302 966
diff --git a/testing/.md.md b/testing/.md.md
new file mode 100644
index 0000000..28c4410
--- /dev/null
+++ b/testing/.md.md
@@ -0,0 +1 @@
logo=Connie_click-me.gif
diff --git a/testing/MeTaDaTa.md b/testing/MeTaDaTa.md
deleted file mode 100644
index c4b8e60..0000000
--- a/testing/MeTaDaTa.md
+++ /dev/null
@@ -1,3 +0,0 @@
1---
2logo: Connie_click-me.gif
3---
diff --git a/testing/index.md b/testing/index.md
index f926155..581d301 100644
--- a/testing/index.md
+++ b/testing/index.md
@@ -1,71 +1,94 @@
1--- 1# G'day world!
2pagetitle: "G'day world!" 2
3author: onefang 3I've been around since the early sixties, but no one ever noticed. You
4pagehistory: https://sledjhamr.org/cgit/notYetAnotherWiki/log/testing/index.md 4really should have tried to pay attention though, I'm awesome. I try to
5--- 5help the world, but that's not what everyone wants me to do. Well, the
6
7I've been around since the early sixties, but no one ever noticed.&nbsp; You
8really should have tried to pay attention though, I'm awesome.&nbsp; I try to
9help the world, but that's not what everyone wants me to do.$_$ Well, the
10people in charge of this poor defenseless world of ours. 6people in charge of this poor defenseless world of ours.
11 7
12 8
13*** 9***
14 10
11## Em'n'Strong
12
13Test *em* _em_ **strong** __strong__ .
14
15# Spaces 15# Spaces
16 16
17Can it *handle* my _usual_ two **space** sentence breaks? Let's test it.$_$ Not by default. 17Can it *handle* my _usual_ two **space** sentence breaks? Let's test it. Not by default.
18 18
19The \\ before a space turns it into a "a literal unicode nonbreaking space character" which looks invisible in the source.&nbsp; \--ascii should output the HTML code far that.$_$ Except doesn't actually work. 19The \\ before a space turns it into a "a literal unicode nonbreaking space character" which looks invisible in the source.\ \--ascii should output the HTML code far that. Except doesn't actually work.
20 20
21Also a \\ at the end of a line turns into a line break, though they get wrapped in paragraph tags.$_$ lol 21Also a \\ at the end of a line turns into a line break, though they get wrapped in paragraph tags. lol \
22 22
23Take two.$_$ And now for something completely different.&nbsp; It's not consistant, need to manually put in the nbsp a few times above.&nbsp; Ah, it only works for the first one per line. 23Just to double check. That's a single space.
24 24
25\ 25\ \$ \' \" \| %
26
27I'm 100% sure that % will get treated correctly now.
26 28
27## Strike out 29## Strike out
28 30
29Test ~~strike~~ --out--.$_$ Needs the extension. 31Test ~~strike~~ --out--. Needs the extension.
30 32
31### URL 33### URL
32 34
33[untalenz](https://untalenz.rocks/) 35[untalenz](https://untalenz.rocks/)
34 36
37[nope.example.com](http://nope.example.com/)
38
35https://sledjhamr.org/ 39https://sledjhamr.org/
36 40
37# Lists 41# Lists
38 42
39 43
40* zero 44* first star
41* 1 45* second star
42* two
43 46
44- zero 47<!-- Separate the lists. -->
45- 1
46- two
47 48
49- first dash
50- second dash
48 51
49No way to say "here is the end of the list" without putting something **else** here?$_$ Ah a comment will work, or anything else. 52No way to say "here is the end of the list" without putting something **else** here? Ah a comment will work, or anything else.
50 53
541. one
552. two
56
57<!-- A comment will work -->
51 58
590. zero
521. one 601. one
532. 2 612. two
54 62
63Autonumbering? Needs the extension. Doesn't matter, they get renumbered anyway if out of order.
55 64
56<!-- A comment will work --> 650. zero
66#. first hash
67#. second hash
57 68
69<!-- Separate the lists. -->
58 70
590. 0 71#. first hash
601. one 72#. second hash
612. 2 73#. third hash
62 74
63Autonumbering? Nope. B-( 75<!-- Separate the lists. -->
64 76
650. zero 770. zero
66 1 782. two
67 two 791. one
80
81Bug. If there's a single word and period at the beginning of a line, it gets turned into a list, or list item.
82
83<!-- Separate the lists. -->
84
85Bug. If there's a single word and period at the beginning of a line, it gets turned into a list, or list item.
86
87~~~
88Bug. If there's a single word and period at the beginning of a line, it gets turned into a list, or list item.
89~~~
68 90
91The stuff in a code block is in a different font, it's mono. lol
69 92
70# images 93# images
71 94
@@ -84,19 +107,46 @@ Autonumbering? Nope. B-(
84 107
85 Plus some extra text. 108 Plus some extra text.
86 109
110
111Next code block.
112
113
114~~~lua
115 a simple
116 indented code block
117 <a/>
118 *hi*
119
120 - one
121
122 Plus some extra text.
123~~~
124
125
126Next code block.
127
87~~~ 128~~~
88< 129<
89 > 130 >
90~~~ 131~~~
91 132
133And a really long one, should turn scrollable.
92~~~lua 134~~~lua
93-- Show some Lua code here, may even be highlighted right. 135-- Show some Lua code here, may even be highlighted right.
94print("G'day world!") 136print("G'day world!")
95-- Let's see what happens with the HTML output by cmark, then gets rendered by the web browser, inside my CSS styled pre code thingy that cmark produces. For a very very very loooong line. Needs to be much longer. What else can I add to this already quite long line to get it to trigger being overly long? I need even mooooooore??? 137-- Let's see what happens with the HTML output by cmark, then gets rendered by the web browser, inside my CSS styled pre code thingy that cmark produces. For a very very very loooong line. Needs to be much longer. What else can I add to this already quite long line to get it to trigger being overly long? I need even mooooooore???
96print'The problem here is that I have to use CSS to style these things, coz cmark wont let me at the style stuff as far as I can see. But using CSS web browsers think the nmall box STILL extends all the way to the end of the content, but the scroll works anyway. So it's fucking up the size of the container.' 138print'The problem here is that I have to use CSS to style these things, coz cmark wont let me at the style stuff as far as I can see. But using CSS web browsers think the small box STILL extends all the way to the end of the content, but the scroll works anyway. So it's fucking up the size of the container.'
97~~~ 139~~~
98 140
99> # What is a blockquote? 141> # What is a blockquote?
100> Still don't know. lol 142> Still don't know. lol
101> 143>
102> Just another useless way to eat space I guess.$_$ shrugs 144> Just another useless way to eat space I guess. shrugs
145> Might be why emails sometimes get that symbol dropped in HTML conversions.
146
147
148|This should be a table. |With two columns and a link |
149|-------------------------|-------------------------------|
150|cell 0,0 |cell 0,1 |
151|cell 1,0 |[linky](https://sledjhamr.org) |
152
diff --git a/testing/index.md.md b/testing/index.md.md
new file mode 100644
index 0000000..c85bb3f
--- /dev/null
+++ b/testing/index.md.md
@@ -0,0 +1 @@
title=G'day world!