From d0800b74d4835cb94d84d665938e39788a9f5e7d Mon Sep 17 00:00:00 2001 From: dvs1 Date: Wed, 1 Jan 2025 19:04:47 +1000 Subject: not Yet Another reWrite plus TODO-- Fixed up most of the linking stuff, and got the favicon / logo inheritance working. --- TODO.md | 4 - notYetAnotherWiki.lua | 387 ++++++++++++++++++++++++++++---------------------- 2 files changed, 214 insertions(+), 177 deletions(-) diff --git a/TODO.md b/TODO.md index 1a87d89..2e2b14f 100644 --- a/TODO.md +++ b/TODO.md @@ -5,10 +5,6 @@ pagehistory: https://sledjhamr.org/cgit/notYetAnotherWiki/log/TODO.md --- ## Do these -Clean up the favicon and logo stuff. - Have one in a root directory that the pages in sub directories point to, instead of the current symlinks. - Apply the same solution to default.template. - Clean up docs and bump to version 0.0. RELEASE!!!????!!!!???? See the conversion therapy section below. diff --git a/notYetAnotherWiki.lua b/notYetAnotherWiki.lua index 2faf285..1343739 100755 --- a/notYetAnotherWiki.lua +++ b/notYetAnotherWiki.lua @@ -6,223 +6,264 @@ local lcmark = require("lcmark") local globalData = { ['_'] = ' ', ['dlr'] = '$', ['karenpurple'] = '#8800ff', - favicon = 'nYAW_icon.png', logo = 'nYAW.png', header = '', menu = '', + favicon = 'nYAW_icon.png', logo = 'nYAW.png', header = '', --menu = '', history = '', footer = 'Powered by notYetAnotherWiki Version -0.1.  ', } -local sites = {} +local Sites, Files, Subs = {}, {}, {} - -local directory = arg[1] -if nil == directory then directory = '.' end -local all = {} -if '.' ~= directory then - for l in io.popen('find . -name "*.md" -type f,l -printf "%P\n"'):lines() do - all[l] = l +local copyTable = function(t, strip) + -- A simple table.subtable = subtable wont work, you end up with a reference so that changes to the later get applaid to the former. + local argh = {} + for l, y in ipairs(t) do + if (l ~= y.name) and strip then table.insert(argh, y) end end -end -for l in io.popen('find ' .. directory .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do - if nil == all[l] then all[l] = l end + return argh end -for i, l in pairs(all) do - local dir, file, parent, path = '', '', '', '', '' +local stringBits = function(l) local bits = {} local last = 1 for j = 1, #l do - local c = string.sub(l, j, j) - if '/' == c then + if '/' == string.sub(l, j, j) then table.insert(bits, string.sub(l, last, j - 1)) last = j + 1 end end - file = string.sub(l, last) - file = string.gsub(file, '%.md$', '') + return bits, string.sub(l, last) +end + - local ln = #bits - if 0 < ln then - dir = bits[ln] - path = table.concat(bits, '/', 1, ln) - if 1 < ln then parent = table.concat(bits, '/', 1, ln - 1) end - end - local files = {name = file, URL = '

' .. file .. '

', } - if nil == sites[path] then sites[path] = {files = {files}} - elseif nil == sites[path].files then sites[path].files = {files} - else table.insert(sites[path].files, files) +local directory = arg[1] +if nil == directory then directory = '.' end +if '.' ~= directory then + for l in io.popen('find . -name "*.md" -type f,l -printf "%P\n"'):lines() do + Files[string.gsub(l, '%.md$', '')] = {} end +end +for l in io.popen('find ' .. directory .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do + local n = string.gsub(l, '%.md$', '') + if nil == Files[n] then Files[n] = {} end +end - if '' ~= dir then --- FIXME - not sure why this is needed anymore, but it fails building subs without it. Just slows things down otherwise. - files = {name = dir, URL = '' .. dir .. '   ', } - if nil == sites[parent] then sites[parent] = {subs = {[files.name] = files}} - elseif nil == sites[parent].subs then sites[parent].subs = {[files.name] = files} - else sites[parent].subs[files.name] = files - end +-- Gotta figure out all the files and subs first. File and sub metadata comes along for the ride. +Subs[''] = {files = {}, subs = {}, bits = {}} +for name, file in pairs(Files) do + local bitter, path = '', '' + local bits, bit = stringBits(name) + local ln = #bits + + Files[name].bits = bits + Files[name].bit = bit + if ln > 0 then bitter = bits[1] end + if '' ~= bitter then Subs[''].subs[bitter] = bitter end -- "bitter end" was entirely by accident, I'm keeping it. B-) + for i, d in ipairs(bits) do + if '' ~= path then path = path .. '/' end + path = path .. d + if nil == Subs[path] then Subs[path] = {files = {}, subs = {}} end + if i < ln then Subs[path].subs[bits[i + 1]] = bits[i + 1] end + Subs[path].bits = copyTable(bits, true) + if i < ln then table.remove(Subs[path].bits, #bits) end end + print('Parsing ' .. name .. '.md') + local h = io.open(name .. '.md', 'r') +-- TODO - should bail here on error? + if nil ~= h then file.cm = h:read('*a') ; h:close() else print('oops! No such name ' .. name) end + local body, metadata, err = lcmark.convert(file.cm, "html", {smart = true, yaml_metadata = true, columns = 0}) + if nil == body then print('oops! ' .. err) + elseif '' == body then + Subs[path].metadata = metadata + Files[name] = nil + else + file.metadata = metadata + file.body = body + table.insert(Subs[path].files, bit) + end end -for k, v in pairs(sites) do - local bit, dir, file, parent, path = '', '', '', '', '' - local bits = {} - local last = 1 - for j = 1, #k do - local c = string.sub(k, j, j) - if '/' == c then - table.insert(bits, string.sub(k, last, j - 1)) - last = j + 1 + + +-- These functions assume the above file and sub scan has completed. +local whichPage = function(f) + local fl = '' + if (nil ~= Subs[f]) then + if 1 == #(Subs[f].files) then fl = Subs[f].files[1] .. '.HTML' else + for i, v in ipairs{'README', 'readme', 'INDEX', 'index'} do + for j, w in ipairs(Subs[f].files) do + if v == w then + print('FOUND ' .. v .. '.HTML') + fl = v .. '.HTML' + break + end + end + if '' ~= fl then break end + end end end - sites[k].parent = table.concat(bits, '/') - table.insert(bits, string.sub(k, last)) - sites[k].bits = bits - if nil ~= sites[k].files then table.sort(sites[k].files, function(a, b) return (a.name <= b.name) end) end - - dir = bits[#bits - 1] - file = bits[#bits] - if nil ~= sites[dir] then - if nil == sites[dir].subs then sites[dir].subs = {} end - last = nil - for j, g in pairs(sites[dir].subs) do - if (g.name == dir) or (g.name == file) then - last = j + return fl +end + + +local linkFrom = function(source, dest) + local depth = 0 + local link = '' + if source ~= dest then + for i, v in ipairs(Subs[source].bits) do + if v ~= Subs[dest].bits[i] then + depth = i break end end - if nil == last then - sites[dir].subs[file] = {name = file, URL = '' .. file .. '   '} - end - end - - bits = {} - if nil ~= v.subs then - for l, w in pairs(v.subs) do - table.insert(bits, w) + depth = #(Subs[source].bits) - depth + depth = depth + 1 + link = string.rep('../', depth) + if (0 == depth) or (depth > #(Subs[dest].bits)) then + for i, v in ipairs(Subs[dest].bits) do + if i >= depth then + if '' ~= link then link = link .. '/' end + link = link .. Subs[dest].bits[i] + end + end end - table.sort(bits, function(a, b) return (a.name <= b.name) end) - v.subs = bits end + return link end -for k, v in pairs(sites) do - if nil ~= v.files then - for l, w in pairs(v.files) do - local path = v.parent - if '' ~= path then path = path .. '/' end - path = path .. v.bits[#(v.bits)] - if '' ~= path then path = path .. '/' end - local file = path .. w.name .. '.md' - if (nil ~= file) and ('' ~= file) then io.write('Parsing ' .. file .. ' -> ') end +for name, file in pairs(Files) do + local path, result = '', '' + local body, metadata = Files[name].body, Files[name].metadata + local bits, bit = Files[name].bits, Files[name].bit + local ln = #bits - local h = io.open(file, 'r') - if nil ~= h then - local cm = h:read('*a') - local result = '' - local body, metadata, err = lcmark.convert(cm, "html", {smart = true, yaml_metadata = true, columns = 0}) - - if nil == body then print('oops! ' .. err) else - - - if '' == body then - -- A simple v.metadata = metadata wont work, you end up with a reference so that changes to metadata get applied to v.metadata. - v.metadata = {} - for l, y in pairs(metadata) do - v.metadata[l] = y - end - local argh = {} - for l, y in ipairs(v.files) do - if w.name ~= y.name then table.insert(argh, y) end - end - v.files = argh - print('') - else - - local bod, err = lcmark.compile_template(body) - if nil == bod then print('oops! ' .. err) else - local templateFile = metadata.template - if nil == file then - templateFile = nil - else - if nil == templateFile then templateFile = 'default' end - templateFile = templateFile .. '.template' - for m, x in pairs(globalData) do if nil == metadata[m] then metadata[m] = x else print('metadata already has ' .. m) end end - if nil ~= v.metadata then - for m, x in pairs(v.metadata) do if nil == metadata[m] then metadata[m] = x else print('metadata already has ' .. m) end end - end - end - - if nil ~= v.files then - for m, x in ipairs(v.files) do - metadata.menu = metadata.menu .. x.URL .. '\n' - end - end - if nil ~= v.subs then - for m, x in pairs(v.subs) do - metadata.header = metadata.header .. x.URL - end - end - - local num = #(v.bits) - local trail = 'home   ' - local p = v.parent - for i = 1, num do - trail = trail .. '' .. v.bits[i] .. '   ' - end - trail = trail .. w.name - metadata.trail = trail - - if nil ~= metadata.pagehistory then metadata.history = '

Page history

' end - if nil ~= metadata.sourcecode then metadata.footer = 'source code     ' .. metadata.footer end - if nil ~= metadata.feedatom then metadata.footer = 'atom feed     ' .. metadata.footer end - if metadata.footer ~= globalData.footer then metadata.footer = 'Web site ' .. metadata.footer end - metadata.footer = '

' .. metadata.footer .. '

' - metadata.body = lcmark.apply_template(bod, metadata) - - local tm = '' - if nil ~= templateFile then - local h = io.open(templateFile, 'r') - if nil ~= h then - tm = tm .. h:read('*a') - h:close() - else - print('oops! No such file ' .. templateFile) - end - - local template, err = lcmark.compile_template(tm) - if nil == template then print('oops! ' .. err) else - result = lcmark.apply_template(template, metadata) - end - else - result = body - end - - if ('' ~= result) and (nil ~= file) then - local base = path .. w.name .. '.HTML' - print(base) - local a, e = io.open(base, 'w') - if nil == a then print('Could not open ' .. base .. ' - ' .. e) else - a:write(result) - a:close() - end - else - print('') - end - end + path = table.concat(bits, '/', 1, ln) + if '' ~= body then + local bod, err = lcmark.compile_template(body) + if nil == bod then print('oops! ' .. err) else + local templateFile = metadata.template + if nil == templateFile then templateFile = 'default' end + file.template = templateFile .. '.template' + end + + local pth = '' + for i, d in ipairs(bits) do + if '' ~= pth then pth = pth .. '/' end + pth = pth .. d + if nil ~= Subs[pth] then + if nil ~= Subs[pth].metadata then + for m, x in pairs(Subs[pth].metadata) do + if nil == metadata[m] then + metadata[m] = x + else end + end + end + end + end + + if nil ~= Subs[''].metadata then + for m, x in pairs(Subs[''].metadata) do if nil == metadata[m] then metadata[m] = x end end + end + for m, x in pairs(globalData) do if nil == metadata[m] then metadata[m] = x end end + for n, y in ipairs{'favicon', 'logo'} do + local pith = '' + if nil ~= metadata[y] then + local pth = '' + for m, x in ipairs(bits) do + if '' ~= pth then pth = pth .. '/' end + pth = pth .. x + if (nil ~= Subs[pth].metadata) and (nil ~= Subs[pth].metadata[y]) then pith = pth end + end + if ('' == pith) and (nil ~= Subs[''].metadata) and (nil ~= Subs[''].metadata[y]) then pith = pth end + if '' == pith then metadata[y] = linkFrom(path, pith) .. globalData[y] + else metadata[y] = linkFrom(path, pith) .. metadata[y] end + end + end + + metadata.header = '' + local pth = '' + for i, f in pairs(Subs[path].subs) do + local fl = '' + if '' ~= path then + if '' ~= pth then pth = pth .. '/' end + pth = pth .. f + fl = whichPage(pth) + else + fl = whichPage(f) + end + +-- if '' == fl then +-- metadata.header = metadata.header .. f .. '   ' +-- else + metadata.header = metadata.header .. '' .. f .. '   ' +-- end + end + + metadata.menu = '' + if nil ~= Subs[path].files then table.sort(Subs[path].files) end + for i, f in ipairs(Subs[path].files) do + if name == f then + metadata.menu = metadata.menu .. '

' .. f .. '

' + else + metadata.menu = metadata.menu .. '

' .. f .. '

' + end + end + + metadata.trail = '' + for i, b in ipairs(bits) do + if i < #bits then + metadata.trail = metadata.trail .. '' .. b .. '   ' + linkFrom(path, table.concat(bits, '/', 1, i)) + else + metadata.trail = metadata.trail .. b .. '   ' + end + end +-- if '' == metadata.trail then metadata.trail = 'home   ' end + if nil ~= metadata.pagehistory then metadata.history = '

Page history

' end + if nil ~= metadata.sourcecode then metadata.footer = 'source code     ' .. metadata.footer end + if nil ~= metadata.feedatom then metadata.footer = 'atom feed     ' .. metadata.footer end + if metadata.footer ~= globalData.footer then metadata.footer = 'Web site ' .. metadata.footer end + metadata.footer = '

' .. metadata.footer .. '

' + + metadata.body = lcmark.apply_template(bod, metadata) + + local tm = '' + if nil ~= file.template then + local h = io.open(file.template, 'r') + if nil ~= h then + tm = tm .. h:read('*a') h:close() else - print('oops! No such file ' .. file) + print('oops! No such file ' .. file.template) end + local template, err = lcmark.compile_template(tm) + if nil == template then print('oops! ' .. err) else + result = lcmark.apply_template(template, metadata) + end + else + result = body end - end + if '' ~= result then + local base = name .. '.HTML' + print('From ' .. name .. '.md -> ' .. base) + local a, e = io.open(base, 'w') + if nil == a then print('Could not open ' .. base .. ' - ' .. e) else + a:write(result) + a:close() + end + end + + else + print('') + end end -- cgit v1.1