@@ -285,8 +285,15 @@ 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 @@ -1110,11 +1117,14 @@ 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 + 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('rsrc_set_prop', c, last, ref, val, l) + 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 @@ -1289,10 +1299,8 @@ 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) @@ -1301,13 +1309,14 @@ end end table.insert(d, rsrc) j:hook('block_insert', c, rsrc, s) - if id == '' then --shorthand syntax + 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 @@ -1407,9 +1416,9 @@ end mf(job, ctx, l, dest) --NOTE: you are responsible for triggering the appropriate hooks if you insert anything! end else - if l then + 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 @@ -1550,18 +1559,20 @@ -- 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 + 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 @@ -1579,23 +1590,25 @@ -- 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) + local mc = r.origin + local mac = mc:ref(r.macro) if not mac then - r.origin:fail('no such reference or resource “%s”', r.macro) + 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 - r.origin:fail('block macro “%s” must be either a reference or an embedded text/x.cortav resource', r.macro) + 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