1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
use env;
use FlagParser;
use *;
// FIXME: default can be eliminated by having a different FlagParser (that returns the value
// instead of modifies self)
// can have an argument, outputs man-page + shell completion
/// Convert Bit Powder Markdown to HTML. Overview of Bit Powder Markdown:
/// .Bl -bullet
/// .It
/// supports attributes with `{attr}` syntax, multiple attributes delimited with `;`. These attributes can be:
/// .Bl -bullet -compact
/// .It
/// CSS classes with: `.class`
/// .It
/// CSS properties with: `key: value`
/// .It
/// HTML tag attributes with: `key=value`
/// .It
/// HTML ids with: `#id`
/// .El
/// .It
/// spans with `[content]`, divs with `[[content]]`;
/// .It
/// marks with `==content==`, and abbrs with `=content=`;
/// .It
/// superscript with `x^^[2]`, and subscript with `CO~~[2]`;
/// .It
/// icons with `:fas-hexagon:`;
/// .It
/// as-is copy to output with `[[[ as-is-content ]]]`;
/// .It
/// reports errors when encountering syntax errors (so does not continue like regular Markdown);
/// .It
/// no tables as of yet.
/// .El
///
/// This utility also supports Bit Powder Mustache templates. Variables can be declared at top of an input file with `key: json-value` pairs. The templates supports:
/// .Bl -bullet
/// .It
/// values with `{{value}}`;
/// .It
/// iterators and conditional with `{{#value}}contents{{/}}`.
/// Contents is displayed (if this default form is used) if value is an object, array of objects, or true.
/// An iteration variable can be specified with `{{#name -> variable}}content{{/}}`, which can be used to iterate over (arrays of) any type.
/// Iterators can have optional default values (in `object`) with `{{#name <- object}}content{{/}}` (these object defaults are evaluated once during parsing of the file and can reference global variables);
/// .It
/// template definition with `{{=name}}content{{/}}`.
/// Templates can have optional default values (in `object`) with `{{=name <- object}}content{{/}}`;
/// .It
/// template instantation with `{{>name}}` or `{{name <- value}}`;
/// .It
/// Error handling is different from normal Mustache: missing fields is always considered an error. Errors can be suppressed with the `expr ??? alternative` try syntax (on error in `expr`, `alternative` will be executed). Shorthand for `expr ??? null` is `expr ???` (which can be used in loops with `{{#someField???}}` (which ignores errors if the field is not found).
/// .El
///
/// Binary Object expressions can be used instead of values as above (think of expressions, functional calls, selectors, etc). This utility supports also Lua in the templates. Prefix anywhere a value is accepted with `lua:` to run Lua code (with current value in `this`).
///
/// There are a couple of special functions added to the Binary Object expressions:
/// .Bl -tag -width Ds
/// .It Ft string Fn compile "string template, [any context]"
/// Compiles a string to a dynamic Mustache template that can be evaluated, and evaluates the defaults using the optional context
/// .Ar context
/// (otherwise empty context is used).
/// .It Ft string Fn eval "string compiled_template, any context"
/// Evaluates a dynamic Mustache template using the context
/// .Ar context .
/// .It Ft void Fn set "string key, any value"
/// .It Ft any Fn get "string key"
/// Sets/retrieves a global value (useful for figure numbers etc).
/// .It Ft string Fn filehash "string path"
/// .It Ft string Fn filewithhash "string path"
/// Calculates the xxhash32 for the contents of the file specified by path (relative to the --base flag). Useful to support caching with a long TTL: setting the hash as query makes the URL unique for the content (if the content changes). The function call
/// .Fn filewithhash "path"
/// prints `path?hash`.
/// .El
///
/// .Sh EXAMPLE
/// .Bd -literal
/// {{=cardfeature <- {fillHeight: true, dark: false, photoHideBreakpoint: "md"}}}
/// [[{.card{{#!dark}}; .light{{/}}}
/// [[{.card-header}
/// :fas-{{icon}}:{.mr-2}
/// {{title}}
/// ]]
/// ...
/// {{eval(body, this)}}
/// ...
/// ]
/// ]]
/// {{/cardfeature}}
///
/// {{cardfeature <- {
/// dark: true,
/// icon: "calendar-star",
/// title: "Upcoming",
/// body: compile(|
/// On **Tuesday 1 December** from **16:00 - 17:30**, *X* will present her recently published book 'XYZ'.
/// ),
/// buttonLeft: {icon: "sign-in", name: "join", href: "http://"},
/// buttonRight: {icon: "calendar", name: "calendar feed", href: "http://"}
/// }}}
/// .Ed