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