aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/notYetAnotherWiki.lua
diff options
context:
space:
mode:
Diffstat (limited to 'notYetAnotherWiki.lua')
-rwxr-xr-xnotYetAnotherWiki.lua387
1 files changed, 214 insertions, 173 deletions
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
7local globalData = { 7local 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. &nbsp;', 10 history = '', footer = 'Powered by <a href="https://sledjhamr.org/cgit/notYetAnotherWiki/about/">notYetAnotherWiki</a> Version -0.1. &nbsp;',
11} 11}
12local sites = {} 12local Sites, Files, Subs = {}, {}, {}
13 13
14 14
15 15local copyTable = function(t, strip)
16local 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.
17if nil == directory then directory = '.' end 17 local argh = {}
18local all = {} 18 for l, y in ipairs(t) do
19if '.' ~= 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
23end 21 return argh
24for 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
26end 22end
27 23
28for i, l in pairs(all) do 24local 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$', '') 34end
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>', } 38local directory = arg[1]
50 if nil == sites[path] then sites[path] = {files = {files}} 39if nil == directory then directory = '.' end
51 elseif nil == sites[path].files then sites[path].files = {files} 40if '.' ~= 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
44end
45for 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
48end
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. 51Subs[''] = {files = {}, subs = {}, bits = {}}
57 files = {name = dir, URL = '<a href="' .. dir .. '/">' .. dir .. '</a> &nbsp; ', } 52for 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
64end 84end
65 85
66for 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 89local 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)) 106end
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 109local 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> &nbsp; '} 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
106end 132end
107 133
108 134
109for k, v in pairs(sites) do
110 135
111 if nil ~= v.files then 136for 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> &nbsp; '
170 local p = v.parent
171 for i = 1, num do
172 trail = trail .. '<a href="' .. string.rep('../', num - i) .. '">' .. v.bits[i] .. '</a> &nbsp; '
173 end
174 trail = trail .. w.name
175 metadata.trail = trail
176
177 if nil ~= metadata.pagehistory then metadata.history = '<p>Page&nbsp;<a href="' .. metadata.pagehistory .. '">history</a></p>' end
178 if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a> &nbsp; &nbsp; ' .. metadata.footer end
179 if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed</a> &nbsp; &nbsp; ' .. 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> &nbsp; '
202-- else
203 metadata.header = metadata.header .. '<a href="' .. f .. '/' .. fl .. '">' .. f .. '</a> &nbsp; '
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> &nbsp; '
221 linkFrom(path, table.concat(bits, '/', 1, i))
222 else
223 metadata.trail = metadata.trail .. b .. ' &nbsp; '
224 end
225 end
226-- if '' == metadata.trail then metadata.trail = '<a href="' .. string.rep('../', ln) .. '/' .. whichPage('') .. '">home</a> &nbsp; ' end
217 227
228 if nil ~= metadata.pagehistory then metadata.history = '<p>Page&nbsp;<a href="' .. metadata.pagehistory .. '">history</a></p>' end
229 if nil ~= metadata.sourcecode then metadata.footer = '<a href="' .. metadata.sourcecode .. '">source code</a> &nbsp; &nbsp; ' .. metadata.footer end
230 if nil ~= metadata.feedatom then metadata.footer = '<a href="' .. metadata.feedatom .. '">atom feed</a> &nbsp; &nbsp; ' .. 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
226end 267end
227 268
228 269