cortav  Diff

Differences From Artifact [454581060f]:

To Artifact [00eceed9de]:


   139    139   							self:fail('template instantiation requires at least %u arguments (in ID “%s”)',n,id)
   140    140   						end
   141    141   						return arg
   142    142   					else return sp end
   143    143   				end)
   144    144   
   145    145   			end
   146         -			if not id:find'%.' then
   147         -				local rid = self.sec.refs[id]
   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
          146  +
          147  +			local function checkFromSec(sec,doc)
          148  +				if sec and not id:find'%.' then
          149  +					local rid = sec.refs[id]
          150  +					if rid then
          151  +						return rid, id, sec
          152  +					end
          153  +
          154  +					if doc.sections[rid] then
          155  +						return nil, id, doc.sections[rid]
          156  +					end
          157  +				else
          158  +					local secid, ref = string.match(id, "(.-)%.(.+)")
          159  +					local s
          160  +					s = s or doc.sections[secid]
          161  +					if s then
          162  +						if s.refs[ref] then
          163  +							return s.refs[ref], ref, s
          164  +						end
          165  +					end
          166  +				end
          167  +			end
          168  +
          169  +			local function scanParents(doc)
          170  +				for i, p in ipairs(doc.parents) do
          171  +					-- TODO figure out a way to ref the embedding section
          172  +					local o,i,s = checkFromSec(nil, p)
          173  +					if o or s then return o,i,s end
          174  +				end
          175  +				-- breadth-first search
          176  +				for i, p in ipairs(doc.parents) do
          177  +					local o,i,s = scanParents(p)
          178  +					if o or s then return o,i,s end
          179  +				end
          180  +			end
          181  +
          182  +			local o,i,s = checkFromSec(self.sec, self.doc)
          183  +
          184  +			if o or s then return o,i,s end
          185  +
          186  +			--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
          187  +			if self.invocation then
          188  +				local dp = id:find'%.'
          189  +				if dp == 1 then
          190  +					local s = self.invocation.origin.sec
          191  +					local ref = id:sub(2)
          192  +					if s and s.refs[ref] then
          193  +						return s.refs[ref], ref, s
          194  +					end
          195  +				elseif not dp then
   154    196   					rid = self.invocation.origin:ref(id)
   155    197   					if rid then
   156    198   						return rid, id, self.invocation.origin.sec
   157    199   					end
   158    200   				end
          201  +			end
   159    202   
   160         -				self:fail("no such ref %s in current section", id or '')
   161         -			else
   162         -				local sec, ref = string.match(id, "(.-)%.(.+)")
   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]
   171         -				if not s then -- fall back on inheritance tree
   172         -					for i, p in ipairs(self.doc.parents) do
   173         -						if p.sections[sec] then
   174         -							s = p.sections[sec]
   175         -							break
   176         -						end
   177         -					end
   178         -				end
   179         -				if s then
   180         -					if s.refs[ref] then
   181         -						return s.refs[ref], ref, sec
   182         -					else self:fail("no such ref %s in section %s", ref, sec) end
   183         -				else self:fail("no such section %s", sec) end
   184         -			end
          203  +			o,i,s = scanParents(doc)
          204  +			if o or s then return o,i,s end
          205  +
          206  +			self:fail("ID “%s” does not name an object or section", id)
   185    207   		end
   186    208   	};
   187    209   }
   188    210   
   189    211   ct.sec = declare {
   190    212   	ident = 'section';
   191    213   	mk = function() return {
................................................................................
  1049   1071   			origin = c:clone();
  1050   1072   		}
  1051   1073   		table.insert(c.sec.blocks, tbl)
  1052   1074   		j:hook('block_table_insert', c, tbl, l)
  1053   1075   		j:hook('block_table_row_insert', c, tbl, tbl.rows[1], l)
  1054   1076   	end
  1055   1077   end
         1078  +
         1079  +local function insert_link_block(seq)
         1080  +	return blockwrap(function(s,c)
         1081  +		local r = s:sub(#seq):gsub('^%s+','') -- chomp
         1082  +		local uri, txt = r:match('^([^%s]*)%s*(.*)$')
         1083  +		return {
         1084  +			uri = ss.uri(uri);
         1085  +			label = ct.parse_span(txt, c);
         1086  +		}
         1087  +	end)
         1088  +end
  1056   1089   
  1057   1090   ct.ctlseqs = {
  1058   1091   	{seq = '.', fn = insert_paragraph};
  1059   1092   	{seq = '¶', fn = insert_paragraph};
  1060   1093   	{seq = '❡', fn = insert_paragraph};
  1061   1094   	{seq = '#', fn = insert_section};
  1062   1095   	{seq = '§', fn = insert_section};
................................................................................
  1253   1286   				})[c] ~= true then return false end
  1254   1287   			end
  1255   1288   			return true
  1256   1289   		end
  1257   1290   	end; fn = blockwrap(function()
  1258   1291   		return { kind = 'horiz-rule' }
  1259   1292   	end)};
         1293  +	{seq='=>', fn = insert_link_block '=>'};
         1294  +	{seq='⇒',  fn = insert_link_block '⇒'};
  1260   1295   	{seq='@', fn=function(s,c,j,d)
  1261   1296   		local function mirror(b)
  1262   1297   			local ch = {}
  1263   1298   			local rev = {
  1264   1299   				['['] = ']'; [']'] = '[';
  1265   1300   				['{'] = '}'; ['}'] = '{';
  1266   1301   				['('] = ')'; [')'] = '(';