121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
....
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
|
ctx.line = 0
ctx.doc = doc
ctx.doc.src = src
ctx.sec = doc:mksec() -- toplevel section
ctx.sec.origin = ctx:clone()
end;
ref = function(self,id)
if not id:find'%.' then
local rid = self.sec.refs[id]
if self.sec.refs[id] then
return self.sec.refs[id], id, self.sec
else self:fail("no such ref %s in current section", id or '') end
else
local sec, ref = string.match(id, "(.-)%.(.+)")
local s = self.doc.sections[sec]
if not s then -- fall back on inheritance tree
for i, p in ipairs(self.doc.parents) do
if p.sections[sec] then
s = p.sections[sec]
break
end
end
................................................................................
return {
kind = 'macro';
macro = id;
args = argv;
}
end)};
{seq='&', fn=blockwrap(function(s,c)
local id, cap = s:match('^&([^%s]+)%s*(.-)%s*$')
if id == nil or id == '' then
c:fail 'malformed embed block'
end
if cap == '' then cap = nil end
return {
kind = 'embed';
ref = id;
cap = cap;
}
end)};
{fn = insert_paragraph};
}
function ct.parse_line(rawline, ctx, dest)
local newspan
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
|
|
>
>
>
>
|
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
....
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
|
ctx.line = 0
ctx.doc = doc
ctx.doc.src = src
ctx.sec = doc:mksec() -- toplevel section
ctx.sec.origin = ctx:clone()
end;
ref = function(self,id)
if self.invocation then
-- allow IDs to contain template substitutions by mimicking the [#n] syntax
id = id:gsub('%b[]', function(sp)
-- should indirection be allowed here? TODO
if sp:sub(2,2) == '#' then
local n = tonumber(sp:sub(3,-2))
if n == nil then
self:fail('invalid template substitution “%s” in ID “%s”', sp, id)
end
local arg = self.invocation.args[n]
if arg == nil then
self:fail('template instantiation requires at least %u arguments (in ID “%s”)',n,id)
end
return arg
else return sp end
end)
end
if not id:find'%.' then
local rid = self.sec.refs[id]
if rid then
return rid, id, self.sec
end
--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
if self.invocation then
rid = self.invocation.origin:ref(id)
if rid then
return rid, id, self.invocation.origin.sec
end
end
self:fail("no such ref %s in current section", id or '')
else
local sec, ref = string.match(id, "(.-)%.(.+)")
local s
if sec == '' then
if self.invocation == nil then
self:fail('site-of-invocation IDs can only be dereferenced in a macro expansion (offending ID: “%s”)', id)
end
s = self.invocation.origin.sec
end
s = s or self.doc.sections[sec]
if not s then -- fall back on inheritance tree
for i, p in ipairs(self.doc.parents) do
if p.sections[sec] then
s = p.sections[sec]
break
end
end
................................................................................
return {
kind = 'macro';
macro = id;
args = argv;
}
end)};
{seq='&', fn=blockwrap(function(s,c)
local mode, id, cap = s:match('^&([-+]?)([^%s]+)%s*(.-)%s*$')
if id == nil or id == '' then
c:fail 'malformed embed block'
end
if cap == '' then cap = nil end
if mode == '-' then mode = 'closed'
elseif mode == '+' then mode = 'open'
else mode = 'inline' end
return {
kind = 'embed';
ref = id;
cap = cap;
mode = mode;
}
end)};
{fn = insert_paragraph};
}
function ct.parse_line(rawline, ctx, dest)
local newspan
|