cortav  Diff

Differences From Artifact [3b9ae546e1]:

To Artifact [7f118fbbfd]:


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