282
283
284
285
286
287
288
289
290
291
292
293
294
295
....
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
....
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
....
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
....
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
....
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
|
if sp == nil then
if test then return false else return '' end
else
return sp
end
elseif self.vars[var] then
return self.vars[var]
else
local sp = scanParents(var)
if sp then return sp end
if test then return false end
return '' -- is this desirable behavior?
end
end;
................................................................................
end};
{seq = '\t', pred = function(l)
return (l:match '\t+([^:]+):%s*(.*)$')
end; fn = blockwrap(function(l,c,j,d)
local ref, val = l:match '\t+([^:]+):%s*(.*)$'
local last = d[#d]
local rsrc
if last and last.kind == 'resource' then
last.props[ref] = val
j:hook('rsrc_set_prop', c, last, ref, val, l)
rsrc = last
elseif last and last.kind == 'reference' and last.rsrc then
last.rsrc.props[ref] = val
rsrc = last.rsrc
else
c.sec.refs[ref] = val
end
................................................................................
open = brak;
close = mirror(brak);
}
rsrc.raw = '';
if src == nil then
rsrc.props.src = 'text/x.cortav'
end
else
-- load the raw body, where possible
end
if id then
if c.sec.refs[id] then
c:fail('an object with id “%s” already exists in that section',id)
else
c.sec.refs[id] = rsrc
end
end
table.insert(d, rsrc)
j:hook('block_insert', c, rsrc, s)
if id == '' then --shorthand syntax
local embed = {
kind = 'embed';
rsrc = rsrc;
origin = c;
}
table.insert(d, embed)
j:hook('block_insert', c, embed, s)
end
if brak then
c.mode = {
................................................................................
local mf = job:proc('modes', ctx.mode.kind)
if not mf then
ctx:fail('unimplemented syntax mode %s', ctx.mode.kind)
end
mf(job, ctx, l, dest) --NOTE: you are responsible for triggering the appropriate hooks if you insert anything!
end
else
if l then
local function tryseqs(seqs, ...)
for _, i in pairs(seqs) do
if ((not i.seq ) or startswith(l, i.seq)) and
((not i.pred) or i.pred (l, ctx )) then
i.fn(l, ctx, job, dest, ...)
return true
end
................................................................................
r.origin:fail('resource “%s” is not inline and supplies no URI',
r.id or "(anonymous)")
end
-- the resource has been cached. check the mime-type to see if
-- we need to parse it or if it is suitable as-is
if resource.mime.class == "text" then
if resource.mime.kind == "x.cortav" then
local sd, sc = r.origin.doc:sub(r.origin)
local lines = ss.str.breaklines(r.origin.doc.enc, resource.raw, {})
for i, ln in ipairs(lines) do
sc.line = sc.line + 1
ct.parse_line(ln, sc, sc.sec.blocks)
end
resource.doc = sd
end
end
end
table.insert(srcs, resource)
end
r.srcs = srcs
-- note that resources do not themselves have kinds. when a
-- document requests to insert a resource, the renderer must
................................................................................
end
end
-- expand block macros
for i, sec in ipairs(ctx.doc.secorder) do
for n, r in pairs(sec.blocks) do
if r.kind == 'macro' then
local mc = r.origin:clone()
mc.invocation = r
local mac = r.origin:ref(r.macro)
if not mac then
r.origin:fail('no such reference or resource “%s”', r.macro)
end
local subdoc, subctx = ctx.doc:sub(mc)
local rawbody
if type(mac) == 'string' then
rawbody = mac
elseif mac.raw then
rawbody = mac.raw
else
r.origin:fail('block macro “%s” must be either a reference or an embedded text/x.cortav resource', r.macro)
end
local lines = ss.str.breaklines(ctx.doc.enc, rawbody)
for i, ln in ipairs(lines) do
ct.parse_line(ln, subctx, subctx.sec.blocks)
end
r.doc = subdoc
|
>
>
>
>
>
>
>
|
>
>
>
|
<
<
|
>
|
|
<
|
>
>
>
>
|
|
|
|
|
|
<
|
<
|
|
>
>
>
|
|
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
....
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
....
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
....
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
....
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
....
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
|
if sp == nil then
if test then return false else return '' end
else
return sp
end
elseif self.vars[var] then
return self.vars[var]
elseif ctx.invocation
and ctx.invocation.props
and ctx.invocation.props['.' .. var] then
return ctx.invocation.props['.' .. var]
elseif ctx.declaration
and ctx.declaration.props['.' .. var] then
return ctx.declaration.props['.' .. var]
else
local sp = scanParents(var)
if sp then return sp end
if test then return false end
return '' -- is this desirable behavior?
end
end;
................................................................................
end};
{seq = '\t', pred = function(l)
return (l:match '\t+([^:]+):%s*(.*)$')
end; fn = blockwrap(function(l,c,j,d)
local ref, val = l:match '\t+([^:]+):%s*(.*)$'
local last = d[#d]
local rsrc
if last and last.kind == 'resource'
or last.kind == 'embed'
or last.kind == 'macro' then
last.props = last.props or {}
last.props[ref] = val
j:hook('set_prop', c, last, ref, val, l)
rsrc = last
elseif last and last.kind == 'reference' and last.rsrc then
last.rsrc.props[ref] = val
rsrc = last.rsrc
else
c.sec.refs[ref] = val
end
................................................................................
open = brak;
close = mirror(brak);
}
rsrc.raw = '';
if src == nil then
rsrc.props.src = 'text/x.cortav'
end
end
if id then
if c.sec.refs[id] then
c:fail('an object with id “%s” already exists in that section',id)
else
c.sec.refs[id] = rsrc
end
end
table.insert(d, rsrc)
j:hook('block_insert', c, rsrc, s)
if id == nil then --shorthand syntax
local embed = {
kind = 'embed';
rsrc = rsrc;
origin = c;
mode = 'inline';
}
table.insert(d, embed)
j:hook('block_insert', c, embed, s)
end
if brak then
c.mode = {
................................................................................
local mf = job:proc('modes', ctx.mode.kind)
if not mf then
ctx:fail('unimplemented syntax mode %s', ctx.mode.kind)
end
mf(job, ctx, l, dest) --NOTE: you are responsible for triggering the appropriate hooks if you insert anything!
end
else
if l and l ~= '' then
local function tryseqs(seqs, ...)
for _, i in pairs(seqs) do
if ((not i.seq ) or startswith(l, i.seq)) and
((not i.pred) or i.pred (l, ctx )) then
i.fn(l, ctx, job, dest, ...)
return true
end
................................................................................
r.origin:fail('resource “%s” is not inline and supplies no URI',
r.id or "(anonymous)")
end
-- the resource has been cached. check the mime-type to see if
-- we need to parse it or if it is suitable as-is
if ss.mime 'text/x.cortav' < resource.mime then
local sd, sc = r.origin.doc:sub(r.origin)
-- we store the resource block itself in the declaration
-- slot so that its properties (e.g. context variables)
-- can affect the way the document is rendered
sc.declaration = r
local lines = ss.str.breaklines(r.origin.doc.enc, resource.raw, {})
for i, ln in ipairs(lines) do
sc.line = sc.line + 1
ct.parse_line(ln, sc, sc.sec.blocks)
end
resource.doc = sd
end
end
table.insert(srcs, resource)
end
r.srcs = srcs
-- note that resources do not themselves have kinds. when a
-- document requests to insert a resource, the renderer must
................................................................................
end
end
-- expand block macros
for i, sec in ipairs(ctx.doc.secorder) do
for n, r in pairs(sec.blocks) do
if r.kind == 'macro' then
local mc = r.origin
local mac = mc:ref(r.macro)
if not mac then
mc:fail('no such reference or resource “%s”', r.macro)
end
local subdoc, subctx = ctx.doc:sub(mc)
local rawbody
subctx.invocation = r
if type(mac) == 'string' then
rawbody = mac
elseif mac.raw then
rawbody = mac.raw
subctx.declaration = mac
else
mc:fail('block macro “%s” must be either a reference or an embedded text/x.cortav resource', r.macro)
end
local lines = ss.str.breaklines(ctx.doc.enc, rawbody)
for i, ln in ipairs(lines) do
ct.parse_line(ln, subctx, subctx.sec.blocks)
end
r.doc = subdoc
|