diff options
Diffstat (limited to 'notYetAnotherWiki.lua')
-rwxr-xr-x | notYetAnotherWiki.lua | 348 |
1 files changed, 242 insertions, 106 deletions
diff --git a/notYetAnotherWiki.lua b/notYetAnotherWiki.lua index 44f311c..f53691b 100755 --- a/notYetAnotherWiki.lua +++ b/notYetAnotherWiki.lua | |||
@@ -15,7 +15,7 @@ local RE = require("re") -- Part of lpeg. https://www.inf.puc-rio.br/~roberto/ | |||
15 | -- Some global data. | 15 | -- Some global data. |
16 | 16 | ||
17 | local GlobalMetaData = { | 17 | local GlobalMetaData = { |
18 | dlr = '$', perc = '%', | 18 | dlr = '$', perc = '%', dot = '.', |
19 | devuanCinnabarDark = '#310202', devuanCinnabarLight = '#510505', | 19 | devuanCinnabarDark = '#310202', devuanCinnabarLight = '#510505', |
20 | devuanDarkPurpyDark = '#33313b', devuanDarkPurpyLight = '#3c3a45', | 20 | devuanDarkPurpyDark = '#33313b', devuanDarkPurpyLight = '#3c3a45', |
21 | devuanDeepSeaDark = '#132f40', devuanDeepSeaLight = '#1a4562', | 21 | devuanDeepSeaDark = '#132f40', devuanDeepSeaLight = '#1a4562', |
@@ -31,6 +31,7 @@ local GlobalMetaData = { | |||
31 | } | 31 | } |
32 | 32 | ||
33 | local Files, Subs, xLinks = {}, {}, {} | 33 | local Files, Subs, xLinks = {}, {}, {} |
34 | local Context = {} -- Coz can't otherwise pass context through to the deeper Lunamark functions I'm overriding. | ||
34 | 35 | ||
35 | local Template = '' | 36 | local Template = '' |
36 | local h = io.open("default.template", 'r') | 37 | local h = io.open("default.template", 'r') |
@@ -87,6 +88,7 @@ local toFile = function(name, key, value) | |||
87 | local bits, bit = stringBits(name) | 88 | local bits, bit = stringBits(name) |
88 | local path = '' | 89 | local path = '' |
89 | Files[name] = {} | 90 | Files[name] = {} |
91 | Files[name].headers = {} | ||
90 | Files[name].bits = bits | 92 | Files[name].bits = bits |
91 | Files[name].bit = bit | 93 | Files[name].bit = bit |
92 | for i, d in ipairs(bits) do | 94 | for i, d in ipairs(bits) do |
@@ -107,6 +109,7 @@ local toFile = function(name, key, value) | |||
107 | h = io.open(name .. '.md', 'r') | 109 | h = io.open(name .. '.md', 'r') |
108 | if nil ~= h then | 110 | if nil ~= h then |
109 | -- print('Parsing ' .. name .. '.md') | 111 | -- print('Parsing ' .. name .. '.md') |
112 | Context = Files[name] | ||
110 | body = h:read('*a') ; h:close() | 113 | body = h:read('*a') ; h:close() |
111 | -- Deal with my typical double spaced sentence endings, and other things. | 114 | -- Deal with my typical double spaced sentence endings, and other things. |
112 | local result = RE.compile( [=[{~ | 115 | local result = RE.compile( [=[{~ |
@@ -123,8 +126,9 @@ local toFile = function(name, key, value) | |||
123 | {"[" {([^]])+} "]{style='color: " {([^}])+} "}" } -> "<span style='color: %3;'>%2</span>" / | 126 | {"[" {([^]])+} "]{style='color: " {([^}])+} "}" } -> "<span style='color: %3;'>%2</span>" / |
124 | {"{#"[A-Za-z_]+"}"} -> '' / | 127 | {"{#"[A-Za-z_]+"}"} -> '' / |
125 | {"### [[edit](/bin/edit/Main/" {([^%nl])+} } -> '' / | 128 | {"### [[edit](/bin/edit/Main/" {([^%nl])+} } -> '' / |
129 | {"#"+ " " {([^%nl])+} } -> header / | ||
126 | . | 130 | . |
127 | )* ~}]=], { } ):match(body) | 131 | )* ~}]=], { header = function(a) table.insert(Context.headers, a); return a end } ):match(body) |
128 | body = result | 132 | body = result |
129 | -- {"<!--".*"-->"} -> '' / | 133 | -- {"<!--".*"-->"} -> '' / |
130 | -- {"[$]"} -> '$dlr$' / -- Replace $, coz otherwise it confuses things later. | 134 | -- {"[$]"} -> '$dlr$' / -- Replace $, coz otherwise it confuses things later. |
@@ -211,27 +215,51 @@ else | |||
211 | print("Can't open everything.md for writing.") | 215 | print("Can't open everything.md for writing.") |
212 | end | 216 | end |
213 | 217 | ||
214 | -- Scan the subdirectories looking for our files. | 218 | -- Scan the sub folders looking for our files. |
215 | local Directory = arg[1] | 219 | local Folder = arg[1] |
216 | toSub('') | 220 | toSub('') |
217 | if nil == Directory then Directory = '.' end | 221 | if nil == Folder then Folder = '.' end |
218 | 222 | --GlobalMetaData.root = Folder | |
219 | -- Sort out realURL for symlinked .md.md files. | 223 | |
220 | for l in io.popen('find -L ' .. Directory .. ' -name unsorted -prune -o -name "*.md.md" -xtype l -printf "%P\n"'):lines() do | 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 | ]] | ||
235 | for l in io.popen('find -L ' .. Folder .. ' -name unsorted -prune -o -name "*.md.md" -xtype l -printf "%P\n"'):lines() do | ||
221 | local metadata = readMdMd(string.sub(l, 1, -4), {}) | 236 | local metadata = readMdMd(string.sub(l, 1, -4), {}) |
222 | -- FIXME - if this already exists, compare the timestamps, most recent wins. | 237 | if nil == metadata.realURL then |
223 | metadata.realURL = string.sub(l, 1, -7) | 238 | metadata.realURL = string.sub(l, 1, -7) |
224 | local a, e = io.open(l, 'w') | 239 | else |
225 | if nil == a then print('Could not open ' .. l .. ' - ' .. e) else | 240 | if metadata.realURL ~= string.sub(l, 1, -7) then |
226 | for k, v in pairs(metadata) do | 241 | metadata.realURL = string.sub(l, 1, -7) |
227 | a:write(k .. '=' .. v .. '\n') | 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() | ||
228 | end | 257 | end |
229 | a:close() | ||
230 | end | 258 | end |
231 | end | 259 | end |
232 | 260 | ||
233 | -- Clean up unsorted. | 261 | -- Clean up unsorted. |
234 | for l in io.popen('find -L ' .. Directory .. ' -name unsorted -prune -o -name "*.md" -a -not -name "*.md.md" -xtype l -printf "%P\n"'):lines() do | 262 | for 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 |
235 | local tp = '_fos' | 263 | local tp = '_fos' |
236 | local metadata = readMdMd(l, {}) | 264 | local metadata = readMdMd(l, {}) |
237 | if nil ~= metadata then | 265 | if nil ~= metadata then |
@@ -241,35 +269,62 @@ for l in io.popen('find -L ' .. Directory .. ' -name unsorted -prune -o -name "* | |||
241 | local a, e = io.open(unsort .. tp .. '.md' , 'r') | 269 | local a, e = io.open(unsort .. tp .. '.md' , 'r') |
242 | if nil ~= a then | 270 | if nil ~= a then |
243 | a:close() | 271 | a:close() |
244 | os.execute('rm ' .. unsort .. tp .. '.*') | 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 | |||
245 | end | 294 | end |
246 | end | 295 | end |
247 | end | 296 | end |
248 | end | 297 | end |
249 | 298 | ||
250 | -- Look for copied pages from the other wikis. | 299 | -- Look for copied pages from the other wikis. |
251 | for l in io.popen('find -L ' .. Directory .. ' -name "*.HTM" -type f,l -printf "%P\n"'):lines() do | 300 | for l in io.popen('find -L ' .. Folder .. ' -name "*.HTM" -type f,l -printf "%P\n"'):lines() do |
252 | -- print('pandoc converting ' .. l .. ' -> ' .. string.sub(l, 1, -4) .. 'md') | 301 | -- Only do this if .HTM is newer than .md, or .md doesn't exist. |
253 | -- Open the HTM files and do the initial cleanups, then pandoc them. | 302 | local htime = io.popen("date -ur " .. l .. " +%s"):read('l') |
254 | h = io.open(l, 'r') | 303 | local mtime = io.popen("date -ur " .. string.sub(l, 1, -4) .. "md +%s 2>/dev/null"):read('l') |
255 | if nil ~= h then | 304 | if (nil == mtime) or (htime > mtime) then |
256 | local body = h:read('*a') ; h:close() | 305 | print('pandoc converting ' .. l .. ' -> ' .. string.sub(l, 1, -4) .. 'md') |
257 | if 'Foswiki' == string.sub(l, 1, 7) then | 306 | os.execute('cp ' .. l .. ' ' .. l .. '_ORIGINAL0') |
258 | -- Strip out the actual content. | 307 | -- Open the HTM files and do the initial cleanups, then pandoc them. |
259 | local beg, en = RE.find(body, [['<div id="patternMainContents">']]) if nil ~= beg then body = string.sub(body, en + 1) end | 308 | h = io.open(l, 'r') |
260 | beg, en = RE.find(body, [['<div class="patternContent">']]) if nil ~= beg then body = string.sub(body, en + 1) end | 309 | if nil ~= h then |
261 | beg, en = RE.find(body, [['<div class="foswikiTopic">']]) if nil ~= beg then | 310 | local body = h:read('*a') ; h:close() |
262 | if ' -- ' == string.sub(body, en + 1, en + 4) then | 311 | writeString(l .. '_ORIGINAL1', body) |
263 | beg, en = RE.find(body, '[%nl]', en + 4) | 312 | if 'Foswiki' == string.sub(l, 1, 7) then |
264 | body = string.sub(body, en + 1) | 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 | ||
265 | end | 321 | end |
266 | end | 322 | beg, en = RE.find(body, [['<div class="patternInfo">']]) if nil ~= beg then body = string.sub(body, 1, beg - 1) end |
267 | 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 |
268 | -- 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 |
269 | 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 |
270 | beg, en = RE.find(body, [['<div class="foswikiSearchResultsPager">']]) if nil ~= beg then body = string.sub(body, 1, beg - 1) end | 326 | -- Some clean ups. |
271 | -- Some clean ups. | 327 | local result = RE.compile( [[{~ |
272 | local result = RE.compile( [[{~ | ||
273 | ( | 328 | ( |
274 | {'class="foswikiCurrentTopicLink"'} -> blank / | 329 | {'class="foswikiCurrentTopicLink"'} -> blank / |
275 | {'class="foswikiNewLink"'} -> blank / | 330 | {'class="foswikiNewLink"'} -> blank / |
@@ -283,41 +338,58 @@ for l in io.popen('find -L ' .. Directory .. ' -name "*.HTM" -type f,l -printf " | |||
283 | -- {'style="' ([^"])+ '"'} -> blank / {"style='" ([^'])+ "'"} -> blank / | 338 | -- {'style="' ([^"])+ '"'} -> blank / {"style='" ([^'])+ "'"} -> blank / |
284 | . | 339 | . |
285 | )* ~}]], { blank = function(a) return '' end } ):match(body) | 340 | )* ~}]], { blank = function(a) return '' end } ):match(body) |
286 | body = result | 341 | body = result |
287 | -- body = RE.gsub(body, [=[{"<!-- ".*"-->"}]=], '') -- FIXME | 342 | -- body = RE.gsub(body, [=[{"<!-- ".*"-->"}]=], '') -- FIXME |
288 | local here = 1 | 343 | local here = 1 |
289 | beg, en = RE.find(body, [['https://fos.wiki.devuan.org/']], here) | 344 | beg, en = RE.find(body, [['https://fos.wiki.devuan.org/']], here) |
290 | while nil ~= beg do | 345 | while nil ~= beg do |
291 | here = beg + 1 | 346 | here = beg + 1 |
292 | local beg0, en0 | 347 | local beg0, en0 |
293 | local url = nil | 348 | local url = nil |
294 | if '"' == string.sub(body, beg - 1, beg - 1) then | 349 | if '"' == string.sub(body, beg - 1, beg - 1) then |
295 | beg0, en0 = RE.find(body, [['"']], en) | 350 | beg0, en0 = RE.find(body, [['"']], en) |
296 | url = string.sub(body, en + 1, en0 - 1) | 351 | url = string.sub(body, en + 1, en0 - 1) |
297 | end | 352 | end |
298 | if "'" == string.sub(body, beg - 1, beg - 1) then | 353 | if "'" == string.sub(body, beg - 1, beg - 1) then |
299 | beg0, en0 = RE.find(body, [["'"]], en) | 354 | beg0, en0 = RE.find(body, [["'"]], en) |
300 | url = string.sub(body, en + 1, en0) | 355 | url = string.sub(body, en + 1, en0) |
301 | end | 356 | end |
302 | 357 | ||
303 | if nil ~= url then | 358 | if nil ~= url then |
304 | if ('pub/' == string.sub(url, 1, 4)) then | 359 | if ('pub/' == string.sub(url, 1, 4)) then |
305 | -- FIXME? - evil hack? | 360 | -- FIXME? - evil hack? |
306 | url = 'Foswiki/' .. url | 361 | url = 'Foswiki/' .. url |
307 | else | 362 | --print('FOSWIKI HTM ' .. url) |
308 | url = nil | 363 | else |
364 | url = nil | ||
365 | end | ||
309 | 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 | ]=] | ||
310 | end | 384 | end |
311 | beg, en, body, here = commonLinky(l, body, 'https://fos.wiki.devuan.org/', url, beg, en, beg0, en0, 1) | ||
312 | end | ||
313 | 385 | ||
314 | writeString(l .. '_NEW', body) | 386 | writeString(l .. '_NEW', body) |
315 | elseif 'PmWiki' == string.sub(l, 1, 6) then | 387 | elseif 'PmWiki' == string.sub(l, 1, 6) then |
316 | local beg, en = RE.find(body, [['<!--PageText-->']]) if nil ~= beg then body = string.sub(body, en + 2) end | 388 | local beg, en = RE.find(body, [['<!--PageText-->']]) if nil ~= beg then body = string.sub(body, en + 2) end |
317 | beg, en = RE.find(body, [["div id='wikitext'>"]]) 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 |
318 | 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. | 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. |
319 | beg, en = RE.find(body, [['<!--HTMLFooter-->']]) if nil ~= beg then body = string.sub(body, 1, beg - 2) end | 391 | beg, en = RE.find(body, [['<!--HTMLFooter-->']]) if nil ~= beg then body = string.sub(body, 1, beg - 2) end |
320 | local result = RE.compile( [[{~ | 392 | local result = RE.compile( [[{~ |
321 | ( | 393 | ( |
322 | {"class='categorylink'"} -> blank / | 394 | {"class='categorylink'"} -> blank / |
323 | {"class='createlink'"} -> blank / | 395 | {"class='createlink'"} -> blank / |
@@ -337,41 +409,53 @@ for l in io.popen('find -L ' .. Directory .. ' -name "*.HTM" -type f,l -printf " | |||
337 | {"<span class='hlt " {([a-z])+} "'></span><pre" } -> "<pre class='%2'" / | 409 | {"<span class='hlt " {([a-z])+} "'></span><pre" } -> "<pre class='%2'" / |
338 | . | 410 | . |
339 | )* ~}]], { blank = function(a) return '' end } ):match(body) | 411 | )* ~}]], { blank = function(a) return '' end } ):match(body) |
340 | body = result | 412 | body = result |
341 | here = 1 | 413 | -- body = RE.gsub(body, [=["<a " {([^ >])+} " >"]=], "<a %1>") |
342 | beg, en = RE.find(body, [["'https://wiki.devuan.org/"]], here) | 414 | -- DONE? - <span class='hlt html'></span><pre style='background-color: #cc00ff;' class='escaped'> ... lines of HTML code ... </pre> |
343 | while nil ~= beg do | 415 | -- most of the time I'll see <pre class='escaped'> |
344 | here = beg + 1 | 416 | -- My own looking glass has several. |
345 | local beg0, en0 = RE.find(body, [["'"]], en) | 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) | ||
346 | -- FIXME? - This might be working around a bug elsewhere. | 427 | -- FIXME? - This might be working around a bug elsewhere. |
347 | if "'" == string.sub(body, en0, en0) then en0 = en0 - 1 end | 428 | if "'" == string.sub(body, en0, en0) then en0 = en0 - 1 end |
348 | local url = string.sub(body, en + 1, en0) | 429 | local url = string.sub(body, en + 1, en0) |
349 | if '?n=' == string.sub(url, 1, 3) then | 430 | if '?n=' == string.sub(url, 1, 3) then |
350 | url = string.sub(url, 4):gsub('[%a]+%.([%a-]+)', '%1_pm.HTML') | 431 | url = string.sub(url, 4):gsub('[%a]+%.([%a-]+)', '%1_pm.HTML') |
351 | elseif ("'" == url) or ('uploads/' == string.sub(url, 1, 8)) then | 432 | elseif ("'" == url) or ('uploads/' == string.sub(url, 1, 8)) then |
352 | -- FIXME - evil hack? Yep, evil hack, need to know the depth of the source, which isn't here. | 433 | -- FIXME - evil hack? Yep, evil hack, need to know the depth of the source, which isn't here. |
353 | url = 'PmWiki/' .. url | 434 | url = 'PmWiki/' .. url |
354 | else | 435 | else |
355 | url = nil | 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 | ||
356 | end | 441 | end |
357 | beg, en, body, here = commonLinky(l, body, "'https://wiki.devuan.org/", url, beg, en, beg0, en0, 0) | ||
358 | end | ||
359 | 442 | ||
360 | writeString(l .. '_NEW', body) | 443 | writeString(l .. '_NEW', body) |
444 | end | ||
361 | end | 445 | end |
362 | end | ||
363 | 446 | ||
364 | ok, rslt, status = os.execute('pandoc --wrap=preserve -f html -t commonmark_x --self-contained ' .. l .. '_NEW' .. ' >' .. string.sub(l, 1, -4) .. 'md') | 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 | ||
365 | end | 449 | end |
366 | 450 | ||
367 | if '.' ~= Directory then | 451 | if '.' ~= Folder then |
368 | for l in io.popen('find -L . -name "*.md" -type f,l -printf "%P\n"'):lines() do | 452 | for l in io.popen('find -L . -name "*.md" -type f,l -printf "%P\n"'):lines() do |
369 | toFile(string.gsub(l, '%.md$', '')) | 453 | toFile(string.gsub(l, '%.md$', '')) |
370 | end | 454 | end |
371 | end | 455 | end |
372 | 456 | ||
373 | -- Can add in a distant directory to, for putting it's results in the current directory. | 457 | -- Can add in a distant folder to, for putting it's results in the current folder. |
374 | for l in io.popen('find -L ' .. Directory .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do | 458 | for l in io.popen('find -L ' .. Folder .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do |
375 | local n = string.gsub(l, '%.md$', '') | 459 | local n = string.gsub(l, '%.md$', '') |
376 | if nil == Files[n] then toFile(n) end | 460 | if nil == Files[n] then toFile(n) end |
377 | end | 461 | end |
@@ -426,12 +510,25 @@ for name, file in pairs(Files) do | |||
426 | end | 510 | end |
427 | end | 511 | end |
428 | 512 | ||
513 | -- Find empty subs. | ||
514 | for 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 | ||
525 | end | ||
429 | 526 | ||
430 | 527 | ||
431 | --------------------------------------------------------------------------------- | 528 | --------------------------------------------------------------------------------- |
432 | -- These functions assume the above file and sub scan has completed. | 529 | -- These functions assume the above file and sub scan has completed. |
433 | 530 | ||
434 | -- Which page in this directory should we show? | 531 | -- Which page in this folder should we show? |
435 | -- NOTE - only looking for the .md files we scanned for before, any stray HTML, html, HTM, and 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. |
436 | local whichPage = function(f) | 533 | local whichPage = function(f) |
437 | local fl = '' | 534 | local fl = '' |
@@ -474,7 +571,7 @@ local whichWiki = function(metadata) | |||
474 | end | 571 | end |
475 | 572 | ||
476 | 573 | ||
477 | -- Calculate a link from the source directory to the destination directory. | 574 | -- Calculate a link from the source folder to the destination folder. |
478 | local linkFrom = function(source, dest) | 575 | local linkFrom = function(source, dest) |
479 | -- Evil hacks! | 576 | -- Evil hacks! |
480 | if 'Profiles' == dest then dest = 'PmWiki/Profiles' end | 577 | if 'Profiles' == dest then dest = 'PmWiki/Profiles' end |
@@ -527,7 +624,7 @@ end | |||
527 | -- More of this actually doing things nonsense. | 624 | -- More of this actually doing things nonsense. |
528 | 625 | ||
529 | -- Create an "everything" page, for URL links to every file.HTML. | 626 | -- Create an "everything" page, for URL links to every file.HTML. |
530 | local Bdy = '# All the pages\n\n| page | converted | original page | last edited UTC | \n| ---- | --------- | ------- | --------------- | ' | 627 | local Bdy = '# All the pages\n\n| page | original page | last edited UTC | \n| --------- | ------- | --------------- | ' |
531 | Pages = {} | 628 | Pages = {} |
532 | for name, file in pairs(Files) do | 629 | for name, file in pairs(Files) do |
533 | local metadata = derefTable(Files[name].metadata, true) | 630 | local metadata = derefTable(Files[name].metadata, true) |
@@ -540,7 +637,7 @@ for name, file in pairs(Files) do | |||
540 | if nil ~= metadata.timestamp then ts = metadata.timestamp end | 637 | if nil ~= metadata.timestamp then ts = metadata.timestamp end |
541 | if nil ~= file.bit then ln = file.bit | 638 | if nil ~= file.bit then ln = file.bit |
542 | end | 639 | end |
543 | table.insert(Pages, '\n| ' .. name .. ' | [' .. ln .. '](<' .. name .. '.HTML>) | ' .. fw .. ' ' .. pw .. ' | ' .. ts .. ' |') | 640 | table.insert(Pages, '\n| [' .. name .. '](<' .. name .. '.HTML>) | ' .. fw .. ' ' .. pw .. ' | ' .. ts .. ' |') |
544 | 641 | ||
545 | -- Track our external links. | 642 | -- Track our external links. |
546 | if (nil ~= metadata.ogBase) and (nil ~= metadata.ogFile) then | 643 | if (nil ~= metadata.ogBase) and (nil ~= metadata.ogFile) then |
@@ -646,7 +743,6 @@ local LunamarkOpts = { | |||
646 | } | 743 | } |
647 | local Writer = Lunamark.writer.html5.new(LunamarkOpts) | 744 | local Writer = Lunamark.writer.html5.new(LunamarkOpts) |
648 | -- Can override the various writer functions, there's something for each of the basic HTML elements. | 745 | -- Can override the various writer functions, there's something for each of the basic HTML elements. |
649 | local Context = {} -- Coz can't otherwise pass context through to the deeper Lunamark functions I'm overriding. | ||
650 | local lunaLinky = function(url) -- Fix up the links. | 746 | local lunaLinky = function(url) -- Fix up the links. |
651 | if ('https://wiki.devuan.org/' ~= url) and ('https://fos.wiki.devuan.org/' ~= url) then | 747 | if ('https://wiki.devuan.org/' ~= url) and ('https://fos.wiki.devuan.org/' ~= url) then |
652 | -- TODO - This might be covering up a bug elsewhere. | 748 | -- TODO - This might be covering up a bug elsewhere. |
@@ -694,9 +790,9 @@ local lunaLinky = function(url) -- Fix up the links. | |||
694 | url = xlnk .. string.gsub(ur, '.*%.', '', 1) | 790 | url = xlnk .. string.gsub(ur, '.*%.', '', 1) |
695 | -- end | 791 | -- end |
696 | if 'PmWiki/uploads/' == p then | 792 | if 'PmWiki/uploads/' == p then |
697 | url = '../' .. p .. string.gsub(ur, '%.', '.', 1) | 793 | url = '../../' .. p .. string.gsub(ur, '%.', '.', 1) |
698 | elseif 'Foswiki/pub/' == p then | 794 | elseif 'Foswiki/pub/' == p then |
699 | url = '../' .. p .. ur | 795 | url = '../../' .. p .. ur |
700 | else | 796 | else |
701 | url = url .. '.HTML' | 797 | url = url .. '.HTML' |
702 | end | 798 | end |
@@ -707,6 +803,12 @@ local lunaLinky = function(url) -- Fix up the links. | |||
707 | return url | 803 | return url |
708 | end | 804 | end |
709 | 805 | ||
806 | function Writer.header(s, level) | ||
807 | local text = Lunamark.util.rope_to_string(s) | ||
808 | -- FIXME - Work around a bug in Lunamark? | ||
809 | text = RE.gsub(text, "{[\\]}", "") | ||
810 | return '<h' .. level .. ' id="' .. RE.gsub(text, '{[ ]}', '_') .. '">' .. text .. ' <a style="font-size: 0.42em;" href="#top">🔼</a></h' .. level .. '>' | ||
811 | end | ||
710 | local OgWriterLink = Writer.link -- So we can call the original from within mine, we are just changing the URL. | 812 | local OgWriterLink = Writer.link -- So we can call the original from within mine, we are just changing the URL. |
711 | function Writer.link(lab, url, tit) | 813 | function Writer.link(lab, url, tit) |
712 | return OgWriterLink(lab, lunaLinky(url), tit) | 814 | return OgWriterLink(lab, lunaLinky(url), tit) |
@@ -752,7 +854,7 @@ for name, file in pairs(Files) do | |||
752 | local pth = file.path | 854 | local pth = file.path |
753 | if '' ~= file.path then pth = file.path .. '/' end | 855 | if '' ~= file.path then pth = file.path .. '/' end |
754 | if 'true' ~= Subs[pth .. f].metadata.hidden then | 856 | if 'true' ~= Subs[pth .. f].metadata.hidden then |
755 | metadata.header = metadata.header .. '<a href="' .. f .. '/' .. whichPage(pth .. f) .. '">' .. f .. '</a> ' | 857 | metadata.header = metadata.header .. '<a href="' .. f .. '/' .. whichPage(pth .. f) .. '">' .. f .. '</a> 📂 ' |
756 | end | 858 | end |
757 | end | 859 | end |
758 | 860 | ||
@@ -770,29 +872,62 @@ for name, file in pairs(Files) do | |||
770 | url = Files[file.path .. '/' .. f].metadata.URL | 872 | url = Files[file.path .. '/' .. f].metadata.URL |
771 | end | 873 | end |
772 | if nil == title then title = f end | 874 | if nil == title then title = f end |
773 | if bit == f then metadata.menu = metadata.menu .. '<p>' .. title .. '</p>' | 875 | if bit == f then |
876 | metadata.menu = metadata.menu .. '<p>' .. title .. '</p>' | ||
877 | for j, g in ipairs(file.headers) do | ||
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, '{[ ]}', ' ') | ||
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(' ', l) .. '<a style="font-size: 0.80em;" href="#' .. RE.gsub(g, '{[ ]}', '_') .. '">' .. h .. '</a></p>' | ||
891 | end | ||
774 | else | 892 | else |
775 | if nil ~= url then metadata.menu = metadata.menu .. '<p><a href="' .. url .. '">' .. title .. ' ☝</a></p>' | 893 | if nil ~= url then metadata.menu = metadata.menu .. '<p><a href="' .. url .. '">' .. title .. ' ☝</a></p>' |
776 | else metadata.menu = metadata.menu .. '<p><a href="' .. f .. '.HTML">' .. title .. '</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 | ||
777 | end | 903 | end |
778 | end | 904 | end |
779 | end | 905 | end |
780 | 906 | ||
781 | -- Figure out this pages footer links. | 907 | -- Figure out this pages footer links. |
908 | local temp = '' | ||
782 | metadata.footer = '' | 909 | metadata.footer = '' |
783 | if nil ~= metadata.pagehistory then metadata.history = '<p>Page <a href="' .. metadata.pagehistory .. '/' .. name .. '.md">history</a></p>' else metadata.history = '' end | 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 | ||
913 | else | ||
914 | temp = '/' .. name .. '.md' | ||
915 | end | ||
916 | if nil ~= metadata.pagehistory then metadata.history = '<p>Page <a href="' .. metadata.pagehistory .. temp .. '">history</a></p>' else | ||
917 | metadata.history = '' | ||
918 | end | ||
784 | if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a>' end | 919 | if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a>' end |
785 | if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed</a> ' .. metadata.footer end | 920 | if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed<img src="feed-icon-14x14.png"></img></a> ' .. metadata.footer end |
786 | if metadata.footer ~= '' then metadata.footer = 'Web site ' .. metadata.footer end | 921 | if metadata.footer ~= '' then metadata.footer = 'Web site ' .. metadata.footer end |
787 | -- Add a link to the original page. | 922 | -- Add a link to the original page. |
788 | if nil ~= metadata.ogURL then | 923 | if nil ~= metadata.ogURL then |
789 | local title, link = whichWiki(metadata) | 924 | local title, link = whichWiki(metadata) |
790 | link = string.gsub(link, 'https://', 'HTTPS://') -- Prevent this one from being converted. | 925 | link = string.gsub(link, 'https://', 'HTTPS://') -- Prevent this one from being converted. |
791 | -- 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? | 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? |
792 | local edit = 'edit' | 927 | local edit = 'T' |
793 | if 'PmWiki' == metadata.ogWiki then edit = '<a href="' .. link .. '?action=edit">edit</a>' end | 928 | if 'PmWiki' == metadata.ogWiki then edit = 'Maybe you can <a href="' .. link .. '?action=edit">edit</a> t' end |
794 | -- if 'Foswiki' == metadata.ogWiki then edit = 'edit' end | 929 | -- if 'Foswiki' == metadata.ogWiki then edit = '' end |
795 | metadata.footer = '<a href="' .. link .. '">Original page</a>, maybe you can ' .. edit .. ' it. ' .. metadata.footer | 930 | metadata.footer = edit .. 'he <a href="' .. link .. '">original page</a>. ' .. metadata.footer |
796 | end | 931 | end |
797 | metadata.footer = '<p>' .. metadata.footer .. '</p>' | 932 | metadata.footer = '<p>' .. metadata.footer .. '</p>' |
798 | 933 | ||
@@ -801,6 +936,7 @@ for name, file in pairs(Files) do | |||
801 | -- Toss the body in first, so the scan can deal with it to. | 936 | -- Toss the body in first, so the scan can deal with it to. |
802 | -- NOTE - this is where we actually parse the markup into HTML. | 937 | -- NOTE - this is where we actually parse the markup into HTML. |
803 | Context = file | 938 | Context = file |
939 | body = RE.gsub(body, '{[%nl]^1[%a]+}[.]^1 ', '%1$dot$ ') -- Coz otherwise stray . trip up the list detection. | ||
804 | 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. | 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. |
805 | bd = RE.gsub(bd, '{[%]}', '$perc$') -- Coz otherwise stray % trip up the capture part. | 941 | bd = RE.gsub(bd, '{[%]}', '$perc$') -- Coz otherwise stray % trip up the capture part. |
806 | temp = RE.gsub(temp, '"$body$"', bd) | 942 | temp = RE.gsub(temp, '"$body$"', bd) |