cortav  Check-in [52f88f818d]

Overview
Comment:macro & doc improvements
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 52f88f818db58c95f4196293a2681596560742a9309535614819a4447c4304c1
User & Date: lexi on 2022-09-09 21:08:16
Other Links: manifest | tags
Context
2022-09-09
21:20
fix stupid table bug check-in: e8ab2a68d8 user: lexi tags: trunk
21:08
macro & doc improvements check-in: 52f88f818d user: lexi tags: trunk
19:04
enable basic ID interpolation check-in: 8b33bc074d user: lexi tags: trunk
Changes

Modified cortav.ct from [1a665df7bf] to [af24dd1316].

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119


120
121
122
123
124
125
126
...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
...
607
608
609
610
611
612
613


















































614
615
616
617
618
619
620
** [`~~~ language] (markdown-style shorthand syntax)
** [`~~~ \[language\] ~~~] (cortav syntax)
** [`~~~ \[language\] #id ~~~]
** [`~~~ title ~~~]
** [`~~~ title \[language\] ~~~]
** [`~~~ \[language\] title ~~~]
** [`~~~ title \[language\] #id ~~~]
*[*definition] ([^def-ex tab]): a line [^def-tab-enc beginning with a tab] is a multipurpose metadata syntax. the tab may be followed by an identifier, a colon, and a value string, in which case it opens a new definition; alternatively, a second tab character turns the line into a [*definition continuation], adding the remaining characters as a new line to the definition value on the previous line.  when a new definition is opened on a line immediately following certain kinds of objects, such as resource, it attaches key-value metadata to that object. when a definition is not preceded by such an object, an independent [*reference] is created instad.
** a [*reference] is a general mechanism for out-of-line metadata, and references are used in many different ways -- e.g. to specify link destinations, footnote contents, abbreviations, or macros. to ensure that a definition is interpreted as a reference, rather than as metadata for an object, precede it with a blank line.
	def-tab-enc: in encodings without tab characters, a definition is opened by a line beginning with two blanks, and continued by a line beginning with four blanks.
	def-ex: [*open a new reference]: [`[!\\t][$key]: [$value]]
		[*continue a reference]: [`[!\\t\\t][$value]]
* [*quotation] ([`<]): a line of the form [`<[$name]> [$quote]] denotes an utterance by [$name].
* [*blockquote] ([`>]): alternate blockquote syntax. can be nested by repeating the [`>] character.
* [*subtitle/caption] ([`\--]): attaches a subtitle to the previous header, or caption to the previous object
* [*embed] ([`&]): embeds a referenced object. can be used to show images or repeat previously defined objects like lists or tables, optionally with a caption.
** [`$[$macro] [$arg1]|[$arg2]|[$argn]…] invokes a block-level macro with the supplied arguments
*** [`$mymacro arg 1|arg 2|arg 3]
** [`&[$image]] embeds an image or other block-level object. [!image] can be a reference with a url or file path, or it can be an embed section (e.g. for SVG files)
***[`&myimg All that remained of the unfortunate blood magic pageant contestants and audience (police photo)]
** [`&-[$ident] [$styled-text]] embeds a closed disclosure element containing the text of the named object (a nonprinting section or cortav resource should usually be used to store the content; it can also name an image or video, of course). in interactive outputs, this will display as a block which can be clicked on to view the full contents of the referenced object [$ident]; if [$styled-text] is present, it overrides the title of the section you are embedding (if any). in static outputs, the disclosure object will display as an enclosed box with [$styled-text] as the title text
*** [`&-ex-a Prosecution Exhibit A (GRAPHIC CONTENT)]
** [`&+[$section] [$styled-text]] is like the above, but the disclosure element is open by default


* [*horizontal rule] ([`\---]): inserts a horizontal rule or other context break; does not end the section. must be followed by newline. underlines can also be used in place of dashes ([`___], [`-_-], [`__-__-__] etc), as can horizontal unicode box drawing characters ([`─ ━ ┈] etc).
* [*page break] ([`\^^]): for formats that support pagination, like EPUB or HTML (when printed), indicates that the rest of the current page should be blank. for formats that do not, extra margins will be inserted. does not create a new section
* [*page rule] ([`\^-^]): inserts a page break for formats that support them, and a horizontal rule for formats that do not. does not create a new section. comprised of any number of horizontal rule characters surrounded by a pair of carets (e.g. [`^-^] [`^_^] [`^----^] [`^__--^] [`^┈┈┈┈┈^])
* [*table cells] ([`+ |]): see [>ex.tab table examples].
* [*equations] ([`=]): block-level equations can be inserted with the [`=] sequence
* [*cross-references] ([`=>] [`⇒]): inserts a block-level link. uses the same syntax as span links ([`⇒[$ident] [$styled-text]]). can be followed by a caption to add a longer descriptive text. especially useful for gemtext output. ident can be omitted to cross-reference, for example, a physical book.
* [*empty lines] (that is, lines consisting of nothing but whitespace) constitute a [!break], which terminates multiline objects that do not have a dedicated termination sequence, for example lists and asides.
................................................................................
*** [`image/*] (graphical outputs only)
*** [`video/*] (interactive outputs only)
*** [`image/svg+xml] is handled specially for HTML files, and may or may not be compatible with other renderer backends.
*** [`font/*] can be used with the HTML backend to reference a web font
*** [`font/woff2] can be used with the HTML backend to reference a web font
*** [`text/plain] (will be inserted as a preformatted text block)
*** [`text/css] (can be used when producing HTML files to link in an extra stylesheet, either by embedding it or referencing it from the header)
*** [`text/x.cortav] (will be parsed and inserted as a formatted text block; context variables can be passed to the file by setting [`ctx.[$var]] parameters on the resource, e.g. [`ctx.recipient-name: Mr. Winthrop])
*** [`application/x-troff] can be used to supply sections of text written in raw [`groff] syntax. these are ignored by other renderers.
*** [`text/html] can be used to supply sections of text written in raw HTML. these are ignored by non-HTML outputs.
*** any MIME-type that matches the type of file being generated by the renderer can be used to include a block of data that will be passed directly to the renderer.
** URI types: additional URI types can be added by extensions or different implementations, but every compliant implementation must support these URIs.
*** [`http], [`https]/[`http+tls]: accesses resources over HTTP. add a [`file] fallback if possible for the benefit of renderers/viewers that do not have internet access abilities.
*** [`file]: references local files. (the meaning of "local" varies depending on the translation format.) absolute paths should begin [`file:/]; the slash should be omitted for relative paths. note that this doesn't have quite the same meaning as in HTML -- [`file] can (and usually should be) used with HTML outputs to refer to resources that reside on the same server. a cortav URI of [`file:/etc/passwd] will actually result in the link [`/etc/passwd], not [`file:///etc/passwd] when converted to HTML. generally, you only should use [`http] when you're referring to a resource that exists on a different domain. on systems where text and binary files are handled differently, the URIs [`file+txt:] and [`file+bin:] can be used to specify an opening mode.
*** [`asset]: identical to file [`file], except that paths are interpreted relative to the asset base (the parent directory of the source file if not otherwise defined), rather than the current working directory of the [`cortav] translator process.
................................................................................
	zombo: https://zombo.com
	any: anything you want
~~~

~~~ macros #mac [cortav] ~~~
the ranuir word {gloss cor|writing}…
	gloss: [*[#1]] “[#2]”


















































~~~

~~~ tables #tab [cortav] ~~~
here is a glossary table.

+ english :+ ranuir + zia ţai  + thaliste        +
| honor   :| tef    | pang     | mbecheve        |







|
|






|
<
<





>
>







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112


113
114
115
116
117
118
119
120
121
122
123
124
125
126
...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
** [`~~~ language] (markdown-style shorthand syntax)
** [`~~~ \[language\] ~~~] (cortav syntax)
** [`~~~ \[language\] #id ~~~]
** [`~~~ title ~~~]
** [`~~~ title \[language\] ~~~]
** [`~~~ \[language\] title ~~~]
** [`~~~ title \[language\] #id ~~~]
*[*definition] ([^def-ex tab]): a line [^def-tab-enc beginning with a tab] is a multipurpose metadata syntax. the tab may be followed by an identifier, a colon, and a value string, in which case it opens a new definition; alternatively, a second tab character turns the line into a [*definition continuation], adding the remaining characters as a new line to the definition value on the previous line.  when a new definition is opened on a line immediately following certain kinds of objects, such as resources, embeds, or multiline macro expansions, it attaches key-value metadata to that object. when a definition is not preceded by such an object, an independent [*reference] is created instad.
** a [*reference] is a general mechanism for out-of-line metadata, and references are used in many different ways -- e.g. to specify link destinations, footnote contents, abbreviations, or macro bodies. to ensure that a definition is interpreted as a reference, rather than as metadata for an object, precede it with a blank line.
	def-tab-enc: in encodings without tab characters, a definition is opened by a line beginning with two blanks, and continued by a line beginning with four blanks.
	def-ex: [*open a new reference]: [`[!\\t][$key]: [$value]]
		[*continue a reference]: [`[!\\t\\t][$value]]
* [*quotation] ([`<]): a line of the form [`<[$name]> [$quote]] denotes an utterance by [$name].
* [*blockquote] ([`>]): alternate blockquote syntax. can be nested by repeating the [`>] character.
* [*subtitle/caption] ([`\--]): attaches a subtitle to the previous header, or caption to the previous object
* [*embed] ([`&]): embeds a referenced object. can be used to show images or repeat previously defined objects like lists or tables, optionally with a caption. an embed line can be followed immediately by a sequence of [*definitions] in the same way that resource definitions can, to override resource properties on a per-instance basis. note that only presentation-related properties like [$desc] can be meaningful overridden, as embed does not trigger a re-render of the parse tree; if you want to override e.g. context variables, use a multiline macro invocation instead.


** [`&[$image]] embeds an image or other block-level object. [!image] can be a reference with a url or file path, or it can be an embed section (e.g. for SVG files)
***[`&myimg All that remained of the unfortunate blood magic pageant contestants and audience (police photo)]
** [`&-[$ident] [$styled-text]] embeds a closed disclosure element containing the text of the named object (a nonprinting section or cortav resource should usually be used to store the content; it can also name an image or video, of course). in interactive outputs, this will display as a block which can be clicked on to view the full contents of the referenced object [$ident]; if [$styled-text] is present, it overrides the title of the section you are embedding (if any). in static outputs, the disclosure object will display as an enclosed box with [$styled-text] as the title text
*** [`&-ex-a Prosecution Exhibit A (GRAPHIC CONTENT)]
** [`&+[$section] [$styled-text]] is like the above, but the disclosure element is open by default
* [`$[$macro] [$arg1]|[$arg2]|[$argn]…] invokes a block-level macro with the supplied arguments, and can be followed by a property override definition list the same way embed and resource lines can. note that while both [`$[$id]] and [`&[$id]] can be used to instantiate resources of type [`text/x.cortav], there is a critical difference: [`$[$id]] renders out the sub-document separately each time it is named, allowing for parameter expansion and for context variables to be overridden for each invocation. by contrast, [`&[$id]] can only insert copies of the same render; no parameters can be passed and context variables will be expanded to their value at the time the resource was defined.
** [`$mymacro arg 1|arg 2|arg 3]
* [*horizontal rule] ([`\---]): inserts a horizontal rule or other context break; does not end the section. must be followed by newline. underlines can also be used in place of dashes ([`___], [`-_-], [`__-__-__] etc), as can horizontal unicode box drawing characters ([`─ ━ ┈] etc).
* [*page break] ([`\^^]): for formats that support pagination, like EPUB or HTML (when printed), indicates that the rest of the current page should be blank. for formats that do not, extra margins will be inserted. does not create a new section
* [*page rule] ([`\^-^]): inserts a page break for formats that support them, and a horizontal rule for formats that do not. does not create a new section. comprised of any number of horizontal rule characters surrounded by a pair of carets (e.g. [`^-^] [`^_^] [`^----^] [`^__--^] [`^┈┈┈┈┈^])
* [*table cells] ([`+ |]): see [>ex.tab table examples].
* [*equations] ([`=]): block-level equations can be inserted with the [`=] sequence
* [*cross-references] ([`=>] [`⇒]): inserts a block-level link. uses the same syntax as span links ([`⇒[$ident] [$styled-text]]). can be followed by a caption to add a longer descriptive text. especially useful for gemtext output. ident can be omitted to cross-reference, for example, a physical book.
* [*empty lines] (that is, lines consisting of nothing but whitespace) constitute a [!break], which terminates multiline objects that do not have a dedicated termination sequence, for example lists and asides.
................................................................................
*** [`image/*] (graphical outputs only)
*** [`video/*] (interactive outputs only)
*** [`image/svg+xml] is handled specially for HTML files, and may or may not be compatible with other renderer backends.
*** [`font/*] can be used with the HTML backend to reference a web font
*** [`font/woff2] can be used with the HTML backend to reference a web font
*** [`text/plain] (will be inserted as a preformatted text block)
*** [`text/css] (can be used when producing HTML files to link in an extra stylesheet, either by embedding it or referencing it from the header)
*** [`text/x.cortav] (will be parsed and inserted as a formatted text block; context variables can be passed to the file by setting [`.[$var]] properties on the resource, e.g. [`.recipient-name: Mr. Winthrop])
*** [`application/x-troff] can be used to supply sections of text written in raw [`groff] syntax. these are ignored by other renderers.
*** [`text/html] can be used to supply sections of text written in raw HTML. these are ignored by non-HTML outputs.
*** any MIME-type that matches the type of file being generated by the renderer can be used to include a block of data that will be passed directly to the renderer.
** URI types: additional URI types can be added by extensions or different implementations, but every compliant implementation must support these URIs.
*** [`http], [`https]/[`http+tls]: accesses resources over HTTP. add a [`file] fallback if possible for the benefit of renderers/viewers that do not have internet access abilities.
*** [`file]: references local files. (the meaning of "local" varies depending on the translation format.) absolute paths should begin [`file:/]; the slash should be omitted for relative paths. note that this doesn't have quite the same meaning as in HTML -- [`file] can (and usually should be) used with HTML outputs to refer to resources that reside on the same server. a cortav URI of [`file:/etc/passwd] will actually result in the link [`/etc/passwd], not [`file:///etc/passwd] when converted to HTML. generally, you only should use [`http] when you're referring to a resource that exists on a different domain. on systems where text and binary files are handled differently, the URIs [`file+txt:] and [`file+bin:] can be used to specify an opening mode.
*** [`asset]: identical to file [`file], except that paths are interpreted relative to the asset base (the parent directory of the source file if not otherwise defined), rather than the current working directory of the [`cortav] translator process.
................................................................................
	zombo: https://zombo.com
	any: anything you want
~~~

~~~ macros #mac [cortav] ~~~
the ranuir word {gloss cor|writing}…
	gloss: [*[#1]] “[#2]”

$def sur|n|socialism
$def par|n|speech
	def: * [*[#1]] [!([#2])]
		** [#3]

%% equivalent to

@def {
	* [*[#1]] [!([#2])]
	** [#3]
}
$def sur|n|socialism
$def par|n|speech

%% we could even do the same thing abusing context variables

@def {
	* [*[#word]] [!([#pos])]
	** [#meaning]
}

$def
	.word: sur
	.pos: n
	.meaning: socialism
$def
	.word: par
	.pos: n
	.meaning: speech

%% context variables are useful because they inherit from the enclosing context
%% thus, we can exploit resource syntax to create templates with default values

@agent {
	+ CODENAME :| [#1]
	+ CIVILIAN IDENTITY :| [#civil]
	+ RULES of ENGAGEMENT :| [#roe]
	+ DANGER LEVEL :| [#danger]
}
	.civil: (unknown)
	.roe: Monitor; do not engage
	.danger: (unknown)

$agent ZUCCHINI PARABLE
	.civil: Zephram "Rolodex" Goldberg
	.danger: Category Scarlet
$agent RHADAMANTH EXQUISITE
	.roe: Eliminate with extreme prejudice; CBRN deployment authorized
	.danger: [*Unquantifiable]
~~~

~~~ tables #tab [cortav] ~~~
here is a glossary table.

+ english :+ ranuir + zia ţai  + thaliste        +
| honor   :| tef    | pang     | mbecheve        |

Modified cortav.lua from [7f118fbbfd] to [827b243474].

282
283
284
285
286
287
288







289
290
291
292
293
294
295
....
1107
1108
1109
1110
1111
1112
1113
1114



1115
1116
1117
1118
1119
1120
1121
1122
1123
....
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309

1310
1311
1312
1313
1314
1315
1316
....
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
....
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556




1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
....
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588

1589
1590

1591
1592
1593
1594
1595

1596
1597
1598
1599
1600
1601
1602
1603
1604
				if sp == nil then
					if test then return false else return '' end
				else
					return sp
				end
			elseif self.vars[var] then
				return self.vars[var]







			else
				local sp = scanParents(var)
				if sp then return sp end
				if test then return false end
				return '' -- is this desirable behavior?
			end
		end;
................................................................................
	end};
	{seq = '\t', pred = function(l)
		return (l:match '\t+([^:]+):%s*(.*)$')
	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



			last.props[ref] = val
			j:hook('rsrc_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
		else
			c.sec.refs[ref] = val
		end
................................................................................
				open = brak;
				close = mirror(brak);
			}
			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)
			else
				c.sec.refs[id] = rsrc
			end
		end
		table.insert(d, rsrc)
		j:hook('block_insert', c, rsrc, s)
		if id == '' then --shorthand syntax
			local embed = {
				kind = 'embed';
				rsrc = rsrc;
				origin = c;

			}
			table.insert(d, embed)
			j:hook('block_insert', c, embed, s)
		end

		if brak then
			c.mode = {
................................................................................
			local mf = job:proc('modes', ctx.mode.kind)
			if not mf then
				ctx:fail('unimplemented syntax mode %s', ctx.mode.kind)
			end
			mf(job, ctx, l, dest) --NOTE: you are responsible for triggering the appropriate hooks if you insert anything!
		end
	else
		if 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
						i.fn(l, ctx, job, dest, ...)
						return true
					end
................................................................................
							r.origin:fail('resource “%s” is not inline and supplies no URI',
											  r.id or "(anonymous)")
						end

						-- 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
							end
						end
					end
					table.insert(srcs, resource)
				end
				r.srcs = srcs
				-- note that resources do not themselves have kinds. when a
				-- document requests to insert a resource, the renderer must
................................................................................
		end
	end

	-- 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)
				if not mac then
					r.origin:fail('no such reference or resource “%s”', r.macro)
				end

				local subdoc, subctx = ctx.doc:sub(mc)
				local rawbody


				if type(mac) == 'string' then
					rawbody = mac
				elseif mac.raw then
					rawbody = mac.raw

				else
					r.origin: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
					ct.parse_line(ln, subctx, subctx.sec.blocks)
				end
				r.doc = subdoc







>
>
>
>
>
>
>







 







|
>
>
>

|







 







<
<










|




>







 







|







 







|
<
|
>
>
>
>
|
|
|
|
|
|
<







 







|
<
|

|

>


>





>

|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
....
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
....
1296
1297
1298
1299
1300
1301
1302


1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
....
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
....
1556
1557
1558
1559
1560
1561
1562
1563

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574

1575
1576
1577
1578
1579
1580
1581
....
1587
1588
1589
1590
1591
1592
1593
1594

1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
				if sp == nil then
					if test then return false else return '' end
				else
					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
				return '' -- is this desirable behavior?
			end
		end;
................................................................................
	end};
	{seq = '\t', pred = function(l)
		return (l:match '\t+([^:]+):%s*(.*)$')
	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'
		         or last.kind == 'embed'
               or last.kind == 'macro' then
			last.props = last.props or {}
			last.props[ref] = val
			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
		else
			c.sec.refs[ref] = val
		end
................................................................................
				open = brak;
				close = mirror(brak);
			}
			rsrc.raw = '';
			if src == nil then
				rsrc.props.src = 'text/x.cortav'
			end


		end
		if id then
			if c.sec.refs[id] then
				c:fail('an object with id “%s” already exists in that section',id)
			else
				c.sec.refs[id] = rsrc
			end
		end
		table.insert(d, rsrc)
		j:hook('block_insert', c, rsrc, s)
		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

		if brak then
			c.mode = {
................................................................................
			local mf = job:proc('modes', ctx.mode.kind)
			if not mf then
				ctx:fail('unimplemented syntax mode %s', ctx.mode.kind)
			end
			mf(job, ctx, l, dest) --NOTE: you are responsible for triggering the appropriate hooks if you insert anything!
		end
	else
		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
						i.fn(l, ctx, job, dest, ...)
						return true
					end
................................................................................
							r.origin:fail('resource “%s” is not inline and supplies no URI',
											  r.id or "(anonymous)")
						end

						-- 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 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
				r.srcs = srcs
				-- note that resources do not themselves have kinds. when a
				-- document requests to insert a resource, the renderer must
................................................................................
		end
	end

	-- 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

				local mac = mc:ref(r.macro)
				if not mac then
					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
					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
					ct.parse_line(ln, subctx, subctx.sec.blocks)
				end
				r.doc = subdoc

Modified render/html.lua from [14fa0c3d9d] to [84a861628f].

853
854
855
856
857
858
859






860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
...
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
				elseif s.mode == 'embed' then
					local mime = s.mime:clone()
					mime.opts = {}
					return string.format('data:%s;base64,%s', mime, ss.str.b64e(s.raw))
				end
			end
			--figure out how to embed the given object






			local embedActs = {
				{ss.mime'image/*',       function(s,ctr)
					if s == nil then
						return {tag = "picture", nodes = {}}
					else
						local uri = uriForSource(s)
						local fbimg, idx
						if next(ctr.nodes) == nil then
							idx = 1
							fbimg = {
								elt = 'img'; --fallback
								attrs = {
									alt = obj.props.desc or obj.props.detail or '';
									title = obj.props.detail;
									src = uri;
									width = obj.props.width;
									height = obj.props.height;
								};
							}
						else idx = #ctr.nodes end
						table.insert(ctr.nodes, idx, {
							elt = 'source'; --fallback
							attrs = { srcset = uri; };
						})
................................................................................
			local top = rtype[2]() -- create container
			for n, src in ipairs(obj.srcs) do
				if rtype[1] < src.mime then
					rtype[2](src, top)
				end
			end
			local ft = flatten(top)
			local cap = b.cap or obj.props.desc or obj.props.detail
			if b.mode == 'inline' then
				-- TODO insert caption
				return ft
			else
				local prop = {}
				if b.mode == 'open' then
					prop.open = true







>
>
>
>
>
>












|
|

|
|







 







|







853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
...
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
				elseif s.mode == 'embed' then
					local mime = s.mime:clone()
					mime.opts = {}
					return string.format('data:%s;base64,%s', mime, ss.str.b64e(s.raw))
				end
			end
			--figure out how to embed the given object
			local function P(p) -- get prop
				if b.props and b.props[p] then
					return b.props[p]
				end
				return obj.props[p]
			end
			local embedActs = {
				{ss.mime'image/*',       function(s,ctr)
					if s == nil then
						return {tag = "picture", nodes = {}}
					else
						local uri = uriForSource(s)
						local fbimg, idx
						if next(ctr.nodes) == nil then
							idx = 1
							fbimg = {
								elt = 'img'; --fallback
								attrs = {
									alt = P'desc' or P'detail' or '';
									title = P'detail';
									src = uri;
									width = P'width';
									height = P'height';
								};
							}
						else idx = #ctr.nodes end
						table.insert(ctr.nodes, idx, {
							elt = 'source'; --fallback
							attrs = { srcset = uri; };
						})
................................................................................
			local top = rtype[2]() -- create container
			for n, src in ipairs(obj.srcs) do
				if rtype[1] < src.mime then
					rtype[2](src, top)
				end
			end
			local ft = flatten(top)
			local cap = b.cap or P'desc' or P'detail'
			if b.mode == 'inline' then
				-- TODO insert caption
				return ft
			else
				local prop = {}
				if b.mode == 'open' then
					prop.open = true