Differences From
Artifact [23a0968fc6]:
22 22 for k, v in pairs(list) do
23 23 if fn(k,v) then new[k] = v end
24 24 end
25 25 return new
26 26 end
27 27
28 28 local function
29 -main(input, output, log, mode, vars)
29 +main(input, output, log, mode, suggestions, vars)
30 30 local doc = ct.parse(input.stream, input.src, mode)
31 31 input.stream:close()
32 32 if mode['parse:show-tree'] then
33 33 log:write(dump(doc))
34 34 end
35 +
36 + -- the document has now had a chance to give its say; if it hasn't specified
37 + -- any modes of its own, we now merge in the 'weak modes' (suggestions)
38 + for k,v in pairs(suggestions) do
39 + if not mode[k] then mode[k] = v end
40 + end
35 41
36 42 if not mode['render:format'] then
37 43 error 'what output format should i translate the input to?'
38 44 end
39 45 if mode['render:format'] == 'none' then return 0 end
40 46 if not ct.render[mode['render:format']] then
41 47 ct.exns.unimpl('output format ā%sā unsupported', mode['render:format']):throw()
................................................................................
51 57
52 58 -- this is kind of gross but the context object belongs to the parser,
53 59 -- not the renderer, so that's not a suitable place for this information
54 60 doc.stage = {
55 61 kind = 'render';
56 62 format = mode['render:format'];
57 63 mode = mode;
64 + suggestions = suggestions;
58 65 }
59 66
60 67 output:write(ct.render[mode['render:format']](doc, render_opts))
61 68 return 0
62 69 end
63 70
64 71 local inp,outp,log = io.stdin, io.stdout, io.stderr
65 72
66 73 local function entry_cli()
67 - local mode, vars, input = default_mode, {}, {
74 + local suggestions, vars, input = default_mode, {}, {
68 75 stream = inp;
69 76 src = {
70 77 file = '(stdin)';
71 78 }
72 79 }
80 +
81 + local mode = {}
73 82
74 83 local optnparams = function(o)
75 84 local param_opts = {
76 85 out = 1;
77 86 log = 1;
78 87 define = 2; -- key value
88 +
79 89 ['mode-set'] = 1;
80 90 ['mode-clear'] = 1;
81 91 mode = 2;
92 +
93 + ['mode-set-weak'] = 1;
94 + ['mode-clear-weak'] = 1;
95 + ['mode-weak'] = 2;
82 96 }
83 97 return param_opts[o] or 0
84 98 end
85 99
86 100 local optmap = {
87 101 o = 'out';
88 102 l = 'log';
89 103 d = 'define';
90 104 V = 'version';
91 105 h = 'help';
92 - y = 'mode-set', n = 'mode-clear';
93 - m = 'mode';
106 + y = 'mode-set', Y = 'mode-set-weak';
107 + n = 'mode-clear', N = 'mode-clear-weak';
108 + m = 'mode', M = 'mode-weak';
94 109 }
95 110
96 111 local checkmodekey = function(key)
97 112 if not key:match '[^:]+:.+' then
98 113 ct.exns.cli('invalid mode key %s', key):throw()
99 114 end
100 115 return key
................................................................................
117 132 ct.exns.cli 'cannot define variable in restricted namespace':throw()
118 133 end
119 134 vars[key] = value
120 135 end;
121 136 mode = function(key,value) mode[checkmodekey(key)] = value end;
122 137 ['mode-set'] = function(key) mode[checkmodekey(key)] = true end;
123 138 ['mode-clear'] = function(key) mode[checkmodekey(key)] = false end;
139 +
140 + ['mode-weak'] = function(key,value) suggestions[checkmodekey(key)] = value end;
141 + ['mode-set-weak'] = function(key) suggestions[checkmodekey(key)] = true end;
142 + ['mode-clear-weak'] = function(key) suggestions[checkmodekey(key)] = false end;
124 143 }
125 144
126 145 local args = {}
127 146 local keepParsing = true
128 147 do local i = 1 while i <= #arg do local v = arg[i]
129 148 local execLongOpt = function(longopt)
130 149 if not onswitch[longopt] then
................................................................................
172 191 if args[1] and args[1] ~= '' then
173 192 local file = io.open(arg[1], "rb")
174 193 if not file then error('unable to load file ' .. args[1]) end
175 194 input.stream = file
176 195 input.src.file = args[1]
177 196 end
178 197
179 - return main(input, outp, log, mode, vars)
198 + return main(input, outp, log, mode, suggestions, vars)
180 199 end
181 200
182 201 local ok, e = pcall(entry_cli)
183 202 -- local ok, e = true, entry_cli()
184 203 if not ok then
185 204 local str = 'translation failure'
186 205 if ss.exn.is(e) then