diff options
author | dvs1 | 2025-01-01 19:04:47 +1000 |
---|---|---|
committer | dvs1 | 2025-01-01 19:04:47 +1000 |
commit | d0800b74d4835cb94d84d665938e39788a9f5e7d (patch) | |
tree | aa8330ba04af077f221dbb7e4e3a7765d9cdca3e | |
parent | Mostly fix up the footer. (diff) | |
download | notYetAnotherWiki-d0800b74d4835cb94d84d665938e39788a9f5e7d.zip notYetAnotherWiki-d0800b74d4835cb94d84d665938e39788a9f5e7d.tar.gz notYetAnotherWiki-d0800b74d4835cb94d84d665938e39788a9f5e7d.tar.bz2 notYetAnotherWiki-d0800b74d4835cb94d84d665938e39788a9f5e7d.tar.xz |
not Yet Another reWrite plus TODO--
Fixed up most of the linking stuff, and got the favicon / logo
inheritance working.
-rw-r--r-- | TODO.md | 4 | ||||
-rwxr-xr-x | notYetAnotherWiki.lua | 387 |
2 files changed, 214 insertions, 177 deletions
@@ -5,10 +5,6 @@ pagehistory: https://sledjhamr.org/cgit/notYetAnotherWiki/log/TODO.md | |||
5 | --- | 5 | --- |
6 | ## Do these | 6 | ## Do these |
7 | 7 | ||
8 | Clean up the favicon and logo stuff. | ||
9 | Have one in a root directory that the pages in sub directories point to, instead of the current symlinks. | ||
10 | Apply the same solution to default.template. | ||
11 | |||
12 | Clean up docs and bump to version 0.0. RELEASE!!!????!!!!???? | 8 | Clean up docs and bump to version 0.0. RELEASE!!!????!!!!???? |
13 | 9 | ||
14 | See the conversion therapy section below. | 10 | 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") | |||
6 | 6 | ||
7 | local globalData = { | 7 | local globalData = { |
8 | ['_'] = ' ', ['dlr'] = '$', ['karenpurple'] = '#8800ff', | 8 | ['_'] = ' ', ['dlr'] = '$', ['karenpurple'] = '#8800ff', |
9 | favicon = 'nYAW_icon.png', logo = 'nYAW.png', header = '', menu = '', | 9 | favicon = 'nYAW_icon.png', logo = 'nYAW.png', header = '', --menu = '', |
10 | history = '', footer = 'Powered by <a href="https://sledjhamr.org/cgit/notYetAnotherWiki/about/">notYetAnotherWiki</a> Version -0.1. ', | 10 | history = '', footer = 'Powered by <a href="https://sledjhamr.org/cgit/notYetAnotherWiki/about/">notYetAnotherWiki</a> Version -0.1. ', |
11 | } | 11 | } |
12 | local sites = {} | 12 | local Sites, Files, Subs = {}, {}, {} |
13 | 13 | ||
14 | 14 | ||
15 | 15 | local copyTable = function(t, strip) | |
16 | local directory = arg[1] | 16 | -- A simple table.subtable = subtable wont work, you end up with a reference so that changes to the later get applaid to the former. |
17 | if nil == directory then directory = '.' end | 17 | local argh = {} |
18 | local all = {} | 18 | for l, y in ipairs(t) do |
19 | if '.' ~= directory then | 19 | if (l ~= y.name) and strip then table.insert(argh, y) end |
20 | for l in io.popen('find . -name "*.md" -type f,l -printf "%P\n"'):lines() do | ||
21 | all[l] = l | ||
22 | end | 20 | end |
23 | end | 21 | return argh |
24 | for l in io.popen('find ' .. directory .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do | ||
25 | if nil == all[l] then all[l] = l end | ||
26 | end | 22 | end |
27 | 23 | ||
28 | for i, l in pairs(all) do | 24 | local stringBits = function(l) |
29 | local dir, file, parent, path = '', '', '', '', '' | ||
30 | local bits = {} | 25 | local bits = {} |
31 | local last = 1 | 26 | local last = 1 |
32 | for j = 1, #l do | 27 | for j = 1, #l do |
33 | local c = string.sub(l, j, j) | 28 | if '/' == string.sub(l, j, j) then |
34 | if '/' == c then | ||
35 | table.insert(bits, string.sub(l, last, j - 1)) | 29 | table.insert(bits, string.sub(l, last, j - 1)) |
36 | last = j + 1 | 30 | last = j + 1 |
37 | end | 31 | end |
38 | end | 32 | end |
39 | file = string.sub(l, last) | 33 | return bits, string.sub(l, last) |
40 | file = string.gsub(file, '%.md$', '') | 34 | end |
35 | |||
41 | 36 | ||
42 | local ln = #bits | ||
43 | if 0 < ln then | ||
44 | dir = bits[ln] | ||
45 | path = table.concat(bits, '/', 1, ln) | ||
46 | if 1 < ln then parent = table.concat(bits, '/', 1, ln - 1) end | ||
47 | end | ||
48 | 37 | ||
49 | local files = {name = file, URL = '<p><a href="' .. file .. '.HTML">' .. file .. '</a></p>', } | 38 | local directory = arg[1] |
50 | if nil == sites[path] then sites[path] = {files = {files}} | 39 | if nil == directory then directory = '.' end |
51 | elseif nil == sites[path].files then sites[path].files = {files} | 40 | if '.' ~= directory then |
52 | else table.insert(sites[path].files, files) | 41 | for l in io.popen('find . -name "*.md" -type f,l -printf "%P\n"'):lines() do |
42 | Files[string.gsub(l, '%.md$', '')] = {} | ||
53 | end | 43 | end |
44 | end | ||
45 | for l in io.popen('find ' .. directory .. ' -name "*.md" -type f,l -printf "%P\n"'):lines() do | ||
46 | local n = string.gsub(l, '%.md$', '') | ||
47 | if nil == Files[n] then Files[n] = {} end | ||
48 | end | ||
54 | 49 | ||
55 | if '' ~= dir then | 50 | -- Gotta figure out all the files and subs first. File and sub metadata comes along for the ride. |
56 | -- FIXME - not sure why this is needed anymore, but it fails building subs without it. Just slows things down otherwise. | 51 | Subs[''] = {files = {}, subs = {}, bits = {}} |
57 | files = {name = dir, URL = '<a href="' .. dir .. '/">' .. dir .. '</a> ', } | 52 | for name, file in pairs(Files) do |
58 | if nil == sites[parent] then sites[parent] = {subs = {[files.name] = files}} | 53 | local bitter, path = '', '' |
59 | elseif nil == sites[parent].subs then sites[parent].subs = {[files.name] = files} | 54 | local bits, bit = stringBits(name) |
60 | else sites[parent].subs[files.name] = files | 55 | local ln = #bits |
61 | end | 56 | |
57 | Files[name].bits = bits | ||
58 | Files[name].bit = bit | ||
59 | if ln > 0 then bitter = bits[1] end | ||
60 | if '' ~= bitter then Subs[''].subs[bitter] = bitter end -- "bitter end" was entirely by accident, I'm keeping it. B-) | ||
61 | for i, d in ipairs(bits) do | ||
62 | if '' ~= path then path = path .. '/' end | ||
63 | path = path .. d | ||
64 | if nil == Subs[path] then Subs[path] = {files = {}, subs = {}} end | ||
65 | if i < ln then Subs[path].subs[bits[i + 1]] = bits[i + 1] end | ||
66 | Subs[path].bits = copyTable(bits, true) | ||
67 | if i < ln then table.remove(Subs[path].bits, #bits) end | ||
62 | end | 68 | end |
63 | 69 | ||
70 | print('Parsing ' .. name .. '.md') | ||
71 | local h = io.open(name .. '.md', 'r') | ||
72 | -- TODO - should bail here on error? | ||
73 | if nil ~= h then file.cm = h:read('*a') ; h:close() else print('oops! No such name ' .. name) end | ||
74 | local body, metadata, err = lcmark.convert(file.cm, "html", {smart = true, yaml_metadata = true, columns = 0}) | ||
75 | if nil == body then print('oops! ' .. err) | ||
76 | elseif '' == body then | ||
77 | Subs[path].metadata = metadata | ||
78 | Files[name] = nil | ||
79 | else | ||
80 | file.metadata = metadata | ||
81 | file.body = body | ||
82 | table.insert(Subs[path].files, bit) | ||
83 | end | ||
64 | end | 84 | end |
65 | 85 | ||
66 | for k, v in pairs(sites) do | 86 | |
67 | local bit, dir, file, parent, path = '', '', '', '', '' | 87 | |
68 | local bits = {} | 88 | -- These functions assume the above file and sub scan has completed. |
69 | local last = 1 | 89 | local whichPage = function(f) |
70 | for j = 1, #k do | 90 | local fl = '' |
71 | local c = string.sub(k, j, j) | 91 | if (nil ~= Subs[f]) then |
72 | if '/' == c then | 92 | if 1 == #(Subs[f].files) then fl = Subs[f].files[1] .. '.HTML' else |
73 | table.insert(bits, string.sub(k, last, j - 1)) | 93 | for i, v in ipairs{'README', 'readme', 'INDEX', 'index'} do |
74 | last = j + 1 | 94 | for j, w in ipairs(Subs[f].files) do |
95 | if v == w then | ||
96 | print('FOUND ' .. v .. '.HTML') | ||
97 | fl = v .. '.HTML' | ||
98 | break | ||
99 | end | ||
100 | end | ||
101 | if '' ~= fl then break end | ||
102 | end | ||
75 | end | 103 | end |
76 | end | 104 | end |
77 | sites[k].parent = table.concat(bits, '/') | 105 | return fl |
78 | table.insert(bits, string.sub(k, last)) | 106 | end |
79 | sites[k].bits = bits | 107 | |
80 | if nil ~= sites[k].files then table.sort(sites[k].files, function(a, b) return (a.name <= b.name) end) end | 108 | |
81 | 109 | local linkFrom = function(source, dest) | |
82 | dir = bits[#bits - 1] | 110 | local depth = 0 |
83 | file = bits[#bits] | 111 | local link = '' |
84 | if nil ~= sites[dir] then | 112 | if source ~= dest then |
85 | if nil == sites[dir].subs then sites[dir].subs = {} end | 113 | for i, v in ipairs(Subs[source].bits) do |
86 | last = nil | 114 | if v ~= Subs[dest].bits[i] then |
87 | for j, g in pairs(sites[dir].subs) do | 115 | depth = i |
88 | if (g.name == dir) or (g.name == file) then | ||
89 | last = j | ||
90 | break | 116 | break |
91 | end | 117 | end |
92 | end | 118 | end |
93 | if nil == last then | 119 | depth = #(Subs[source].bits) - depth |
94 | sites[dir].subs[file] = {name = file, URL = '<a href="' .. file .. '/">' .. file .. '</a> '} | 120 | depth = depth + 1 |
95 | end | 121 | link = string.rep('../', depth) |
96 | end | 122 | if (0 == depth) or (depth > #(Subs[dest].bits)) then |
97 | 123 | for i, v in ipairs(Subs[dest].bits) do | |
98 | bits = {} | 124 | if i >= depth then |
99 | if nil ~= v.subs then | 125 | if '' ~= link then link = link .. '/' end |
100 | for l, w in pairs(v.subs) do | 126 | link = link .. Subs[dest].bits[i] |
101 | table.insert(bits, w) | 127 | end |
128 | end | ||
102 | end | 129 | end |
103 | table.sort(bits, function(a, b) return (a.name <= b.name) end) | ||
104 | v.subs = bits | ||
105 | end | 130 | end |
131 | return link | ||
106 | end | 132 | end |
107 | 133 | ||
108 | 134 | ||
109 | for k, v in pairs(sites) do | ||
110 | 135 | ||
111 | if nil ~= v.files then | 136 | for name, file in pairs(Files) do |
112 | for l, w in pairs(v.files) do | 137 | local path, result = '', '' |
113 | local path = v.parent | 138 | local body, metadata = Files[name].body, Files[name].metadata |
114 | if '' ~= path then path = path .. '/' end | 139 | local bits, bit = Files[name].bits, Files[name].bit |
115 | path = path .. v.bits[#(v.bits)] | 140 | local ln = #bits |
116 | if '' ~= path then path = path .. '/' end | ||
117 | local file = path .. w.name .. '.md' | ||
118 | if (nil ~= file) and ('' ~= file) then io.write('Parsing ' .. file .. ' -> ') end | ||
119 | 141 | ||
120 | local h = io.open(file, 'r') | 142 | path = table.concat(bits, '/', 1, ln) |
121 | if nil ~= h then | ||
122 | local cm = h:read('*a') | ||
123 | local result = '' | ||
124 | local body, metadata, err = lcmark.convert(cm, "html", {smart = true, yaml_metadata = true, columns = 0}) | ||
125 | |||
126 | if nil == body then print('oops! ' .. err) else | ||
127 | |||
128 | |||
129 | if '' == body then | ||
130 | -- A simple v.metadata = metadata wont work, you end up with a reference so that changes to metadata get applied to v.metadata. | ||
131 | v.metadata = {} | ||
132 | for l, y in pairs(metadata) do | ||
133 | v.metadata[l] = y | ||
134 | end | ||
135 | local argh = {} | ||
136 | for l, y in ipairs(v.files) do | ||
137 | if w.name ~= y.name then table.insert(argh, y) end | ||
138 | end | ||
139 | v.files = argh | ||
140 | print('') | ||
141 | else | ||
142 | |||
143 | local bod, err = lcmark.compile_template(body) | ||
144 | if nil == bod then print('oops! ' .. err) else | ||
145 | local templateFile = metadata.template | ||
146 | if nil == file then | ||
147 | templateFile = nil | ||
148 | else | ||
149 | if nil == templateFile then templateFile = 'default' end | ||
150 | templateFile = templateFile .. '.template' | ||
151 | for m, x in pairs(globalData) do if nil == metadata[m] then metadata[m] = x else print('metadata already has ' .. m) end end | ||
152 | if nil ~= v.metadata then | ||
153 | for m, x in pairs(v.metadata) do if nil == metadata[m] then metadata[m] = x else print('metadata already has ' .. m) end end | ||
154 | end | ||
155 | end | ||
156 | |||
157 | if nil ~= v.files then | ||
158 | for m, x in ipairs(v.files) do | ||
159 | metadata.menu = metadata.menu .. x.URL .. '\n' | ||
160 | end | ||
161 | end | ||
162 | if nil ~= v.subs then | ||
163 | for m, x in pairs(v.subs) do | ||
164 | metadata.header = metadata.header .. x.URL | ||
165 | end | ||
166 | end | ||
167 | |||
168 | local num = #(v.bits) | ||
169 | local trail = '<a href="' .. string.rep('../', num) .. '">home</a> ' | ||
170 | local p = v.parent | ||
171 | for i = 1, num do | ||
172 | trail = trail .. '<a href="' .. string.rep('../', num - i) .. '">' .. v.bits[i] .. '</a> ' | ||
173 | end | ||
174 | trail = trail .. w.name | ||
175 | metadata.trail = trail | ||
176 | |||
177 | if nil ~= metadata.pagehistory then metadata.history = '<p>Page <a href="' .. metadata.pagehistory .. '">history</a></p>' end | ||
178 | if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a> ' .. metadata.footer end | ||
179 | if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed</a> ' .. metadata.footer end | ||
180 | if metadata.footer ~= globalData.footer then metadata.footer = 'Web site ' .. metadata.footer end | ||
181 | metadata.footer = '<p>' .. metadata.footer .. '</p>' | ||
182 | metadata.body = lcmark.apply_template(bod, metadata) | ||
183 | |||
184 | local tm = '' | ||
185 | if nil ~= templateFile then | ||
186 | local h = io.open(templateFile, 'r') | ||
187 | if nil ~= h then | ||
188 | tm = tm .. h:read('*a') | ||
189 | h:close() | ||
190 | else | ||
191 | print('oops! No such file ' .. templateFile) | ||
192 | end | ||
193 | |||
194 | local template, err = lcmark.compile_template(tm) | ||
195 | if nil == template then print('oops! ' .. err) else | ||
196 | result = lcmark.apply_template(template, metadata) | ||
197 | end | ||
198 | else | ||
199 | result = body | ||
200 | end | ||
201 | |||
202 | if ('' ~= result) and (nil ~= file) then | ||
203 | local base = path .. w.name .. '.HTML' | ||
204 | print(base) | ||
205 | local a, e = io.open(base, 'w') | ||
206 | if nil == a then print('Could not open ' .. base .. ' - ' .. e) else | ||
207 | a:write(result) | ||
208 | a:close() | ||
209 | end | ||
210 | else | ||
211 | print('') | ||
212 | end | ||
213 | end | ||
214 | 143 | ||
144 | if '' ~= body then | ||
145 | local bod, err = lcmark.compile_template(body) | ||
146 | if nil == bod then print('oops! ' .. err) else | ||
147 | local templateFile = metadata.template | ||
148 | if nil == templateFile then templateFile = 'default' end | ||
149 | file.template = templateFile .. '.template' | ||
150 | end | ||
151 | |||
152 | local pth = '' | ||
153 | for i, d in ipairs(bits) do | ||
154 | if '' ~= pth then pth = pth .. '/' end | ||
155 | pth = pth .. d | ||
156 | if nil ~= Subs[pth] then | ||
157 | if nil ~= Subs[pth].metadata then | ||
158 | for m, x in pairs(Subs[pth].metadata) do | ||
159 | if nil == metadata[m] then | ||
160 | metadata[m] = x | ||
161 | else | ||
215 | end | 162 | end |
163 | end | ||
164 | end | ||
165 | end | ||
166 | end | ||
167 | |||
168 | if nil ~= Subs[''].metadata then | ||
169 | for m, x in pairs(Subs[''].metadata) do if nil == metadata[m] then metadata[m] = x end end | ||
170 | end | ||
171 | for m, x in pairs(globalData) do if nil == metadata[m] then metadata[m] = x end end | ||
172 | for n, y in ipairs{'favicon', 'logo'} do | ||
173 | local pith = '' | ||
174 | if nil ~= metadata[y] then | ||
175 | local pth = '' | ||
176 | for m, x in ipairs(bits) do | ||
177 | if '' ~= pth then pth = pth .. '/' end | ||
178 | pth = pth .. x | ||
179 | if (nil ~= Subs[pth].metadata) and (nil ~= Subs[pth].metadata[y]) then pith = pth end | ||
180 | end | ||
181 | if ('' == pith) and (nil ~= Subs[''].metadata) and (nil ~= Subs[''].metadata[y]) then pith = pth end | ||
182 | if '' == pith then metadata[y] = linkFrom(path, pith) .. globalData[y] | ||
183 | else metadata[y] = linkFrom(path, pith) .. metadata[y] | ||
216 | end | 184 | end |
185 | end | ||
186 | end | ||
187 | |||
188 | metadata.header = '' | ||
189 | local pth = '' | ||
190 | for i, f in pairs(Subs[path].subs) do | ||
191 | local fl = '' | ||
192 | if '' ~= path then | ||
193 | if '' ~= pth then pth = pth .. '/' end | ||
194 | pth = pth .. f | ||
195 | fl = whichPage(pth) | ||
196 | else | ||
197 | fl = whichPage(f) | ||
198 | end | ||
199 | |||
200 | -- if '' == fl then | ||
201 | -- metadata.header = metadata.header .. f .. '</a> ' | ||
202 | -- else | ||
203 | metadata.header = metadata.header .. '<a href="' .. f .. '/' .. fl .. '">' .. f .. '</a> ' | ||
204 | -- end | ||
205 | end | ||
206 | |||
207 | metadata.menu = '' | ||
208 | if nil ~= Subs[path].files then table.sort(Subs[path].files) end | ||
209 | for i, f in ipairs(Subs[path].files) do | ||
210 | if name == f then | ||
211 | metadata.menu = metadata.menu .. '<p>' .. f .. '</p>' | ||
212 | else | ||
213 | metadata.menu = metadata.menu .. '<p><a href="' .. f .. '.HTML">' .. f .. '</a></p>' | ||
214 | end | ||
215 | end | ||
216 | |||
217 | metadata.trail = '' | ||
218 | for i, b in ipairs(bits) do | ||
219 | if i < #bits then | ||
220 | metadata.trail = metadata.trail .. '<a href="' .. linkFrom(path, table.concat(bits, '/', 1, i)) .. whichPage(b) .. '">' .. b .. '</a> ' | ||
221 | linkFrom(path, table.concat(bits, '/', 1, i)) | ||
222 | else | ||
223 | metadata.trail = metadata.trail .. b .. ' ' | ||
224 | end | ||
225 | end | ||
226 | -- if '' == metadata.trail then metadata.trail = '<a href="' .. string.rep('../', ln) .. '/' .. whichPage('') .. '">home</a> ' end | ||
217 | 227 | ||
228 | if nil ~= metadata.pagehistory then metadata.history = '<p>Page <a href="' .. metadata.pagehistory .. '">history</a></p>' end | ||
229 | if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a> ' .. metadata.footer end | ||
230 | if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed</a> ' .. metadata.footer end | ||
231 | if metadata.footer ~= globalData.footer then metadata.footer = 'Web site ' .. metadata.footer end | ||
232 | metadata.footer = '<p>' .. metadata.footer .. '</p>' | ||
233 | |||
234 | metadata.body = lcmark.apply_template(bod, metadata) | ||
235 | |||
236 | local tm = '' | ||
237 | if nil ~= file.template then | ||
238 | local h = io.open(file.template, 'r') | ||
239 | if nil ~= h then | ||
240 | tm = tm .. h:read('*a') | ||
218 | h:close() | 241 | h:close() |
219 | else | 242 | else |
220 | print('oops! No such file ' .. file) | 243 | print('oops! No such file ' .. file.template) |
221 | end | 244 | end |
222 | 245 | ||
246 | local template, err = lcmark.compile_template(tm) | ||
247 | if nil == template then print('oops! ' .. err) else | ||
248 | result = lcmark.apply_template(template, metadata) | ||
249 | end | ||
250 | else | ||
251 | result = body | ||
223 | end | 252 | end |
224 | end | ||
225 | 253 | ||
254 | if '' ~= result then | ||
255 | local base = name .. '.HTML' | ||
256 | print('From ' .. name .. '.md -> ' .. base) | ||
257 | local a, e = io.open(base, 'w') | ||
258 | if nil == a then print('Could not open ' .. base .. ' - ' .. e) else | ||
259 | a:write(result) | ||
260 | a:close() | ||
261 | end | ||
262 | end | ||
263 | |||
264 | else | ||
265 | print('') | ||
266 | end | ||
226 | end | 267 | end |
227 | 268 | ||
228 | 269 | ||