Differences From
Artifact [1054336dd5]:
116 116 new.generation = old.generation + 1
117 117 else
118 118 new.generation = 1
119 119 end
120 120 end;
121 121 fns = {
122 122 fail = function(self, msg, ...)
123 + --error(string.format(msg,...))
123 124 ct.exns.tx(msg, self.src.file, self.line or 0, ...):throw()
124 125 end;
125 126 insert = function(self, block)
126 127 block.origin = self:clone()
127 128 table.insert(self.sec.blocks,block)
128 129 return block
129 130 end;
................................................................................
159 160 if sec then
160 161 local rid = sec.refs[id]
161 162 if rid then
162 163 return rid, id, sec
163 164 end
164 165 end
165 166
166 - for _, i in ipairs(sec.imports) do
167 + if sec.imports.objs[id] then
168 + local ol = sec.imports.objs[id]
169 + return ol.obj, id, ol.sec
170 + end
171 +
172 + for _, i in ipairs(sec.imports.scope) do
167 173 local rr, ri, rs = checkFromSec(i, doc)
168 174 if ri then return rr, ri, rs end
169 175 end
170 176
171 177 if doc.sections[id] then
172 178 return nil, id, doc.sections[id]
173 179 end
174 180
175 - for _, i in ipairs(doc.globals) do
181 + if doc.globals.objs[id] then
182 + local ol = doc.globals.objs[id]
183 + return ol.obj, id, ol.sec
184 + end
185 +
186 + for _, i in ipairs(doc.globals.scope) do
176 187 local rr, ri, rs = checkFromSec(i, doc)
177 188 if ri then return rr, ri, rs end
178 189 end
179 190 else
180 191 local secid, ref = string.match(id, "(.-)%.(.+)")
181 192 local s
182 193 s = s or doc.sections[secid]
................................................................................
231 242 }
232 243
233 244 ct.sec = declare {
234 245 ident = 'section';
235 246 mk = function() return {
236 247 blocks = {};
237 248 refs = {};
238 - imports = {};
249 + imports = {scope={}, objs={}};
239 250 depth = 0;
240 251 kind = 'ordinary';
241 252 } end;
242 253 construct = function(self, id, depth)
243 254 self.id = id
244 255 self.depth = depth or self.depth
245 256 end;
................................................................................
366 377 nctx.line = ctx.line
367 378 nctx.docDepth = (ctx.docDepth or 0) + ctx.sec.depth - 1
368 379 return newdoc, nctx
369 380 end;
370 381 };
371 382 mk = function(...) return {
372 383 sections = {};
373 - globals = {};
384 + globals = {objs={},scope={}};
374 385 secorder = {};
375 386 embed = {};
376 387 meta = {};
377 388 vars = {};
378 389 parents = {...};
379 390 ext = {
380 391 inhibit = {};
................................................................................
959 970 if l:sub(1,1) == '.' then l = l:sub(2) end
960 971 return {
961 972 kind = "paragraph";
962 973 spans = ct.parse_span(l, c);
963 974 }
964 975 end)
965 976
966 -local insert_section = function(l,c,j)
967 - local depth, id, t = l:match '^([#§]+)([^%s]*)%s*(.-)$'
977 +local function insert_section(skind) return function(l,c,j)
978 + local depth, id, t = l:match '^([#§^]+)([^%s]*)%s*(.-)$'
968 979 if id and id ~= "" then
969 980 if c.doc.sections[id] then
970 981 c:fail('duplicate section name “%s”', id)
971 982 end
972 983 else id = nil end
973 984
974 985 local s = c.doc:mksec(id, utf8.len(depth))
975 986 s.depth = utf8.len(depth)
976 987 s.origin = c:clone()
977 - s.blocks={}
988 + s.blocks = {}
989 + if skind then s.kind = skind end
978 990
979 - if t and t ~= "" then
991 + if skind ~= "namespace" and t and t ~= "" then
980 992 local heading = {
981 993 kind = "label";
982 994 spans = ct.parse_span(t,c);
983 995 origin = s.origin;
984 996 captions = s;
985 997 }
986 998 c.doc.docjob:hook('meddle_span', heading.spans, heading)
987 999 table.insert(s.blocks, heading)
988 1000 s.heading_node = heading
989 1001 end
990 1002 c.sec = s
991 1003
992 1004 j:hook('section_attach', c, s)
993 -end
1005 +end end
994 1006
995 1007 local dsetmeta = function(w,c,j)
996 1008 local key, val = w(1)
997 1009 c.doc.meta[key] = val
998 1010 j:hook('metadata_set', key, val)
999 1011 end
1000 1012 local dextctl = function(w,c)
................................................................................
1018 1030 license = dsetmeta;
1019 1031 keywords = dsetmeta;
1020 1032 desc = dsetmeta;
1021 1033 when = dcond;
1022 1034 unless = dcond;
1023 1035 with = function(w,c)
1024 1036 local _,str = w(2)
1025 - local aka, name = str:match '^([^=])=(.*)$'
1026 - if aka == nil then name=str aka=name end
1037 + local aka, name = str:match '^([^=]+)=(.+)$'
1027 1038
1039 + if aka == nil then name=str end
1028 1040 local o,id,s = c:ref(name)
1041 +
1029 1042 if o then -- import object
1030 - c.sec.import.objs[aka] = o
1043 + c.sec.imports.objs[aka or name] = {obj=o, sec=s}
1031 1044 else -- import scope
1032 - table.insert(c.sec.import.scope, s)
1045 + if aka ~= nil then c:fail'alias is meaningless for scope import' end
1046 + table.insert(c.sec.imports.scope, s)
1033 1047 end
1034 1048 end;
1035 1049 global = function(w,c)
1036 1050 local _,str = w(2)
1037 1051 if str ~= nil and str ~= '' then
1038 1052 local aka, name = str:match '^([^=])=(.*)$'
1039 - if aka == nil then name=str aka=name end
1040 1053
1054 + if aka == nil then name=str end
1041 1055 local o,id,s = c:ref(name)
1042 1056
1043 1057 if o then
1044 - c.doc.globals.objs[aka] = name
1058 + c.doc.globals.objs[aka or name] = {obj=o, sec=s}
1045 1059 else
1046 - table.insert(c.doc.globals, s)
1060 + if aka ~= nil then c:fail'alias is meaningless for scope import' end
1061 + table.insert(c.doc.globals.scope, s)
1047 1062 end
1048 1063 else
1049 - table.insert(c.doc.globals, c.sec)
1064 + table.insert(c.doc.globals.scope, c.sec)
1050 1065 end
1051 1066 end;
1052 1067 pragma = function(w,c)
1053 1068 end;
1054 1069 lang = function(w,c)
1055 1070 local _, op, l = w(2)
1056 1071 local langstack = c.doc.stage.langstack
................................................................................
1155 1170 end)
1156 1171 end
1157 1172
1158 1173 ct.ctlseqs = {
1159 1174 {seq = '.', fn = insert_paragraph};
1160 1175 {seq = '¶', fn = insert_paragraph};
1161 1176 {seq = '❡', fn = insert_paragraph};
1162 - {seq = '#', fn = insert_section};
1163 - {seq = '§', fn = insert_section};
1177 + {seq = '#', fn = insert_section()};
1178 + {seq = '§', fn = insert_section()};
1179 + {seq = '^', fn = insert_section 'namespace'};
1164 1180 {seq = '+', fn = insert_table_row};
1165 1181 {seq = '|', fn = insert_table_row};
1166 1182 {seq = '│', fn = insert_table_row};
1167 1183 {seq = '!', fn = function(l,c,j,d)
1168 1184 local last = d[#d]
1169 1185 local txt = l:match '^%s*!%s*(.-)$'
1170 1186 if (not last) or last.kind ~= 'aside' then