Differences From
Artifact [454581060f]:
139 139 self:fail('template instantiation requires at least %u arguments (in ID “%s”)',n,id)
140 140 end
141 141 return arg
142 142 else return sp end
143 143 end)
144 144
145 145 end
146 - if not id:find'%.' then
147 - local rid = self.sec.refs[id]
148 - if rid then
149 - return rid, id, self.sec
150 - end
151 -
152 - --nothing in the current section, but this ID could be looked up in the context of a macro expansion. if so, check section of the site of invocation as well
153 - if self.invocation then
146 +
147 + local function checkFromSec(sec,doc)
148 + if sec and not id:find'%.' then
149 + local rid = sec.refs[id]
150 + if rid then
151 + return rid, id, sec
152 + end
153 +
154 + if doc.sections[rid] then
155 + return nil, id, doc.sections[rid]
156 + end
157 + else
158 + local secid, ref = string.match(id, "(.-)%.(.+)")
159 + local s
160 + s = s or doc.sections[secid]
161 + if s then
162 + if s.refs[ref] then
163 + return s.refs[ref], ref, s
164 + end
165 + end
166 + end
167 + end
168 +
169 + local function scanParents(doc)
170 + for i, p in ipairs(doc.parents) do
171 + -- TODO figure out a way to ref the embedding section
172 + local o,i,s = checkFromSec(nil, p)
173 + if o or s then return o,i,s end
174 + end
175 + -- breadth-first search
176 + for i, p in ipairs(doc.parents) do
177 + local o,i,s = scanParents(p)
178 + if o or s then return o,i,s end
179 + end
180 + end
181 +
182 + local o,i,s = checkFromSec(self.sec, self.doc)
183 +
184 + if o or s then return o,i,s end
185 +
186 + --nothing in the current section, but this ID could be looked up in the context of a macro expansion. if so, check section of the site of invocation as well
187 + if self.invocation then
188 + local dp = id:find'%.'
189 + if dp == 1 then
190 + local s = self.invocation.origin.sec
191 + local ref = id:sub(2)
192 + if s and s.refs[ref] then
193 + return s.refs[ref], ref, s
194 + end
195 + elseif not dp then
154 196 rid = self.invocation.origin:ref(id)
155 197 if rid then
156 198 return rid, id, self.invocation.origin.sec
157 199 end
158 200 end
201 + end
159 202
160 - self:fail("no such ref %s in current section", id or '')
161 - else
162 - local sec, ref = string.match(id, "(.-)%.(.+)")
163 - local s
164 - if sec == '' then
165 - if self.invocation == nil then
166 - self:fail('site-of-invocation IDs can only be dereferenced in a macro expansion (offending ID: “%s”)', id)
167 - end
168 - s = self.invocation.origin.sec
169 - end
170 - s = s or self.doc.sections[sec]
171 - if not s then -- fall back on inheritance tree
172 - for i, p in ipairs(self.doc.parents) do
173 - if p.sections[sec] then
174 - s = p.sections[sec]
175 - break
176 - end
177 - end
178 - end
179 - if s then
180 - if s.refs[ref] then
181 - return s.refs[ref], ref, sec
182 - else self:fail("no such ref %s in section %s", ref, sec) end
183 - else self:fail("no such section %s", sec) end
184 - end
203 + o,i,s = scanParents(doc)
204 + if o or s then return o,i,s end
205 +
206 + self:fail("ID “%s” does not name an object or section", id)
185 207 end
186 208 };
187 209 }
188 210
189 211 ct.sec = declare {
190 212 ident = 'section';
191 213 mk = function() return {
................................................................................
1049 1071 origin = c:clone();
1050 1072 }
1051 1073 table.insert(c.sec.blocks, tbl)
1052 1074 j:hook('block_table_insert', c, tbl, l)
1053 1075 j:hook('block_table_row_insert', c, tbl, tbl.rows[1], l)
1054 1076 end
1055 1077 end
1078 +
1079 +local function insert_link_block(seq)
1080 + return blockwrap(function(s,c)
1081 + local r = s:sub(#seq):gsub('^%s+','') -- chomp
1082 + local uri, txt = r:match('^([^%s]*)%s*(.*)$')
1083 + return {
1084 + uri = ss.uri(uri);
1085 + label = ct.parse_span(txt, c);
1086 + }
1087 + end)
1088 +end
1056 1089
1057 1090 ct.ctlseqs = {
1058 1091 {seq = '.', fn = insert_paragraph};
1059 1092 {seq = '¶', fn = insert_paragraph};
1060 1093 {seq = '❡', fn = insert_paragraph};
1061 1094 {seq = '#', fn = insert_section};
1062 1095 {seq = '§', fn = insert_section};
................................................................................
1253 1286 })[c] ~= true then return false end
1254 1287 end
1255 1288 return true
1256 1289 end
1257 1290 end; fn = blockwrap(function()
1258 1291 return { kind = 'horiz-rule' }
1259 1292 end)};
1293 + {seq='=>', fn = insert_link_block '=>'};
1294 + {seq='⇒', fn = insert_link_block '⇒'};
1260 1295 {seq='@', fn=function(s,c,j,d)
1261 1296 local function mirror(b)
1262 1297 local ch = {}
1263 1298 local rev = {
1264 1299 ['['] = ']'; [']'] = '[';
1265 1300 ['{'] = '}'; ['}'] = '{';
1266 1301 ['('] = ')'; [')'] = '(';