Overview
| Comment: | add --version -V flag |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
0c6a7846785c6aa3dbf9875546d9c41d |
| User & Date: | lexi on 2021-12-21 05:04:57 |
| Other Links: | manifest | tags |
Context
|
2021-12-22
| ||
| 10:19 | add extension mechanism, move toc to extensions, update docs, fix bugs check-in: 330e1ecfdb user: lexi tags: trunk | |
|
2021-12-21
| ||
| 05:04 | add --version -V flag check-in: 0c6a784678 user: lexi tags: trunk | |
| 03:26 | fix embarassing typobug check-in: d5e8521d30 user: lexi tags: trunk | |
Changes
Modified cli.lua from [37b0a0a8ee] to [bdd85f20a4].
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 .. 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 ... 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 ... 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
local ss = require 'sirsem'
local default_mode = {
['render:format'] = 'html';
['html:gen-styles'] = true;
}
local function
kmap(fn, list)
local new = {}
for k, v in pairs(list) do
local nk,nv = fn(k,v)
new[nk or k] = nv or v
end
return new
end
local function
kfilter(list, fn)
local new = {}
for k, v in pairs(list) do
if fn(k,v) then new[k] = v end
end
return new
end
local function
main(input, output, log, mode, suggestions, vars)
local doc = ct.parse(input.stream, input.src, mode)
input.stream:close()
if mode['parse:show-tree'] then
log:write(dump(doc))
end
................................................................................
error 'what output format should i translate the input to?'
end
if mode['render:format'] == 'none' then return 0 end
if not ct.render[mode['render:format']] then
ct.exns.unimpl('output format “%s” unsupported', mode['render:format']):throw()
end
local render_opts = kmap(function(k,v)
return k:sub(2+#mode['render:format'])
end, kfilter(mode, function(m)
return ss.str.begins(m, mode['render:format']..':')
end))
doc.vars = vars
-- this is kind of gross but the context object belongs to the parser,
-- not the renderer, so that's not a suitable place for this information
................................................................................
mode = function(key,value) mode[checkmodekey(key)] = value end;
['mode-set'] = function(key) mode[checkmodekey(key)] = true end;
['mode-clear'] = function(key) mode[checkmodekey(key)] = false end;
['mode-weak'] = function(key,value) suggestions[checkmodekey(key)] = value end;
['mode-set-weak'] = function(key) suggestions[checkmodekey(key)] = true end;
['mode-clear-weak'] = function(key) suggestions[checkmodekey(key)] = false end;
}
local args = {}
local keepParsing = true
do local i = 1 while i <= #arg do local v = arg[i]
local execLongOpt = function(longopt)
if not onswitch[longopt] then
ct.exns.cli('switch --%s unrecognized', longopt):throw()
end
local nargs = optnparams(longopt)
if nargs > 1 then
if i + nargs > #arg then
ct.exns.cli('not enough arguments for switch --%s (%u expected)', longopt, nargs):throw()
end
local nt = {}
for j = i+1, i+nargs do
table.insert(nt, arg[j])
end
onswitch[longopt](table.unpack(nt))
elseif nargs == 1 then
onswitch[longopt](arg[i+1])
end
i = i + nargs
end
if v == '--' then
keepParsing = false
else
local longopt = v:match '^%-%-(.+)$'
................................................................................
execLongOpt(longopt)
else
if keepParsing and v:sub(1,1) == '-' then
for c,p in ss.str.enc.utf8.each(v:sub(2)) do
if optmap[c] then
execLongOpt(optmap[c])
else
ct.exns.cli('switch -%i unrecognized', c):throw()
end
end
else
table.insert(args, v)
end
end
|
< < < < < < < < < < < < < < < < < < < | | > > > > > > > > > > > > > > > > > > > > > > > | | > > | |
2 3 4 5 6 7 8 9 10 11 12 13 14 15 .. 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 ... 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 ... 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
local ss = require 'sirsem'
local default_mode = {
['render:format'] = 'html';
['html:gen-styles'] = true;
}
local function
main(input, output, log, mode, suggestions, vars)
local doc = ct.parse(input.stream, input.src, mode)
input.stream:close()
if mode['parse:show-tree'] then
log:write(dump(doc))
end
................................................................................
error 'what output format should i translate the input to?'
end
if mode['render:format'] == 'none' then return 0 end
if not ct.render[mode['render:format']] then
ct.exns.unimpl('output format “%s” unsupported', mode['render:format']):throw()
end
local render_opts = ss.kmap(function(k,v)
return k:sub(2+#mode['render:format'])
end, ss.kfilter(mode, function(m)
return ss.str.begins(m, mode['render:format']..':')
end))
doc.vars = vars
-- this is kind of gross but the context object belongs to the parser,
-- not the renderer, so that's not a suitable place for this information
................................................................................
mode = function(key,value) mode[checkmodekey(key)] = value end;
['mode-set'] = function(key) mode[checkmodekey(key)] = true end;
['mode-clear'] = function(key) mode[checkmodekey(key)] = false end;
['mode-weak'] = function(key,value) suggestions[checkmodekey(key)] = value end;
['mode-set-weak'] = function(key) suggestions[checkmodekey(key)] = true end;
['mode-clear-weak'] = function(key) suggestions[checkmodekey(key)] = false end;
['version'] = function()
outp:write(ct.info:about())
if next(ct.ext.loaded) then
outp:write('\nactive extensions:\n')
for k,v in pairs(ct.ext.loaded) do
outp:write(string.format(' * %s', v.id ..
(v.version and (' ' .. v.version:string()) or '')))
if v.desc then
outp:write(string.format(': %s', v.desc))
if v.contributors then
outp:write(string.format(' [%s]', table.concat(
ss.map(function(ctr)
return ctr.name or ctr.handle
end, v.contributors), ', ')))
end
else
outp:write'\n'
end
end
end
os.exit(0)
end
}
local args = {}
local keepParsing = true
do local i = 1 while i <= #arg do local v = arg[i]
local execLongOpt = function(longopt)
if not onswitch[longopt] then
ct.exns.cli('switch --%s unrecognized', longopt):throw()
end
local nargs = optnparams(longopt)
if nargs > 1 then
if i + nargs > #arg then
ct.exns.cli('not enough arguments for switch --%s (%s expected)', longopt, nargs):throw()
end
local nt = {}
for j = i+1, i+nargs do
table.insert(nt, arg[j])
end
print('onsw')
elseif nargs == 1 then
onswitch[longopt](arg[i+1])
else
onswitch[longopt]()
end
i = i + nargs
end
if v == '--' then
keepParsing = false
else
local longopt = v:match '^%-%-(.+)$'
................................................................................
execLongOpt(longopt)
else
if keepParsing and v:sub(1,1) == '-' then
for c,p in ss.str.enc.utf8.each(v:sub(2)) do
if optmap[c] then
execLongOpt(optmap[c])
else
ct.exns.cli('switch -%s unrecognized', c):throw()
end
end
else
table.insert(args, v)
end
end
|
Modified cortav.lua from [70cf5fbd0d] to [7d896a453b].
8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
local startswith = ss.str.begins
local eachcode = ss.str.enc.utf8.each
local dump = ss.dump
local declare = ss.declare
-- make this module available to require() when linked into a lua bytecode program with luac
local ct = ss.namespace 'cortav'
ct.render = {}
ct.exns = {
tx = ss.exnkind('translation error', function(msg,...)
return string.format("(%s:%u) "..msg, ...)
end);
io = ss.exnkind('IO error', function(msg, ...)
|
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
local startswith = ss.str.begins local eachcode = ss.str.enc.utf8.each local dump = ss.dump local declare = ss.declare -- make this module available to require() when linked into a lua bytecode program with luac local ct = ss.namespace 'cortav' ct.info = { version = ss.version {0,1; 'devel'}; package_name = 'cortav'; contributors = { { name = 'lexi hale', handle = 'velartrill'; mail = 'lexi@hale.su', homepage = 'https://hale.su' }; }; ident_string = function(i) return string.format('%s %s', i.package_name, i.version) end; credits = function(i) local all = ss.copy(i.contributors) for i,who in pairs(all) do who.role = who.role or 'core functionality' end for name,ext in pairs(ct.ext.loaded) do if ext.contributors then for _,c in pairs(ext.contributors) do local ofs, ref = ss.find(all, function(a) return a.handle == c.handle end) if ofs then ref.role = string.format('%s; %s extension', ref.role, name) else local c = ss.clone(ext.author) c.role = name .. ' extension' end end end end return all end; credits_ascii = function(contributors) local body = '' for _, c in pairs(contributors) do local str if c.handle then str = string.format('%s “%s” <%s>', c.name, c.handle, c.mail) else str = string.format('%s <%s>', c.name, c.mail) end if c.homepage then str = string.format('%s (%s)', str, c.homepage) end if c.role then str = string.format('%s: %s', str, c.role) end body = body .. string.format(' ~ %s\n', str) end return body end; about = function(i) return i:ident_string() .. '\n' .. i.credits_ascii(i:credits()) end; } ct.render = {} ct.exns = { tx = ss.exnkind('translation error', function(msg,...) return string.format("(%s:%u) "..msg, ...) end); io = ss.exnkind('IO error', function(msg, ...) |
Modified ext/toc.lua from [a3dcc0807f] to [ed743c91e7].
1 2 3 4 5 6 7 8 9 10 |
local ct = require 'cortav'
local ss = require 'sirsem'
ct.ext.install {
id = 'toc';
desc = 'provides a table of contents for HTML renderer plus generic fallback';
directive = function(words)
end;
}
|
> > |
1 2 3 4 5 6 7 8 9 10 11 12 |
local ct = require 'cortav'
local ss = require 'sirsem'
ct.ext.install {
id = 'toc';
desc = 'provides a table of contents for HTML renderer plus generic fallback';
version = ss.version {0,1; 'devel'};
contributors = {{name='lexi hale', handle='velartrill', mail='lexi@hale.su', homepage='https://hale.su'}};
directive = function(words)
end;
}
|
Modified sirsem.lua from [a1f6282434] to [8f6ee343ec].
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
268
269
270
271
272
273
274
|
function ss.filter(list, fn)
local new = {}
for i, v in ipairs(list) do
if fn(v,i) then table.insert(new, v) end
end
return new
end
ss.str = {}
function ss.str.begins(str, pfx)
return string.sub(str, 1, #pfx) == pfx
end
................................................................................
ss.str.exn('out of place token “%s”', stop):throw()
end
end
end
ss.str.exn('token “%s” expected before end of line', stop):throw()
end
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
function ss.filter(list, fn)
local new = {}
for i, v in ipairs(list) do
if fn(v,i) then table.insert(new, v) end
end
return new
end
function ss.kmap(fn, list)
local new = {}
for k, v in pairs(list) do
local nk,nv = fn(k,v)
new[nk or k] = nv or v
end
return new
end
function ss.kfilter(list, fn)
local new = {}
for k, v in pairs(list) do
if fn(k,v) then new[k] = v end
end
return new
end
function ss.find(tbl, pred, ...)
pred = pred or function(a,b)
return a == b
end
for k,v in pairs(tbl) do
if pred(v,k,...) then return k,v end
end
return nil
end
function ss.clone(tbl) -- performs a shallow copy
if tbl.clone then return tbl:clone() end
local new = {}
for k,v in pairs(tbl) do
new[k] = v
end
return new
end
function ss.copy(tbl) -- performs a deep copy
local new = {}
for k,v in pairs(tbl) do
if type(v) == 'table' then
if v.clone then
new[k] = v:clone() -- this may or may not do a deep copy!
else
new[k] = ss.copy(v)
end
else
new[k] = v
end
end
return new
end
function ss.delegate(tbl,tpl) -- returns a table that looks up keys it lacks from
-- tbl (lightweight alternative to shallow copies)
tpl = tpl or {}
return setmetatable({}, {__index=tbl})
end
ss.str = {}
function ss.str.begins(str, pfx)
return string.sub(str, 1, #pfx) == pfx
end
................................................................................
ss.str.exn('out of place token “%s”', stop):throw()
end
end
end
ss.str.exn('token “%s” expected before end of line', stop):throw()
end
ss.version = ss.declare {
name = 'version';
mk = function(tbl) return tbl end;
fns = {
pre = function(self,other) end;
post = function(self,other) end;
string = function(self) return tostring(self) end;
};
cast = {
string = function(vers)
if not(next(vers)) then return '0.0' end
local str = ''
for _,v in pairs(vers) do
if type(v) == 'string' then
if str ~= '' then str = str .. '-' end
str = str .. v
else
if str ~= '' then str = str .. '.' end
str = str .. tostring(v)
end
end
return str
end
};
}
function ss.classinstance(o)
local g = getmetatable(o)
if not o then return nil end
local mm = getmetatable(g)
if not o then return nil end
if mm.__name == 'class' then
return g
else
return nil
end
end
|