cortav  Check-in [dd5c3bfcb9]

Overview
Comment:various improvements
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: dd5c3bfcb91d4ab9aa0c1579329e6e81dd5ce90cf53111b078a729b07a1cd405
User & Date: lexi on 2022-09-14 12:22:00
Other Links: manifest | tags
Context
2022-09-30
18:57
"fix" macro bullshit check-in: 84b6c875fb user: lexi tags: trunk
2022-09-14
12:22
various improvements check-in: dd5c3bfcb9 user: lexi tags: trunk
2022-09-10
19:14
tweak docs check-in: 5a78370f0f user: lexi tags: trunk
Changes

Modified cli.lua from [6b3b695c7e] to [9a8697d2cc].

30
31
32
33
34
35
36




37

38
39
40
41
42
43
44
	end

	if not mode['render:format'] then
		error 'what output format should i translate the input to?'
	end
	if mode['render:format'] == 'none' then return 0 end
	if not ct.render[mode['render:format']] then




		ct.exns.unimpl('output format “%s” unsupported', mode['render:format']):throw()

	end
	
	local render_opts = ss.kmap(function(k,v)
		return k:sub(2+#mode['render:format'])
	end, ss.kfilter(mode, function(m)
		return ss.str.begins(m, mode['render:format']..':')
	end))







>
>
>
>
|
>







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	end

	if not mode['render:format'] then
		error 'what output format should i translate the input to?'
	end
	if mode['render:format'] == 'none' then return 0 end
	if not ct.render[mode['render:format']] then
		if (not ct.render.html) and not _G.native then
			-- we may be running uncompiled; otherwise something is seriously broken
			require('render.' .. mode['render:format'])
		else
			ct.exns.unimpl('output format “%s” unsupported', mode['render:format']):throw()
		end
	end
	
	local render_opts = ss.kmap(function(k,v)
		return k:sub(2+#mode['render:format'])
	end, ss.kfilter(mode, function(m)
		return ss.str.begins(m, mode['render:format']..':')
	end))

Modified cortav.ct from [5152d1b5b1] to [607ec9b33c].







1
2
3
4
5
6
7
8
9
10
..
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
...
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
...
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776






# cortav specification
[*cortav] is a markup language designed to be a simpler, but more capable alternative to markdown. its name derives from the [>dict Ranuir words] [!cor] "writing" and [!tav] "document", translating to something like "(plain) text document".

	dict: http://ʞ.cc/fic/spirals/glossary

the cortav [!format] can be called [!cortavgil], or [!gil cortavi], to differentiate it from the reference implementation [!cortavsir] or [!sir cortavi].

%toc

## cortav vs. markdown
................................................................................
* level 1: [*styling]. simple inline formatting sequences like strong, emphatic, literal, links, etc. math equation styling need not be supported. paragraphs, lists, and references are the only block elements supported. suitable for styling tweets and other very short content.
* level 2: [*layout]. implements header, paragraph, newline, directive, and reference block elements. supports resources at least for remote or attached images. suitable for longer social media posts.
* level 3: [*publishing]. implements all currently standardized core behavior, including zero or more extensions.
* level 4: [*reference]. implements all currently standardized behavior, including [!all] standardized extensions.

! note that which translators are implemented is not specified by level, as this is, naturally, implementation-dependent. (it would make rather little sense for the blurb parser of a cortav-enabled blog engine to support generating PDFs, after all.) level encodes only which features of the cortav [!language] are supported.

##onblocks structure
cortav is based on an HTML-like block model, where a document consists of sections, which are made up of blocks, which may contain a sequence of spans. flows of text are automatically conjoined into spans, and blocks are separated by one or more newlines. this means that, unlike in markdown, a single logical paragraph [*cannot] span multiple ASCII lines. the primary purpose of this was to ensure ease of parsing, but also, both markdown and cortav are supposed to be readable from within a plain text editor. this is the 21st century. every reasonable text editor supports soft word wrap, and if yours doesn't, that's entirely your own damn fault. hard-wrapping lines is incredibly user-hostile, especially to users on mobile devices with small screens. cortav does not allow it.

the first character(s) of every line (the "control sequence") indicates the role of that line. if no control sequence is recognized, the line is treated as a paragraph. the currently supported control sequences are listed below. some control sequences have alternate forms, in order to support modern, readable unicode characters as well as plain ascii text.

* [*paragraphs] ([`.] [` ¶] [`❡]): a paragraph is a simple block of text. the period control sequence is only necessary if the paragraph text starts with text that would be interpreted as a control sequence otherwise
* [*newlines] [` \\]: inserts a line break into previous paragraph and attaches the following text. mostly useful for poetry or lyrics
* [*section starts] [`#] [`§]: starts a new section. all sections have an associated depth, determined by the number of sequence repetitions (e.g. "###" indicates depth three). sections may have headers and IDs; both are optional. IDs, if present, are a sequence of raw-text immediately following the hash marks. if the line has one or more space character followed by styled-text, a header will be attached. the character immediately following the hashes can specify a particular type of section. e.g.:
** [`#] is a simple section break.
** [`#anchor] opens a new section with the ID [`anchor].
** [`# header] opens a new section with the title "header".
** [`#anchor header] opens a new section with both the ID [`anchor] and the title "header".
* [*nonprinting sections] ([`^]): sometimes, you'll want to create a namespace without actually adding a visible new section to the document. you can achieve this by creating a [!nonprinting section] and defining resources within it. nonprinting sections can also be used to store comments, notes, to-dos, or other meta-information that is useful to have in the source file without it becoming a part of the output. nonprinting sections can be used for a sort of "literate markup," where resource and reference definitions can intermingle with human-readable narrative about those definitions.
* [*resource] ([`@]): defines a [!resource]. a resource is a file or object that is to be embedded in the document somehow. common examples of resources include images, videos, iframes, or headers/footers. resources can be defined inline, or reference external objects. see [>rsrc resources] for more information.
* [*lists] ([`*] [`:]): these are like paragraph nodes, but list nodes that occur next to each other will be arranged so as to show they compose a sequence. depth is determined by the number of stars/colons. like headers, a list entry may have an ID that can be used to refer back to it; it is indicated in the same way. if colons are used, this indicates that the order of the items is signifiant. [`:]-lists and [`*]-lists may be intermixed; however, note than only the last character in the sequence actually controls the type. a blank line terminates the current list.
* [*directives] ([`%]): a directive issues a hint to the renderer in the form of an arbitrary string. directives are normally ignored if they are not supported, but you may cause a warning to be emitted where the directive is not supported with [`%!] or mark a directive critical with [`%!!] so that rendering will entirely fail if it cannot be obeyed.
* [*comments] ([`%%]): a comment is a line of text that is simply ignored by the renderer.
* [*asides] ([`!]): indicates text that diverges from the narrative, and can be skipped without interrupting it. think of it like block-level parentheses. asides which follow one another are merged as paragraphs of the same aside, usually represented as a sort of box. if the first line of an aside contains a colon, the stretch of styled-text from the beginning to the aside to the colon will be treated as a "type heading," e.g. "Warning:"
* [*code] ([`~~~]): a line beginning with ~~~ begins or terminates a block of code. code blocks are by default not parsed, but parsing can be activated by preceding the code block with an [`%[*expand]] directive. the opening line should look like one of the below
** [`~~~]
** [`~~~ language] (markdown-style shorthand syntax)
................................................................................
** [`~~~ 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. only [`&[$id]] can instantiate resources of types other than [`text/x.cortav]. there is also a semantic distinction: resources interpreted as macros are inserted "in-band", on an equal basis with nearby elements; resources interpreted as embeds are set off to clearly indicate that they are a sub-document, and on interactive outputs may have their own independently-scrolling viewport.
................................................................................
* [*table cells] ([`+ |]): see [>ex.tab table examples].
* [*equations] ([`=]): block-level equations can be inserted with the [`=] sequence
* [*cross-references] ([`=>] [`⇒]): inserts a block-level link. has two forms for the sake of gemtext compatibility. [$styled-text] is a descriptive text of the destination. especially useful for menus and gemtext output.
** the cortav syntax is [`=>[$ident] [$styled-text]], where [$ident] is an identifier; links to the same destination as [`\[>[$ident] [$styled-text]\]] would
** the compatibility syntax is [`=> [$uri] [$styled-text]] (note the space before [$uri]!). instead of taking an identifier for an object in the document, it directly accepts a URI. note that this is not formally equivalent to gemtext's link syntax, which also allows paths in place of URIs; [`cortav] does not. the gemtext line ["=> /somewhere] would need to be expressed as ["=> file:/somewhere], and ["=> /somewhere?key=val] as ["http:/somewhere?key=val] (or ["gemini:/somewhere?key=val], if the result is to be served over a gemini server).
* [*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.

##onspans styled text
most blocks contain a sequence of spans. these spans are produced by interpreting a stream of [*styled-text] following the control sequence. styled-text is a sequence of codepoints potentially interspersed with escapes. an escape is formed by an open square bracket [`\[] followed by a [*span control sequence], and arguments for that sequence like more styled-text. escapes can be nested.

* strong {obj *|styled-text}: causes its text to stand out from the narrative, generally rendered as bold or a brighter color.
* emphatic {obj !|styled-text}: indicates that its text should be spoken with emphasis, generally rendered as italics
* custom style {span .|id|[$styled-text]}: applies a specially defined font style. for example, if you have defined [`caution] to mean "demibold italic underline", cortav will try to apply the proper weight and styling within the constraints of the current font to the span [$styled-text]. see the [>fonts-sty fonts section] for more information about this mechanism.
* literal {obj `|styled-text}: indicates that its text is a reference to a literal sequence of characters or other discrete token. generally rendered in monospace
* variable {obj $|styled-text}: indicates to the reader that its text is a placeholder, rather than a literal representation. generally rendered in italic monospace, ideally of a different color
................................................................................
* raw {obj \\ |[$raw-text]}: causes all characters within to be interpreted literally, without expansion. the only special characters are square brackets, which must have a matching closing bracket, and backslashes.
* raw literal [` \["[$raw-text]\]]: shorthand for a raw inside a literal, that is ["[`[\\…]]]
* macro [` \{[$name] [$arguments]}]: invokes a [>ex.mac macro] inline, specified with a reference. if the result of macro expansion contains newlines, they will be treated as line breaks, rather than paragraph breaks as they would be in a multiline context.
* argument {obj #|var}: in macros only, inserts the [$var]-th argument. otherwise, inserts a context variable provided by the renderer.
* raw argument {obj ##|var}: like above, but does not evaluate [$var].
* term {obj &|name}, {span &|name|[$expansion]}: quotes a defined term with a link to its definition, optionally with a custom expansion of the term (for instance, to expand the first use of an acronym)
* inline image {obj &@|name}: shows a small image or other object inline. the unicode character [`🖼] can also be used instead of [`&@].
* unicode codepoint {obj U+|hex-integer}: inserts an arbitrary UCS codepoint in the output, specified by [$hex-integer]. lowercase [`u] is also legal.
* math mode {obj =|equation}: activates additional transformations on the span to format it as a mathematical equation; e.g. [`*] becomes [`×] and [`/] --> [`÷].
* extension {span %|ext|…}: invokes extension named in [$ext]. [$ext] will usually be an extension name followed by a symbol (often a period) and then an extension-specific directive, although for some simple extensions it may just be the plain extension name. further syntax and semantics depend on the extension. this syntax can also be used to apply formatting specific to certain renderers, such as assigning a CSS class in the [`html] renderer (["[%html.myclass my [!styled] text]]).
* critical extension {span %!|ext|…}: like [!extension], but will trigger an error if the requested extension is not available

* extension text {span %:|ext|[$styled-text]}: like [!extension], but when the requested extension is not present, [$styled-text] wlil be emitted as-is. this is a better way to apply CSS classes, as the text will still be visible when rendered to formats other than HTML.
* inline comment {obj %%|...}: ignored. useful for editorial annotations not intended to be part of the rendered product.

	span: [` \[[*[#1]][$[#2]] [#3]\]]
	obj: [` \[[*[#1]][$[#2]]\]]

##tabs tables
................................................................................
***: [*heading]: the section can occur on the same page as text and  headings from other sections
** {d pragma accent} specifies an accent hue (in degrees around the color wheel) for renderers which support colorized output
** {d pragma accent-spread} is a factor that controls the "spread" of hues used in the document. if 0, only the accent color will be used; if larger, other hues will be used in addition to the primary accent color.
** {d pragma dark-on-light on\|off} controls whether the color scheme used should be light-on-dark or dark-on-light
** {d pragma page-width} indicates how wide the pages should be
** {d pragma title-page} specifies a section to use as a title page, for renderer backends that support pagination

! note on pragmata: particularly when working with collections of documents, you should not keep formatting metadata in the documents themselves! the best thing to do is to have a makefile for compiling the documents using whatever tools you want to support, and encoding the rendering options in this file (for the reference implementation this currently means as command line arguments, but eventually it will support intent files as well) so they can all be changed in one place; pragmas should instead be used for per-document [*overrides] of default settings.
! a workaround for the lack of intent files in the reference implementation is to have a single pseudo-stylesheet that contains only {d pragma} statements, and then import this file from each individual source file using the {d include} directive. this is suboptimal and recommended only when you need to ensure compatibility between different implementations.
! when creating HTML files, an even better alternative may be to turn off style generation entirely and link in an external, hand-written CSS stylesheet. this is generally the way you should compile sources for existing websites if you aren't going to write your own extension.

##ex examples

~~~ blockquotes #bq [cortav] ~~~
the following excerpts of text were recovered from a partially erased hard drive found in the Hawthorne manor in the weeks after the Incident. context is unknown.

#>
—spoke to the man under the bridge again, the one who likes to bite the heads off the fish, and he suggested i take a brief sabbatical and journey to the Wandering Oak (where all paths meet) in search of inspiration and the forsaken sword of Pirate Queen Granuaile. a capital idea! i shall depart upon the morrow, having honored the Lord Odin and poisoned my accursed minstrels as is tradition—
—can't smell my soul anymore, but that's beside the point entirely—
—that second moon (always have wondered why nobody else seems to notice the damn fool thing except on Michaelmas day). alas, my luck did not endure, and i was soon to find myself knee-deep in—
—just have to see about that, won't we!—
#

the nearest surviving relative of Lord Hawthorne is believed to be a wandering beggar with a small pet meerkat who sells cursed wooden trinkets to unwary children. she will not be contacted, as the officers of the Yard fear her.
~~~

~~~links & notes #lnr [cortav] ~~~
this sentence contains a [>zombo link] to zombo com. you can do anything[^any] at zombo com.
	zombo: https://zombo.com
................................................................................
	.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.

................................................................................
the interpreter should provide a [`cortav] table with the objects:
* [`ctx]: contains context variables

used files should return a table with the following members
* [`macros]: an array of functions that return strings or arrays of strings when invoked. these will be injected into the global macro namespace.

###ts ts
the [*ts] extension allows documents to be marked up for basic classification constraints and automatically redacted. if you are seriously relying on [`ts] for confidentiality, make damn sure you start the file with [$%[*requires] ts], so that rendering will fail with an error if the extension isn't supported.

[`ts] currently has no support for misinformation.

[`ts] enables the directives:
* [`%[*ts] class [$scope level] ([$styled-text])]: indicates a classification level for either the whole document (scope [$doc]) or the next section (scope [$sec]). if the ts level is below [$level], the section will be redacted or rendering will fail with an error, as appropriate. if styled-text is included, this will be treated as the name of the classification level.
* [`%[*ts] word [$scope word] ([$styled-text])]: indicates a codeword clearance that must be present for the text to render. if styled-text is present, this will be used to render the name of the codeword instead of [$word].
* [`%[*when] ts level [$level]]
>
>
>
>
>
>

|
<







 







|











|
|







 







|
|







 







|







 







|


|
>







 







|








<
|
|
|
|
<







 







|







 







|







1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
..
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
...
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606

607
608
609
610
611
612
613
...
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
...
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
%% this is the reference specification that i used to initially cobble together my
%% spec for the language i was going to implement, and which i then expanded
%% as i added features to the reference implementation. it's a mess and it
%% urgently needs to be rewritten into a more accessible and navigable
%% document for new users. TODO

# cortav specification
[*cortav] is a markup language designed to be a simpler, [!well-specified], and more capable alternative to markdown. its name derives from the [>dict Ranuir words] [!cor] "writing" and [!tav] "document", translating to something like "(plain) text document".

	dict: http://ʞ.cc/fic/spirals/glossary

the cortav [!format] can be called [!cortavgil], or [!gil cortavi], to differentiate it from the reference implementation [!cortavsir] or [!sir cortavi].

%toc

## cortav vs. markdown
................................................................................
* level 1: [*styling]. simple inline formatting sequences like strong, emphatic, literal, links, etc. math equation styling need not be supported. paragraphs, lists, and references are the only block elements supported. suitable for styling tweets and other very short content.
* level 2: [*layout]. implements header, paragraph, newline, directive, and reference block elements. supports resources at least for remote or attached images. suitable for longer social media posts.
* level 3: [*publishing]. implements all currently standardized core behavior, including zero or more extensions.
* level 4: [*reference]. implements all currently standardized behavior, including [!all] standardized extensions.

! note that which translators are implemented is not specified by level, as this is, naturally, implementation-dependent. (it would make rather little sense for the blurb parser of a cortav-enabled blog engine to support generating PDFs, after all.) level encodes only which features of the cortav [!language] are supported.

##onblocks structure (block elements)
cortav is based on an HTML-like block model, where a document consists of sections, which are made up of blocks, which may contain a sequence of spans. flows of text are automatically conjoined into spans, and blocks are separated by one or more newlines. this means that, unlike in markdown, a single logical paragraph [*cannot] span multiple ASCII lines. the primary purpose of this was to ensure ease of parsing, but also, both markdown and cortav are supposed to be readable from within a plain text editor. this is the 21st century. every reasonable text editor supports soft word wrap, and if yours doesn't, that's entirely your own damn fault. hard-wrapping lines is incredibly user-hostile, especially to users on mobile devices with small screens. cortav does not allow it.

the first character(s) of every line (the "control sequence") indicates the role of that line. if no control sequence is recognized, the line is treated as a paragraph. the currently supported control sequences are listed below. some control sequences have alternate forms, in order to support modern, readable unicode characters as well as plain ascii text.

* [*paragraphs] ([`.] [` ¶] [`❡]): a paragraph is a simple block of text. the period control sequence is only necessary if the paragraph text starts with text that would be interpreted as a control sequence otherwise
* [*newlines] [` \\]: inserts a line break into previous paragraph and attaches the following text. mostly useful for poetry or lyrics
* [*section starts] [`#] [`§]: starts a new section. all sections have an associated depth, determined by the number of sequence repetitions (e.g. "###" indicates depth three). sections may have headers and IDs; both are optional. IDs, if present, are a sequence of raw-text immediately following the hash marks. if the line has one or more space character followed by styled-text, a header will be attached. the character immediately following the hashes can specify a particular type of section. e.g.:
** [`#] is a simple section break.
** [`#anchor] opens a new section with the ID [`anchor].
** [`# header] opens a new section with the title "header".
** [`#anchor header] opens a new section with both the ID [`anchor] and the title "header".
* [*nonprinting sections] ([`^]): sometimes, you'll want to create a namespace without actually adding a visible new section to the document. you can achieve this by creating a [!nonprinting section] and defining resources within it. nonprinting sections can also be used to store comments, notes, to-dos, or other meta-information that is useful to have in the source file without it becoming a part of the output. nonprinting sections can be used for a sort of "literate markup," where resource and reference definitions can intermingle with human-readable narrative about those definitions. note that unlike comments, nonprinting sections are still parsed and can still affect other sections by means of definitions and pragmata.
* [*resource] ([`@]): defines a [!resource]. a resource is a file or object that is to be embedded in the document somehow. common examples of resources include images, videos, iframes, or headers/footers. resources can be defined inline, or reference external objects that are read in either at compile-time or view-time. see [>rsrc resources] for more information.
* [*lists] ([`*] [`:]): these are like paragraph nodes, but list nodes that occur next to each other will be arranged so as to show they compose a sequence. depth is determined by the number of stars/colons. like headers, a list entry may have an ID that can be used to refer back to it; it is indicated in the same way. if colons are used, this indicates that the order of the items is signifiant. [`:]-lists and [`*]-lists may be intermixed; however, note than only the last character in the sequence actually controls the type. a blank line terminates the current list.
* [*directives] ([`%]): a directive issues a hint to the renderer in the form of an arbitrary string. directives are normally ignored if they are not supported, but you may cause a warning to be emitted where the directive is not supported with [`%!] or mark a directive critical with [`%!!] so that rendering will entirely fail if it cannot be obeyed.
* [*comments] ([`%%]): a comment is a line of text that is simply ignored by the renderer.
* [*asides] ([`!]): indicates text that diverges from the narrative, and can be skipped without interrupting it. think of it like block-level parentheses. asides which follow one another are merged as paragraphs of the same aside, usually represented as a sort of box. if the first line of an aside contains a colon, the stretch of styled-text from the beginning to the aside to the colon will be treated as a "type heading," e.g. "Warning:"
* [*code] ([`~~~]): a line beginning with ~~~ begins or terminates a block of code. code blocks are by default not parsed, but parsing can be activated by preceding the code block with an [`%[*expand]] directive. the opening line should look like one of the below
** [`~~~]
** [`~~~ language] (markdown-style shorthand syntax)
................................................................................
** [`~~~ 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] ([`>[$id] [$body]]): "inline" blockquote syntax. can be nested by repeating the [`>] character. the [$id] is optional, but the [`>] character must be immediately followed by whitespace if the block is not to have an ID.
* [*subtitle/caption] (["--]): attaches a subtitle to the previous header, or caption to the previous object. after a blockquote, attaches an attribution line
* [*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. only [`&[$id]] can instantiate resources of types other than [`text/x.cortav]. there is also a semantic distinction: resources interpreted as macros are inserted "in-band", on an equal basis with nearby elements; resources interpreted as embeds are set off to clearly indicate that they are a sub-document, and on interactive outputs may have their own independently-scrolling viewport.
................................................................................
* [*table cells] ([`+ |]): see [>ex.tab table examples].
* [*equations] ([`=]): block-level equations can be inserted with the [`=] sequence
* [*cross-references] ([`=>] [`⇒]): inserts a block-level link. has two forms for the sake of gemtext compatibility. [$styled-text] is a descriptive text of the destination. especially useful for menus and gemtext output.
** the cortav syntax is [`=>[$ident] [$styled-text]], where [$ident] is an identifier; links to the same destination as [`\[>[$ident] [$styled-text]\]] would
** the compatibility syntax is [`=> [$uri] [$styled-text]] (note the space before [$uri]!). instead of taking an identifier for an object in the document, it directly accepts a URI. note that this is not formally equivalent to gemtext's link syntax, which also allows paths in place of URIs; [`cortav] does not. the gemtext line ["=> /somewhere] would need to be expressed as ["=> file:/somewhere], and ["=> /somewhere?key=val] as ["http:/somewhere?key=val] (or ["gemini:/somewhere?key=val], if the result is to be served over a gemini server).
* [*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.

##onspans styled text (span elements)
most blocks contain a sequence of spans. these spans are produced by interpreting a stream of [*styled-text] following the control sequence. styled-text is a sequence of codepoints potentially interspersed with escapes. an escape is formed by an open square bracket [`\[] followed by a [*span control sequence], and arguments for that sequence like more styled-text. escapes can be nested.

* strong {obj *|styled-text}: causes its text to stand out from the narrative, generally rendered as bold or a brighter color.
* emphatic {obj !|styled-text}: indicates that its text should be spoken with emphasis, generally rendered as italics
* custom style {span .|id|[$styled-text]}: applies a specially defined font style. for example, if you have defined [`caution] to mean "demibold italic underline", cortav will try to apply the proper weight and styling within the constraints of the current font to the span [$styled-text]. see the [>fonts-sty fonts section] for more information about this mechanism.
* literal {obj `|styled-text}: indicates that its text is a reference to a literal sequence of characters or other discrete token. generally rendered in monospace
* variable {obj $|styled-text}: indicates to the reader that its text is a placeholder, rather than a literal representation. generally rendered in italic monospace, ideally of a different color
................................................................................
* raw {obj \\ |[$raw-text]}: causes all characters within to be interpreted literally, without expansion. the only special characters are square brackets, which must have a matching closing bracket, and backslashes.
* raw literal [` \["[$raw-text]\]]: shorthand for a raw inside a literal, that is ["[`[\\…]]]
* macro [` \{[$name] [$arguments]}]: invokes a [>ex.mac macro] inline, specified with a reference. if the result of macro expansion contains newlines, they will be treated as line breaks, rather than paragraph breaks as they would be in a multiline context.
* argument {obj #|var}: in macros only, inserts the [$var]-th argument. otherwise, inserts a context variable provided by the renderer.
* raw argument {obj ##|var}: like above, but does not evaluate [$var].
* term {obj &|name}, {span &|name|[$expansion]}: quotes a defined term with a link to its definition, optionally with a custom expansion of the term (for instance, to expand the first use of an acronym)
* inline image {obj &@|name}: shows a small image or other object inline. the unicode character [`🖼] can also be used instead of [`&@].
* unicode codepoint {obj U|hex-integer}: inserts an arbitrary UCS codepoint in the output, specified by [$hex-integer]. lowercase [`u] is also legal, as are [`U+] and [`u+].
* math mode {obj =|equation}: activates additional transformations on the span to format it as a mathematical equation; e.g. [`*] becomes [`×] and [`/] --> [`÷].
* extension {span %|ext|…}: invokes extension named in [$ext]. [$ext] will usually be an extension name followed by a symbol (often a period) and then an extension-specific directive, although for some simple extensions it may just be the plain extension name. further syntax and semantics depend on the extension. this syntax can also be used to apply formatting specific to certain renderers, such as assigning a CSS class in the [`html] renderer (["[%html.myclass my [!styled] text]]).
* important extension {span %!|ext|…}: like [!extension], but will issue a warning if the requested extension is not available
* critical extension {span %!!|ext|…}: like [!important extension], but will trigger an error and abort compilation if the requested extension is not available
* extension text {span %:|ext|[$styled-text]}: like [!extension], but when the requested extension is not present, [$styled-text] wlil be emitted as-is. this is a better way to apply CSS classes, as the text will still be visible when rendered to formats other than HTML.
* inline comment {obj %%|...}: ignored. useful for editorial annotations not intended to be part of the rendered product.

	span: [` \[[*[#1]][$[#2]] [#3]\]]
	obj: [` \[[*[#1]][$[#2]]\]]

##tabs tables
................................................................................
***: [*heading]: the section can occur on the same page as text and  headings from other sections
** {d pragma accent} specifies an accent hue (in degrees around the color wheel) for renderers which support colorized output
** {d pragma accent-spread} is a factor that controls the "spread" of hues used in the document. if 0, only the accent color will be used; if larger, other hues will be used in addition to the primary accent color.
** {d pragma dark-on-light on\|off} controls whether the color scheme used should be light-on-dark or dark-on-light
** {d pragma page-width} indicates how wide the pages should be
** {d pragma title-page} specifies a section to use as a title page, for renderer backends that support pagination

! note on pragmata: particularly when working with collections of documents, you should not keep shared formatting metadata duplicated across the documents themselves! the best thing to do is to have a makefile for compiling the documents using whatever tools you want to support, and encoding the rendering options in this file (for the reference implementation this currently means as command line arguments, but eventually it will support intent files as well) so they can all be changed in one place; pragmas should instead be used for per-document [*overrides] of default settings.
! a workaround for the lack of intent files in the reference implementation is to have a single pseudo-stylesheet that contains only {d pragma} statements, and then import this file from each individual source file using the {d include} directive. this is suboptimal and recommended only when you need to ensure compatibility between different implementations.
! when creating HTML files, an even better alternative may be to turn off style generation entirely and link in an external, hand-written CSS stylesheet. this is generally the way you should compile sources for existing websites if you aren't going to write your own extension.

##ex examples

~~~ blockquotes #bq [cortav] ~~~
the following excerpts of text were recovered from a partially erased hard drive found in the Hawthorne manor in the weeks after the Incident. context is unknown.


> —spoke to the man under the bridge again, the one who likes to bite the heads off the fish, and he suggested i take a brief sabbatical and journey to the Wandering Oak (where all paths meet) in search of inspiration and the forsaken sword of Pirate Queen Granuaile. a capital idea! i shall depart upon the morrow, having honored the Lord Odin and poisoned my accursed minstrels as is tradition—
> —can't smell my soul anymore, but that's beside the point entirely—
> —that second moon (always have wondered why nobody else seems to notice the damn fool thing except on Michaelmas day). alas, my luck did not endure, and i was soon to find myself knee-deep in—
> —just have to see about that, won't we!—


the nearest surviving relative of Lord Hawthorne is believed to be a wandering beggar with a small pet meerkat who sells cursed wooden trinkets to unwary children. she will not be contacted, as the officers of the Yard fear her.
~~~

~~~links & notes #lnr [cortav] ~~~
this sentence contains a [>zombo link] to zombo com. you can do anything[^any] at zombo com.
	zombo: https://zombo.com
................................................................................
	.civil: (unknown)
	.roe: Monitor; do not engage
	.danger: (unknown)

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

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

................................................................................
the interpreter should provide a [`cortav] table with the objects:
* [`ctx]: contains context variables

used files should return a table with the following members
* [`macros]: an array of functions that return strings or arrays of strings when invoked. these will be injected into the global macro namespace.

###ts ts
the [*ts] extension allows documents to be marked up for basic classification constraints and automatically redacted. if you are seriously relying on [`ts] for confidentiality, make damn sure you start the file with [$%!![*needs] ts], so that rendering will fail with an error if the extension isn't supported.

[`ts] currently has no support for misinformation.

[`ts] enables the directives:
* [`%[*ts] class [$scope level] ([$styled-text])]: indicates a classification level for either the whole document (scope [$doc]) or the next section (scope [$sec]). if the ts level is below [$level], the section will be redacted or rendering will fail with an error, as appropriate. if styled-text is included, this will be treated as the name of the classification level.
* [`%[*ts] word [$scope word] ([$styled-text])]: indicates a codeword clearance that must be present for the text to render. if styled-text is present, this will be used to render the name of the codeword instead of [$word].
* [`%[*when] ts level [$level]]

Modified cortav.lua from [940c3efd41] to [2184d83e7b].

1
2
3
4










5
6
7
8
9
10
11
...
732
733
734
735
736
737
738







739
740
741
742
743
744
745
...
794
795
796
797
798
799
800






801
802
803
804
805
806
807
-- [ʞ] cortav.lua
--  ~ lexi hale <lexi@hale.su>
--  © AGPLv3
--  ? reference implementation of the cortav document language











local ss = require 'sirsem'
-- aliases for commonly used sirsem funcs
local startswith = ss.str.begins
local dump = ss.dump
local declare = ss.declare

................................................................................
			spans = {{
				kind = 'raw';
				spans = {str};
				origin = o;
			}};
			origin = o;
		}







	end
	ct.spanctls = {
		{seq = '!', parse = formatter 'emph'};
		{seq = '*', parse = formatter 'strong'};
		{seq = '~', parse = formatter 'strike'};
		{seq = '+', parse = formatter 'insert'};
		{seq = '\\', parse = function(s, c) -- raw
................................................................................
			}
		end};
		{seq = '>', parse = insert_link};
		{seq = '→', parse = insert_link};
		{seq = '🔗', parse = insert_link};
		{seq = '##', parse = insert_var_ref(true)};
		{seq = '#', parse = insert_var_ref(false)};






		{seq = '%%', parse = function (s,c)
			local com = s:match '^%%%%%s*(.*)$'
			return {
				kind = 'comment';
				comment = com;
			}
		end};




>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>







 







>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
...
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
-- [ʞ] cortav.lua
--  ~ lexi hale <lexi@hale.su>
--  © AGPLv3
--  ? reference implementation of the cortav document language
--
--  ! TODO refactor encoding logic. it's a complete
--         mess and i seem to have repeatedly gotten
--         confused about how it's supposed to work.
--         the whole shitshow needs to be replaced
--         with a clean, simple paradigm: documents
--         are translated to UTF8 on the way in, and
--         translate back out on the way out. trying
--         to cope with multiple simultaneous
--         encodings in memory is a disaster zone.

local ss = require 'sirsem'
-- aliases for commonly used sirsem funcs
local startswith = ss.str.begins
local dump = ss.dump
local declare = ss.declare

................................................................................
			spans = {{
				kind = 'raw';
				spans = {str};
				origin = o;
			}};
			origin = o;
		}
	end
	local function unicodepoint(s,c)
		local cp = tonumber(s, 16)
		return {
			kind = 'codepoint';
			code = cp;
		}
	end
	ct.spanctls = {
		{seq = '!', parse = formatter 'emph'};
		{seq = '*', parse = formatter 'strong'};
		{seq = '~', parse = formatter 'strike'};
		{seq = '+', parse = formatter 'insert'};
		{seq = '\\', parse = function(s, c) -- raw
................................................................................
			}
		end};
		{seq = '>', parse = insert_link};
		{seq = '→', parse = insert_link};
		{seq = '🔗', parse = insert_link};
		{seq = '##', parse = insert_var_ref(true)};
		{seq = '#', parse = insert_var_ref(false)};

		{seq = 'U+', parse = unicodepoint};
		{seq = 'u+', parse = unicodepoint};
		{seq = 'U',  parse = unicodepoint};
		{seq = 'u',  parse = unicodepoint};

		{seq = '%%', parse = function (s,c)
			local com = s:match '^%%%%%s*(.*)$'
			return {
				kind = 'comment';
				comment = com;
			}
		end};

Modified desk/cortav.xml from [a3601c692e] to [2b77e7703b].

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
...
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
...
251
252
253
254
255
256
257

258
259
260
261
262
263
264
		<contexts>
			<context name='init' attribute='Normal Text' lineEndContext='#pop' fallthroughContext='text'>
				<RegExpr String='\\.' attribute='Escaped Char'/>
				<RegExpr attribute='Section Cue' context='sec-ident' String='(#|§)+' firstNonSpace='true' />
				<StringDetect String='~~~' attribute='Literal Block Cue' firstNonSpace='true' context='literal-block-cue'/>
				<RegExpr attribute='List' String='[\*:]+' firstNonSpace='true' context='text' />
				<Detect2Chars char='%' char1='%' attribute='Comment' context='comment'/>
				<Detect2Chars char='%' char1='!' attribute='Critical Directive Cue' context='directive'/>

				<DetectChar char='%' attribute='Directive Cue' context='directive'/>
				<DetectChar char='@' attribute='Resource Cue' context='resource-ident'/>
				<DetectChar char='$' attribute='Deref Cue' context='block-macro-ident'/>
				<DetectChar char='&amp;' attribute='Deref Cue' context='block-deref-ident'/>
				<Detect2Chars char='&#9;' char1='&#9;' context='refdef'/>
				<DetectChar char='&#9;' context='refdef-id'/>

................................................................................
				<DetectChar   attribute='Span Cue' char='>' context='#pop!ref' />
				<DetectChar   attribute='Span Cue' char='^' context='#pop!ref' />
				<DetectChar   attribute='Span Cue' char='&amp;' context='#pop!ref' />
				<DetectChar   attribute='Span Cue' char='#' context='#pop!var-ref' />
				<DetectChar   attribute='Span Cue' char='\' context='#pop!flat-span' />
				<DetectChar   attribute='Span Cue' char='=' context='#pop!inline-math' />
				<Detect2Chars attribute='Comment' char='%' char1='%' context='#pop!inline-comment' />

				<Detect2Chars attribute='Critical Directive Cue' char='%' char1='!' context='#pop!inline-directive' />
				<DetectChar   attribute='Directive Cue' char='%' context='#pop!inline-directive' />
			</context>

			<context name='flat-span' attribute='Unstyled Text' lineEndContext='#pop'>
				<DetectChar attribute='Unstyled Text' context='flat-span' char='['/>
				<Detect2Chars attribute='Escaped Char' context='#stay' char='\' char1=']'/>
				<DetectChar attribute='Span Delimiter' context='#pop' char=']'/>
................................................................................
		</contexts>
		<itemDatas>
			<itemData name='Normal Text' defStyleNum='dsNormal'/>
			<itemData name='Styled Text' defStyleNum='dsNormal'/>
			<itemData name='Emphatic Text' defStyleNum='dsNormal' italic='true'/>
			<itemData name='Strong Text' defStyleNum='dsNormal' bold='true'/>
			<itemData name='Deleted Text' defStyleNum='dsNormal' strikeOut='true'/>
				
			<itemData name='Section Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Deref Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Header' defStyleNum='dsControlFlow' underline='true'/>
			<itemData name='Identifier' defStyleNum='dsVariable'/>

			<itemData name='Unstyled Text' defStyleNum='dsVerbatimString'/>
			<itemData name='Escaped Char' defStyleNum='dsSpecialChar'/>
................................................................................
			<itemData name='Span Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Resource Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Resource Identifier' defStyleNum='dsVariable' bold='true'/>
			<itemData name='Span Delimiter' defStyleNum='dsKeyword'/>
			<itemData name='Directive' defStyleNum='dsAttribute' bold='true'/>
			<itemData name='Directive Cue' defStyleNum='dsAttribute'/>
			<itemData name='Critical Directive Cue' defStyleNum='dsImport' bold='true'/>

			<itemData name='Extension Directive' defStyleNum='dsImport' bold='true'/>
			<itemData name='Renderer Directive' defStyleNum='dsExtension' bold='true'/>
			<itemData name='Standard Namespace' defStyleNum='dsBuiltIn' bold='true'/>
			<itemData name='Comment' defStyleNum='dsComment'/>
			<itemData name='Error' defStyleNum='dsError'/>
			<itemData name='Macro' defStyleNum='dsPreprocessor' bold='true'/>
			<itemData name='Macro Delimiter' defStyleNum='dsPreprocessor'/>







|
>







 







>
|







 







|







 







>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
...
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
		<contexts>
			<context name='init' attribute='Normal Text' lineEndContext='#pop' fallthroughContext='text'>
				<RegExpr String='\\.' attribute='Escaped Char'/>
				<RegExpr attribute='Section Cue' context='sec-ident' String='(#|§)+' firstNonSpace='true' />
				<StringDetect String='~~~' attribute='Literal Block Cue' firstNonSpace='true' context='literal-block-cue'/>
				<RegExpr attribute='List' String='[\*:]+' firstNonSpace='true' context='text' />
				<Detect2Chars char='%' char1='%' attribute='Comment' context='comment'/>
				<Detect2Chars char='%' char1='!' attribute='Important Directive Cue' context='directive'/>
				<StringDetect String='%!!' attribute='Critical Directive Cue' firstNonSpace='true' context='directive'/>
				<DetectChar char='%' attribute='Directive Cue' context='directive'/>
				<DetectChar char='@' attribute='Resource Cue' context='resource-ident'/>
				<DetectChar char='$' attribute='Deref Cue' context='block-macro-ident'/>
				<DetectChar char='&amp;' attribute='Deref Cue' context='block-deref-ident'/>
				<Detect2Chars char='&#9;' char1='&#9;' context='refdef'/>
				<DetectChar char='&#9;' context='refdef-id'/>

................................................................................
				<DetectChar   attribute='Span Cue' char='>' context='#pop!ref' />
				<DetectChar   attribute='Span Cue' char='^' context='#pop!ref' />
				<DetectChar   attribute='Span Cue' char='&amp;' context='#pop!ref' />
				<DetectChar   attribute='Span Cue' char='#' context='#pop!var-ref' />
				<DetectChar   attribute='Span Cue' char='\' context='#pop!flat-span' />
				<DetectChar   attribute='Span Cue' char='=' context='#pop!inline-math' />
				<Detect2Chars attribute='Comment' char='%' char1='%' context='#pop!inline-comment' />
				<StringDetect String='%!!' attribute='Critical Directive Cue' firstNonSpace='true' context='#pop!inline-directive'/>
				<Detect2Chars attribute='Important Directive Cue' char='%' char1='!' context='#pop!inline-directive' />
				<DetectChar   attribute='Directive Cue' char='%' context='#pop!inline-directive' />
			</context>

			<context name='flat-span' attribute='Unstyled Text' lineEndContext='#pop'>
				<DetectChar attribute='Unstyled Text' context='flat-span' char='['/>
				<Detect2Chars attribute='Escaped Char' context='#stay' char='\' char1=']'/>
				<DetectChar attribute='Span Delimiter' context='#pop' char=']'/>
................................................................................
		</contexts>
		<itemDatas>
			<itemData name='Normal Text' defStyleNum='dsNormal'/>
			<itemData name='Styled Text' defStyleNum='dsNormal'/>
			<itemData name='Emphatic Text' defStyleNum='dsNormal' italic='true'/>
			<itemData name='Strong Text' defStyleNum='dsNormal' bold='true'/>
			<itemData name='Deleted Text' defStyleNum='dsNormal' strikeOut='true'/>

			<itemData name='Section Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Deref Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Header' defStyleNum='dsControlFlow' underline='true'/>
			<itemData name='Identifier' defStyleNum='dsVariable'/>

			<itemData name='Unstyled Text' defStyleNum='dsVerbatimString'/>
			<itemData name='Escaped Char' defStyleNum='dsSpecialChar'/>
................................................................................
			<itemData name='Span Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Resource Cue' defStyleNum='dsKeyword' bold='true'/>
			<itemData name='Resource Identifier' defStyleNum='dsVariable' bold='true'/>
			<itemData name='Span Delimiter' defStyleNum='dsKeyword'/>
			<itemData name='Directive' defStyleNum='dsAttribute' bold='true'/>
			<itemData name='Directive Cue' defStyleNum='dsAttribute'/>
			<itemData name='Critical Directive Cue' defStyleNum='dsImport' bold='true'/>
			<itemData name='Important Directive Cue' defStyleNum='dsImport' bold='true'/>
			<itemData name='Extension Directive' defStyleNum='dsImport' bold='true'/>
			<itemData name='Renderer Directive' defStyleNum='dsExtension' bold='true'/>
			<itemData name='Standard Namespace' defStyleNum='dsBuiltIn' bold='true'/>
			<itemData name='Comment' defStyleNum='dsComment'/>
			<itemData name='Error' defStyleNum='dsError'/>
			<itemData name='Macro' defStyleNum='dsPreprocessor' bold='true'/>
			<itemData name='Macro Delimiter' defStyleNum='dsPreprocessor'/>

Modified makefile from [10a67640c2] to [97fc0b1491].

32
33
34
35
36
37
38



39
40
41
42
43
44
45
..
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
...
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
#    doesn't accept options like -l -x -o then you'll have to build
#    the binary by hand, sorry. but if you want to contribute a build
#    script to the repository, i'll happily take merge requests :)

lua != which lua
luac != which luac
sh != which sh




extens = $(wildcard ext/*.lua)
extens-names ?= $(basename $(notdir $(extens)))
rendrs = $(wildcard render/*.lua)
rendrs-names ?= $(basename $(notdir $(rendrs)))
binds = $(wildcard bind/*.c)
binds-names ?= $(basename $(notdir $(binds)))
................................................................................
ifneq ($(filter net,$(binds-names)),)
    lua-bindeps += -lcurl
endif

dbg-flags-luac = $(if $(debug),,-s)
dbg-flags-cc = $(if $(debug),-g,-s)

# sterilize the operating theatre
export LUA_PATH=./?.lua;./?.lc
export LUA_PATH_5_3=./?.lc;./?.lua
export LUA_PATH_5_4=./?.lc;./?.lua
export LUA_INIT=
export LUA_INIT_5_3=
export LUA_INIT_5_4=

# by default, we fetch and parse information about encodings we
# support so that cortav can do fancy things like format math
# equations by character class (e.g. italicizing variables)
# this is not necessary for parsing the format, and can be
# disabled by blanking the encoding-data list when building
# ($ make encoding-data=)
................................................................................

.PHONY: syncdoc
syncdoc: $(build)/cortav.html
	fossil uv add $< --as cortav.html
	fossil uv sync --all

# clean is written in overly cautious fashion to minimize damage,
# just in case it ever gets invoked in a bad way
.PHONY: clean
clean:
	rm -f $(build)/*.{html,lc,sh,txt,desktop} \
	      $(build)/$(executable){,.bin}

	rmdir $(build)

$(build)/%.sh: desk/%.sh | $(build)/
	echo >$@ "#!$(sh)"
	echo >>$@ 'cortav_exec="$(bin-prefix)/$(executable)"'
	echo >>$@ 'cortav_flags="$${ct_format_flags-$(default-format-flags)}"'
	cat $< >> $@







>
>
>







 







<
<
<
<
<
<
<







 







|



|
>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
..
60
61
62
63
64
65
66







67
68
69
70
71
72
73
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#    doesn't accept options like -l -x -o then you'll have to build
#    the binary by hand, sorry. but if you want to contribute a build
#    script to the repository, i'll happily take merge requests :)

lua != which lua
luac != which luac
sh != which sh

#sterilize the operating theatre
lua += -E

extens = $(wildcard ext/*.lua)
extens-names ?= $(basename $(notdir $(extens)))
rendrs = $(wildcard render/*.lua)
rendrs-names ?= $(basename $(notdir $(rendrs)))
binds = $(wildcard bind/*.c)
binds-names ?= $(basename $(notdir $(binds)))
................................................................................
ifneq ($(filter net,$(binds-names)),)
    lua-bindeps += -lcurl
endif

dbg-flags-luac = $(if $(debug),,-s)
dbg-flags-cc = $(if $(debug),-g,-s)









# by default, we fetch and parse information about encodings we
# support so that cortav can do fancy things like format math
# equations by character class (e.g. italicizing variables)
# this is not necessary for parsing the format, and can be
# disabled by blanking the encoding-data list when building
# ($ make encoding-data=)
................................................................................

.PHONY: syncdoc
syncdoc: $(build)/cortav.html
	fossil uv add $< --as cortav.html
	fossil uv sync --all

# clean is written in overly cautious fashion to minimize damage,
# just in case it ever gets invoked in a bad way (e.g. build=/)
.PHONY: clean
clean:
	rm -f $(build)/*.{html,lc,sh,txt,desktop} \
	      $(build)/$(executable){,.bin} \
	      $(build)/bind
	rmdir $(build)

$(build)/%.sh: desk/%.sh | $(build)/
	echo >$@ "#!$(sh)"
	echo >>$@ 'cortav_exec="$(bin-prefix)/$(executable)"'
	echo >>$@ 'cortav_flags="$${ct_format_flags-$(default-format-flags)}"'
	cat $< >> $@

Modified render/groff.lua from [3a20caca9a] to [810c155515].

343
344
345
346
347
348
349
350




351
352
353
354
355
356
357
			rs.macAdd 'strike'
			rcc.prop.color = 'del'
		elseif s.style == 'insert' then
			rs.macAdd 'insert'
			rcc.prop.color = 'new'
		end
		rs.renderSpans(rcc, s.spans, b, sec)
	end;





	function spanRenderers.link(rc, l, b, sec)
		rs.renderSpans(rc, l.spans, b, sec)
		rs.linkctr = rs.linkctr + 1
		rs.macAdd 'footnote'
		local p = rc:span(string.format('[%u]', rs.linkctr))
		if type(l.ref) == 'string' then







|
>
>
>
>







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
			rs.macAdd 'strike'
			rcc.prop.color = 'del'
		elseif s.style == 'insert' then
			rs.macAdd 'insert'
			rcc.prop.color = 'new'
		end
		rs.renderSpans(rcc, s.spans, b, sec)
	end

	function spanRenderers.codepoint(rc, s, b, sec)
		utf8.char(s.code)
	end

	function spanRenderers.link(rc, l, b, sec)
		rs.renderSpans(rc, l.spans, b, sec)
		rs.linkctr = rs.linkctr + 1
		rs.macAdd 'footnote'
		local p = rc:span(string.format('[%u]', rs.linkctr))
		if type(l.ref) == 'string' then

Modified render/html.lua from [28584fb71a] to [f4ce452531].

694
695
696
697
698
699
700







701
702
703
704
705
706
707
			elseif sp.style == 'strike' or sp.style == 'insert' then
				addStyle 'editors_markup'
			elseif sp.style == 'variable' then
				addStyle 'var'
			end
			return tag(tags[sp.style],nil,htmlSpan(sp.spans,...))
		end








		function span_renderers.deref(t,b,s)
			local r = b.origin:ref(t.ref)
			local name = t.ref
			if name:find'%.' then name = name:match '^[^.]*%.(.+)$' end
			if type(r) == 'string' then
				addStyle 'abbr'







>
>
>
>
>
>
>







694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
			elseif sp.style == 'strike' or sp.style == 'insert' then
				addStyle 'editors_markup'
			elseif sp.style == 'variable' then
				addStyle 'var'
			end
			return tag(tags[sp.style],nil,htmlSpan(sp.spans,...))
		end

		function span_renderers.codepoint(t,b,s)
			-- is this a UTF8 output?
			return utf8.char(t.code)
			-- else
			-- return string.format("&#%u;", code)
		end

		function span_renderers.deref(t,b,s)
			local r = b.origin:ref(t.ref)
			local name = t.ref
			if name:find'%.' then name = name:match '^[^.]*%.(.+)$' end
			if type(r) == 'string' then
				addStyle 'abbr'

Modified sirsem.lua from [2b64c7033a] to [c72ad0a8fc].

17
18
19
20
21
22
23







24
25
26
27
28
29
30
		end
		return pkg
	end
	ss = namespace 'sirsem'
	ss.namespace = namespace
end








local native = _G.native

function ss.map(fn, lst)
	local new = {}
	for k,v in pairs(lst) do
		table.insert(new, fn(v,k))
	end







>
>
>
>
>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
		end
		return pkg
	end
	ss = namespace 'sirsem'
	ss.namespace = namespace
end

-- the C shim provides extra functionality that cannot
-- be implemented in pure Lua. this functionality is
-- accessed through the _G.native namespace. native
-- functions should not be called directly; rather,
-- they should be called from sirsem.lua wrappers that
-- can provide alternative implementations or error
-- messages when cortav is build in plain lua mode
local native = _G.native

function ss.map(fn, lst)
	local new = {}
	for k,v in pairs(lst) do
		table.insert(new, fn(v,k))
	end