cortav  Diff

Differences From Artifact [5feb0b86b1]:

To Artifact [bf3719fe9a]:


    83     83   		return string.format("mode ā€œ%sā€ "..msg, ...)
    84     84   	end);
    85     85   	unimpl = ss.exnkind 'feature not implemented';
    86     86   	ext = ss.exnkind 'extension error';
    87     87   	enc = ss.exnkind('encoding error', function(msg, ...)
    88     88   		return string.format('[%s]' .. msg, ...)
    89     89   	end);
           90  +	rdr = ss.exnkind('could not render', function(msg, ...)
           91  +		return string.format('(backend %s)'..msg, ...)
           92  +	end);
    90     93   }
    91     94   
    92     95   ct.ctx = declare {
    93     96   	mk = function(src) return {src = src} end;
    94     97   	ident = 'context';
    95     98   	cast = {
    96     99   		string = function(me)
................................................................................
   141    144   		depth = 0;
   142    145   		kind = 'ordinary';
   143    146   	} end;
   144    147   	construct = function(self, id, depth)
   145    148   		self.id = id
   146    149   		self.depth = depth
   147    150   	end;
          151  +	fns = {
          152  +		visible = function(self)
          153  +			if self.kind == 'nonprinting' then return false end
          154  +			local invisibles = {
          155  +				['break'] = true;
          156  +				reference = true;
          157  +				resource = true;
          158  +				directive = true;
          159  +			}
          160  +			for k,b in pairs(self.blocks) do
          161  +				if not (invisibles[b.kind] or b.invisible) then return true end
          162  +				-- extensions that add invisible nodes to the AST must
          163  +				-- mark them as such for rendering to work properly!
          164  +			end
          165  +			return false
          166  +		end;
          167  +	}
   148    168   }
   149    169   
   150    170   ct.doc = declare {
   151    171   	ident = 'doc';
   152    172   	fns = {
   153    173   		mksec = function(self, id, depth)
   154    174   			local o = ct.sec(id, depth)
................................................................................
   749    769   				if ss.str.begins(substr, i.seq) then
   750    770   					found = true
   751    771   					table.insert(spans, i.parse(substr:sub(1+#i.seq), ctx))
   752    772   					break
   753    773   				end
   754    774   			end
   755    775   			if not found then
   756         -				ctx:fail('no recognized control sequence in [%s]', substr)
          776  +				buf = buf .. c
   757    777   			end
   758    778   		elseif c == '\n' then
   759    779   			flush()
   760    780   			table.insert(spans,{kind='line-break',origin=ctx:clone()})
   761    781   		else
   762    782   			buf = buf .. c
   763    783   		end
................................................................................
   986   1006   		if (not last) or (last.kind ~= 'reference') then
   987   1007   			c:fail('reference continuations must immediately follow a reference')
   988   1008   		end
   989   1009   		local str = l:match '^\t\t(.-)%s*$'
   990   1010   		last.val = last.val .. '\n' .. str
   991   1011   		c.sec.refs[last.key] = last.val
   992   1012   	end};
   993         -	{seq = '\t', fn = blockwrap(function(l,c,j,d)
         1013  +	{seq = '\t', pred = function(l)
         1014  +		return (l:match '\t+([^:]+):%s*(.*)$')
         1015  +	end; fn = blockwrap(function(l,c,j,d)
   994   1016   		local ref, val = l:match '\t+([^:]+):%s*(.*)$'
   995   1017   		local last = d[#d]
   996   1018   		local rsrc
   997   1019   		if last and last.kind == 'resource' then
   998   1020   			last.props[ref] = val
   999   1021   			rsrc = last
  1000   1022   		elseif last and last.kind == 'reference' and last.rsrc then
................................................................................
  1185   1207   			end
  1186   1208   		end
  1187   1209   	end
  1188   1210   	job:hook('line_end',ctx,l)
  1189   1211   end
  1190   1212   
  1191   1213   function ct.parse(file, src, mode, setup)
  1192         -
         1214  +	-- this object is threaded down through the parse tree
         1215  +	-- and copied to store information like the origin of the
         1216  +	-- element in the source code
  1193   1217   	local ctx = ct.ctx.mk(src)
  1194   1218   	ctx.line = 0
  1195   1219   	ctx.doc = ct.doc.mk()
  1196   1220   	ctx.doc.src = src
  1197   1221   	ctx.sec = ctx.doc:mksec() -- toplevel section
  1198   1222   	ctx.sec.origin = ctx:clone()
  1199   1223   	ctx.lang = mode['meta:lang']
................................................................................
  1267   1291   			end
  1268   1292   		end
  1269   1293   	end
  1270   1294   	ctx.doc.stage = nil
  1271   1295   	ctx.doc.docjob:hook('meddle_ast')
  1272   1296   	return ctx.doc
  1273   1297   end
         1298  +
         1299  +function ct.expand_var(v)
         1300  +	local val
         1301  +	if v.pos then
         1302  +		if not v.origin.invocation then
         1303  +			v.origin:fail 'positional arguments can only be used in a macro invocation'
         1304  +		elseif not v.origin.invocation.args[v.pos] then
         1305  +			v.origin.invocation.origin:fail('macro invocation %s missing positional argument #%u', v.origin.invocation.macro, v.pos)
         1306  +		end
         1307  +		val = v.origin.invocation.args[v.pos]
         1308  +	else
         1309  +		val = v.origin.doc:context_var(v.var, v.origin)
         1310  +	end
         1311  +	if v.raw then
         1312  +		return val, true
         1313  +	else
         1314  +		return ct.parse_span(val, v.origin), false
         1315  +	end
         1316  +end