@tabnas/markdown 0.7.10 → 0.7.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/block.d.ts +1 -1
- package/dist/block.js +1 -1
- package/dist/markdown.d.ts +1 -1
- package/dist/markdown.js +1 -1
- package/dist/translate.d.ts +1 -0
- package/dist/translate.js +130 -65
- package/dist/translate.js.map +1 -1
- package/package.json +1 -1
- package/src/block.ts +1 -1
- package/src/markdown.ts +1 -1
- package/src/translate.ts +131 -65
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
A CommonMark parser for the [Tabnas](https://github.com/tabnas/parser) engine.
|
|
4
4
|
|
|
5
5
|
**This parser is conformant to CommonMark 0.31.2**, all 652 examples, across all 26
|
|
6
|
-
sections of the spec suite, in
|
|
6
|
+
sections of the spec suite, in all three runtimes. The suite is vendored in this repository, so
|
|
7
7
|
the claim is checkable: `npm run conformance` reports 652/652, with no build step and no
|
|
8
8
|
engine installed. It runs with the GFM extensions off, which is what measuring CommonMark
|
|
9
9
|
conformance means: with `gfm: true` the extensions deliberately change nine of those
|
package/dist/block.d.ts
CHANGED
|
@@ -189,7 +189,7 @@ export declare class BlockParser {
|
|
|
189
189
|
* Not simply `offset`: a JavaScript string index counts UTF-16 units, so an
|
|
190
190
|
* astral character (emoji, rare CJK) would advance the column by two. A
|
|
191
191
|
* column means a character, so `\u{1F600} *x*` must report the same columns
|
|
192
|
-
* in
|
|
192
|
+
* in every runtime.
|
|
193
193
|
*
|
|
194
194
|
* Counted incrementally from the last offset already measured. `addChild`
|
|
195
195
|
* runs once per container opened, so counting from the start of the line
|
package/dist/block.js
CHANGED
|
@@ -1186,7 +1186,7 @@ class BlockParser {
|
|
|
1186
1186
|
* Not simply `offset`: a JavaScript string index counts UTF-16 units, so an
|
|
1187
1187
|
* astral character (emoji, rare CJK) would advance the column by two. A
|
|
1188
1188
|
* column means a character, so `\u{1F600} *x*` must report the same columns
|
|
1189
|
-
* in
|
|
1189
|
+
* in every runtime.
|
|
1190
1190
|
*
|
|
1191
1191
|
* Counted incrementally from the last offset already measured. `addChild`
|
|
1192
1192
|
* runs once per container opened, so counting from the start of the line
|
package/dist/markdown.d.ts
CHANGED
|
@@ -26,4 +26,4 @@ export type { ParserOptions } from './options.ts';
|
|
|
26
26
|
export { renderHTML } from './html.ts';
|
|
27
27
|
export { translate } from './translate';
|
|
28
28
|
export type { TranslationPart, TranslationParts } from './translate';
|
|
29
|
-
declare const VERSION = "0.7.
|
|
29
|
+
declare const VERSION = "0.7.12";
|
package/dist/markdown.js
CHANGED
|
@@ -161,6 +161,6 @@ Object.defineProperty(exports, "translate", { enumerable: true, get: function ()
|
|
|
161
161
|
// VERSION is this package's version. It MUST equal package.json "version":
|
|
162
162
|
// the release orchestrator rewrites both, and the version test fails the
|
|
163
163
|
// build if they drift. Mirrors `const VERSION` in go/markdown.go.
|
|
164
|
-
const VERSION = '0.7.
|
|
164
|
+
const VERSION = '0.7.12';
|
|
165
165
|
exports.VERSION = VERSION;
|
|
166
166
|
//# sourceMappingURL=markdown.js.map
|
package/dist/translate.d.ts
CHANGED
package/dist/translate.js
CHANGED
|
@@ -41,15 +41,26 @@ const TRANSLATION = Object.freeze({
|
|
|
41
41
|
"tree"
|
|
42
42
|
],
|
|
43
43
|
"writes": "records",
|
|
44
|
+
"root": "array",
|
|
45
|
+
"schema": "markdown-ast",
|
|
44
46
|
"lift": "alchemy/lift.alc",
|
|
45
47
|
"render": "alchemy/render.alc",
|
|
46
48
|
"loss": [
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
+
"The rows are the elements of the root array, and a root of another kind is written as one row.",
|
|
50
|
+
"The columns are the first row's, an object's keys or an array's positions labelled 0, 1 and so on, so a member or position of a later row that the first row lacks is not written, and one the first row has and a later row lacks is an empty cell.",
|
|
51
|
+
"When the first row is a scalar there is one column, named value, and every row is written whole in it, an array or an object as its compact JSON text.",
|
|
52
|
+
"A table of no columns, such as the one an empty array or object makes, is written as the empty document, which reads back as the empty table.",
|
|
53
|
+
"Read as records, a document with no table is the empty table, of no columns and no rows.",
|
|
54
|
+
"Read as records, a document with several tables is its first table, and the tables after it are not read.",
|
|
55
|
+
"Inline markup in a cell is flattened to its text when it is read, an image to its alt text; a written cell escapes every character that can begin inline markup, so it reads back as the text it was.",
|
|
56
|
+
"A null and a missing cell are both written as an empty cell, so the two cannot be told apart, or from an empty string, when read back.",
|
|
57
|
+
"A nested array or object in a cell is written as its compact JSON text.",
|
|
58
|
+
"A number that is not finite is written as Infinity, -Infinity or NaN, and as null inside a nested array or object, since JSON has no spelling for one.",
|
|
59
|
+
"Every value is written as text, so a number or a boolean reads back as a string.",
|
|
49
60
|
"Column alignment is not kept.",
|
|
50
61
|
"A line break in a cell is written as a space.",
|
|
51
|
-
"
|
|
52
|
-
"A U+0000 in a cell is written as
|
|
62
|
+
"Whitespace at either end of a cell is not kept, as the reader trims it: the space, the tab, U+00A0, U+FEFF, U+2028, U+2029 and the other Unicode space separators, though not U+0085.",
|
|
63
|
+
"A U+0000 in a cell is written as U+FFFD, the character a Markdown reader puts in its place, so it reads back as U+FFFD."
|
|
53
64
|
]
|
|
54
65
|
}
|
|
55
66
|
}
|
|
@@ -79,26 +90,36 @@ const TRANSLATION = Object.freeze({
|
|
|
79
90
|
; cell of text beside emphasis, a link, an image, inline HTML or an
|
|
80
91
|
; autolink is their texts run together, \`Bob *b*\` as \`Bob b\`.
|
|
81
92
|
;
|
|
82
|
-
;
|
|
83
|
-
; the
|
|
84
|
-
;
|
|
93
|
+
; A Markdown document is read as records through its table and nothing
|
|
94
|
+
; else, so the first table is the one read: a table after it is not
|
|
95
|
+
; read, its rows and cells passed over as any other node's. A document
|
|
96
|
+
; with no table is read as the empty table, a schema of no columns, no
|
|
97
|
+
; row and \`table-end\`, which the render writes back as the empty
|
|
98
|
+
; document. The manifest's loss lines say both.
|
|
85
99
|
;
|
|
86
100
|
; The state is one vector, [stack phase seen in-cell runs cells]:
|
|
87
101
|
; stack the open containers, one marker each: \`:array\`, \`:node\` for
|
|
88
102
|
; an object whose type is not known yet or is any other node,
|
|
89
103
|
; and \`:table\`, \`:row\` or \`:cell\` once its \`type\` has named
|
|
90
|
-
; one,
|
|
104
|
+
; one, or \`:later\` for a table after the first, so that its
|
|
105
|
+
; end is known when its object ends;
|
|
91
106
|
; phase \`:before\` the table, \`:header\` inside it until its first
|
|
92
|
-
; row ends, \`:body\` once the schema is written, \`:after\` it
|
|
107
|
+
; row ends, \`:body\` once the schema is written, \`:after\` it,
|
|
108
|
+
; and \`:later\` inside a table after it, which is not read;
|
|
93
109
|
; seen what the last key was, \`:type\`, \`:text\` (a \`value\` or an
|
|
94
|
-
; \`alt\`) or \`:other\`, so that the scalar after it is classified
|
|
110
|
+
; \`alt\`) or \`:other\`, so that the scalar after it is classified,
|
|
111
|
+
; and \`:none\` before the first event, so that events with no
|
|
112
|
+
; value at all are told from a document with no table;
|
|
95
113
|
; in-cell whether a cell is open, so that text under it is the cell's;
|
|
96
114
|
; runs the open cell's runs of text, in order;
|
|
97
115
|
; cells the open row's cells, as wide as one row.
|
|
98
116
|
; It grows with the document's nesting and with one row's width, never
|
|
99
|
-
; with the table's length: a row is emitted when its
|
|
100
|
-
;
|
|
101
|
-
;
|
|
117
|
+
; with the table's length or the document's: a row is emitted when its
|
|
118
|
+
; object ends and dropped, and a later table keeps nothing. Events no
|
|
119
|
+
; tree has (a key outside an object, an end with nothing open), and
|
|
120
|
+
; events of a node where the reader's tree never puts one (a row or a
|
|
121
|
+
; cell outside a table, a table inside one), fail with
|
|
122
|
+
; PROTOCOL_ORDER_ERROR, saying so.
|
|
102
123
|
|
|
103
124
|
; A column record of the TableRows protocol, as the standard library's
|
|
104
125
|
; \`public-column\` makes one.
|
|
@@ -138,31 +159,35 @@ def markdown-mark [marker stack]
|
|
|
138
159
|
push marker (pop stack)
|
|
139
160
|
|
|
140
161
|
; The scalar after \`type\`: the three nodes the lift reads leave their
|
|
141
|
-
; marker on the stack and move the phase;
|
|
162
|
+
; marker on the stack and move the phase; a table after the first leaves
|
|
163
|
+
; \`:later\`, and its rows and cells, like any other node, stay \`:node\`.
|
|
142
164
|
def markdown-node [name stack phase in-cell runs cells]
|
|
143
165
|
match name
|
|
144
166
|
case "table"
|
|
145
167
|
match phase
|
|
146
168
|
case :before (transition [(markdown-mark :table stack) :header :other in-cell runs cells] [])
|
|
147
|
-
case :after (
|
|
148
|
-
case _ (fail "the events hold a table inside a table, which the reader's tree never has")
|
|
169
|
+
case :after (transition [(markdown-mark :later stack) :later :other in-cell runs cells] [])
|
|
170
|
+
case _ (fail :protocol-order "the events hold a table inside a table, which the reader's tree never has")
|
|
149
171
|
case "tableRow"
|
|
150
172
|
match phase
|
|
151
|
-
case :before (fail "the events hold a table row outside a table, which the reader's tree never has")
|
|
152
|
-
case :after (fail "the events hold a table row outside a table, which the reader's tree never has")
|
|
173
|
+
case :before (fail :protocol-order "the events hold a table row outside a table, which the reader's tree never has")
|
|
174
|
+
case :after (fail :protocol-order "the events hold a table row outside a table, which the reader's tree never has")
|
|
175
|
+
case :later (transition [stack phase :other in-cell runs cells] [])
|
|
153
176
|
case _ (transition [(markdown-mark :row stack) phase :other in-cell runs []] [])
|
|
154
177
|
case "tableCell"
|
|
155
178
|
match phase
|
|
156
|
-
case :before (fail "the events hold a table cell outside a table, which the reader's tree never has")
|
|
157
|
-
case :after (fail "the events hold a table cell outside a table, which the reader's tree never has")
|
|
179
|
+
case :before (fail :protocol-order "the events hold a table cell outside a table, which the reader's tree never has")
|
|
180
|
+
case :after (fail :protocol-order "the events hold a table cell outside a table, which the reader's tree never has")
|
|
181
|
+
case :later (transition [stack phase :other in-cell runs cells] [])
|
|
158
182
|
case _
|
|
159
183
|
if in-cell
|
|
160
|
-
fail "the events hold a table cell inside a cell, which the reader's tree never has"
|
|
184
|
+
fail :protocol-order "the events hold a table cell inside a cell, which the reader's tree never has"
|
|
161
185
|
transition [(markdown-mark :cell stack) phase :other true [] cells] []
|
|
162
186
|
case _ (transition [stack phase :other in-cell runs cells] [])
|
|
163
187
|
|
|
164
188
|
; An object's end: a cell joins its row, a row is the schema or a
|
|
165
|
-
; record, the table is done, and any other
|
|
189
|
+
; record, the table is done, a later table is passed over, and any other
|
|
190
|
+
; node is dropped.
|
|
166
191
|
def markdown-close [stack phase in-cell runs cells]
|
|
167
192
|
match (markdown-top stack)
|
|
168
193
|
case :cell
|
|
@@ -175,9 +200,11 @@ def markdown-close [stack phase in-cell runs cells]
|
|
|
175
200
|
transition [(pop stack) phase :other in-cell runs []] [(row cells)]
|
|
176
201
|
case :table
|
|
177
202
|
transition [(pop stack) :after :other in-cell runs cells] []
|
|
203
|
+
case :later
|
|
204
|
+
transition [(pop stack) :after :other in-cell runs cells] []
|
|
178
205
|
case :node
|
|
179
206
|
transition [(pop stack) phase :other in-cell runs cells] []
|
|
180
|
-
case _ (fail "the events end an object that is not open, which a tree's never do")
|
|
207
|
+
case _ (fail :protocol-order "the events end an object that is not open, which a tree's never do")
|
|
181
208
|
|
|
182
209
|
def markdown-event [stack phase seen in-cell runs cells event]
|
|
183
210
|
match event
|
|
@@ -187,8 +214,8 @@ def markdown-event [stack phase seen in-cell runs cells event]
|
|
|
187
214
|
transition [(push :array stack) phase :other in-cell runs cells] []
|
|
188
215
|
case (key name)
|
|
189
216
|
match (markdown-top stack)
|
|
190
|
-
case :none (fail "the events hold a key outside an object, which a tree's never do")
|
|
191
|
-
case :array (fail "the events hold a key inside an array, which a tree's never do")
|
|
217
|
+
case :none (fail :protocol-order "the events hold a key outside an object, which a tree's never do")
|
|
218
|
+
case :array (fail :protocol-order "the events hold a key inside an array, which a tree's never do")
|
|
192
219
|
case _ (transition [stack phase (markdown-seen name) in-cell runs cells] [])
|
|
193
220
|
case (scalar value)
|
|
194
221
|
match seen
|
|
@@ -202,27 +229,34 @@ def markdown-event [stack phase seen in-cell runs cells event]
|
|
|
202
229
|
case array-end
|
|
203
230
|
match (markdown-top stack)
|
|
204
231
|
case :array (transition [(pop stack) phase :other in-cell runs cells] [])
|
|
205
|
-
case _ (fail "the events end an array that is not open, which a tree's never do")
|
|
232
|
+
case _ (fail :protocol-order "the events end an array that is not open, which a tree's never do")
|
|
206
233
|
|
|
207
234
|
def markdown-lift-step [s event]
|
|
208
235
|
match s
|
|
209
236
|
case [stack phase seen in-cell runs cells]
|
|
210
237
|
markdown-event stack phase seen in-cell runs cells event
|
|
211
238
|
|
|
239
|
+
; What the end of the events adds once every container is closed: the
|
|
240
|
+
; table's end, or, for a document with no table, the empty table.
|
|
241
|
+
def markdown-lift-end [stack outputs]
|
|
242
|
+
match (count stack)
|
|
243
|
+
case 0 outputs
|
|
244
|
+
case _ (fail :protocol-order "the events ended inside a container, which a tree's never do")
|
|
245
|
+
|
|
212
246
|
def markdown-lift-finish [s]
|
|
213
247
|
match s
|
|
214
248
|
case [stack phase seen in-cell runs cells]
|
|
215
|
-
match
|
|
216
|
-
case :
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
case
|
|
220
|
-
|
|
221
|
-
|
|
249
|
+
match seen
|
|
250
|
+
case :none (fail :protocol-order "the events hold no value, where a tree's hold one")
|
|
251
|
+
case _
|
|
252
|
+
match phase
|
|
253
|
+
case :after (markdown-lift-end stack [table-end])
|
|
254
|
+
case :before (markdown-lift-end stack [(schema []) table-end])
|
|
255
|
+
case _ (fail :protocol-order "the events ended inside a table, which a tree's never do")
|
|
222
256
|
|
|
223
257
|
; The lift: the document's events in, the table's records out.
|
|
224
258
|
def markdown-lift [input]
|
|
225
|
-
scan-emit [[] :before :
|
|
259
|
+
scan-emit [[] :before :none false [] []] markdown-lift-step markdown-lift-finish (events input)
|
|
226
260
|
` }),
|
|
227
261
|
render: Object.freeze({ entry: "markdown-render", source: `; Markdown's render: a table's records, the TableRows protocol (one
|
|
228
262
|
; \`schema\`, a \`row\` per record and \`table-end\`), written as one GFM pipe
|
|
@@ -235,45 +269,69 @@ def markdown-lift [input]
|
|
|
235
269
|
; \`| --- | --- |\`, and a row per record, each line ended by a line feed
|
|
236
270
|
; and every cell between \`| \` and \` |\`. A cell is its value's text as
|
|
237
271
|
; the CSV renderer writes it (\`scalar-text\`: a string as it is, a number
|
|
238
|
-
; by its lexeme,
|
|
272
|
+
; by its lexeme, or by its word, \`Infinity\`, \`-Infinity\` or \`NaN\`, when
|
|
273
|
+
; it is not finite, a boolean by its name, null and a missing cell as
|
|
239
274
|
; nothing, a vector or a record as its compact JSON text), with every
|
|
240
|
-
; backslash doubled and every
|
|
241
|
-
;
|
|
242
|
-
;
|
|
243
|
-
;
|
|
244
|
-
;
|
|
245
|
-
;
|
|
246
|
-
;
|
|
247
|
-
;
|
|
248
|
-
;
|
|
249
|
-
;
|
|
250
|
-
;
|
|
275
|
+
; backslash doubled, and every character that can begin inline markup
|
|
276
|
+
; escaped with a backslash, as CommonMark lets any ASCII punctuation be
|
|
277
|
+
; escaped: the pipe, which the reader's split skips after a backslash
|
|
278
|
+
; (so its escape holds only when a backslash before it is itself
|
|
279
|
+
; escaped), the backtick of a code span, the \`*\` and \`_\` of emphasis,
|
|
280
|
+
; the brackets of a link, an image or a footnote, the \`<\` of an autolink
|
|
281
|
+
; or of raw HTML, the \`&\` of an entity or numeric character reference,
|
|
282
|
+
; and the \`~\` of GFM's strikethrough. The reader turns each escape back
|
|
283
|
+
; into its character, so a written cell reads back as the text it was;
|
|
284
|
+
; a URL that GFM reads as an autolink reads back as its own text, which
|
|
285
|
+
; is the link's. Every line break is replaced by a space, since a row is
|
|
286
|
+
; one line, and a U+0000 is written as U+FFFD, the character CommonMark
|
|
287
|
+
; has every reader put in its place; the loss declaration says both.
|
|
288
|
+
; Alignment is not written: every column's delimiter is \`---\`.
|
|
289
|
+
;
|
|
290
|
+
; A table of no columns, the one an empty array or object makes, has no
|
|
291
|
+
; pipe table, since a row needs at least one cell: it is written as the
|
|
292
|
+
; empty document, nothing at all, and so are its rows, which have no
|
|
293
|
+
; cells. The lift reads that document back as the empty table, of no
|
|
294
|
+
; columns and no rows.
|
|
251
295
|
;
|
|
252
296
|
; The state is one marker: \`:start\` before the schema, the schema's
|
|
253
297
|
; width (a number) while rows may follow, and \`:ended\` after
|
|
254
298
|
; \`table-end\`, so that a stream which breaks the protocol (a row before
|
|
255
299
|
; the schema, a second schema, a row of another width, anything after
|
|
256
|
-
; the end, no end) fails with
|
|
257
|
-
; being written. The check is this file's rather than
|
|
258
|
-
; whose refusals speak of CSV.
|
|
259
|
-
; needs at least one cell, so such a table has no Markdown form.
|
|
300
|
+
; the end, no end) fails with PROTOCOL_ORDER_ERROR, saying so, rather
|
|
301
|
+
; than being written. The check is this file's rather than
|
|
302
|
+
; \`csv-table\`'s, whose refusals speak of CSV.
|
|
260
303
|
|
|
261
304
|
; What \`scalar-text\` reads: null and a missing cell are written as
|
|
262
305
|
; nothing, where the CSV renderer's \`csv-options\` map a missing cell to
|
|
263
|
-
; an error.
|
|
306
|
+
; an error, and a number that is not finite as its word.
|
|
264
307
|
def markdown-options
|
|
265
308
|
record
|
|
266
309
|
entry :null-text ""
|
|
267
310
|
entry :missing ""
|
|
311
|
+
entry :non-finite :literal
|
|
268
312
|
|
|
269
|
-
; A cell's text, as it stands between the pipes
|
|
313
|
+
; A cell's text, as it stands between the pipes: the backslashes doubled
|
|
314
|
+
; first, so that the escapes written after them stay single.
|
|
270
315
|
def markdown-cell [cell]
|
|
271
316
|
replace-text "\\r" " "
|
|
272
317
|
replace-text "\\n" " "
|
|
273
318
|
replace-text "\\r\\n" " "
|
|
274
|
-
replace-text "
|
|
275
|
-
|
|
276
|
-
|
|
319
|
+
replace-text "\\u0000" "\\ufffd"
|
|
320
|
+
markdown-escape
|
|
321
|
+
replace-text "\\\\" "\\\\\\\\"
|
|
322
|
+
scalar-text markdown-options cell
|
|
323
|
+
|
|
324
|
+
; Every character that can begin inline markup, escaped with a backslash.
|
|
325
|
+
def markdown-escape [cell-text]
|
|
326
|
+
replace-text "~" "\\\\~"
|
|
327
|
+
replace-text "&" "\\\\&"
|
|
328
|
+
replace-text "<" "\\\\<"
|
|
329
|
+
replace-text "]" "\\\\]"
|
|
330
|
+
replace-text "[" "\\\\["
|
|
331
|
+
replace-text "_" "\\\\_"
|
|
332
|
+
replace-text "*" "\\\\*"
|
|
333
|
+
replace-text "\`" "\\\\\`"
|
|
334
|
+
replace-text "|" "\\\\|" cell-text
|
|
277
335
|
|
|
278
336
|
def markdown-label [column]
|
|
279
337
|
markdown-cell (get :label column)
|
|
@@ -291,38 +349,45 @@ def markdown-delimiter [width]
|
|
|
291
349
|
repeat width "| --- "
|
|
292
350
|
"|\\n"
|
|
293
351
|
|
|
352
|
+
; A record's line in a table \`width\` columns wide, or none in a table of
|
|
353
|
+
; no columns, which is written as the empty document.
|
|
354
|
+
def markdown-row [width cells]
|
|
355
|
+
match width
|
|
356
|
+
case 0 []
|
|
357
|
+
case _ [(markdown-line (map markdown-cell cells))]
|
|
358
|
+
|
|
294
359
|
def markdown-render-step [s event]
|
|
295
360
|
match event
|
|
296
361
|
case (schema columns)
|
|
297
362
|
match s
|
|
298
363
|
case :start
|
|
299
364
|
match (count columns)
|
|
300
|
-
case 0 (
|
|
365
|
+
case 0 (transition 0 [])
|
|
301
366
|
case _
|
|
302
367
|
transition (count columns)
|
|
303
368
|
vector
|
|
304
369
|
markdown-line (map markdown-label columns)
|
|
305
370
|
markdown-delimiter (count columns)
|
|
306
|
-
case _ (fail "the events hold a second schema, where a table's hold one")
|
|
371
|
+
case _ (fail :protocol-order "the events hold a second schema, where a table's hold one")
|
|
307
372
|
case (row cells)
|
|
308
373
|
match s
|
|
309
|
-
case :start (fail "the events hold a row before the schema, which a table's never do")
|
|
310
|
-
case :ended (fail "the events hold a row after table-end, which a table's never do")
|
|
374
|
+
case :start (fail :protocol-order "the events hold a row before the schema, which a table's never do")
|
|
375
|
+
case :ended (fail :protocol-order "the events hold a row after table-end, which a table's never do")
|
|
311
376
|
case _
|
|
312
377
|
match (compare (count cells) s)
|
|
313
|
-
case :equal (transition s
|
|
314
|
-
case _ (fail "the events hold a row that is not as wide as the schema, which a table's never do")
|
|
378
|
+
case :equal (transition s (markdown-row s cells))
|
|
379
|
+
case _ (fail :protocol-order "the events hold a row that is not as wide as the schema, which a table's never do")
|
|
315
380
|
case table-end
|
|
316
381
|
match s
|
|
317
|
-
case :start (fail "the events end before the schema, which a table's never do")
|
|
318
|
-
case :ended (fail "the events hold a second table-end, which a table's never do")
|
|
382
|
+
case :start (fail :protocol-order "the events end before the schema, which a table's never do")
|
|
383
|
+
case :ended (fail :protocol-order "the events hold a second table-end, which a table's never do")
|
|
319
384
|
case _ (transition :ended [])
|
|
320
385
|
|
|
321
386
|
def markdown-render-finish [s]
|
|
322
387
|
match s
|
|
323
388
|
case :ended []
|
|
324
|
-
case :start (fail "the events hold no schema, where a table's hold one first")
|
|
325
|
-
case _ (fail "the events ended before table-end, which a table's never do")
|
|
389
|
+
case :start (fail :protocol-order "the events hold no schema, where a table's hold one first")
|
|
390
|
+
case _ (fail :protocol-order "the events ended before table-end, which a table's never do")
|
|
326
391
|
|
|
327
392
|
; The render: the table's records in, the pipe table's text out.
|
|
328
393
|
def markdown-render [input]
|
package/dist/translate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":";AAAA,yDAAyD;;
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":";AAAA,yDAAyD;;QAgavD,SAAS;AA/YX,MAAM,WAAW,GAAqB,MAAM,CAAC,MAAM,CAAC;IAClD,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DX;IACC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgMvD,EAAE,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuI3D,EAAE,CAAC;CACH,CAAC,CAAA;AAEF,SAAS,SAAS;IAChB,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tabnas/markdown",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.12",
|
|
4
4
|
"description": "A Tabnas parser plugin for CommonMark/GFM Markdown — headings, lists, blockquotes, code, emphasis, links and more, into a JSON AST.",
|
|
5
5
|
"main": "dist/markdown.js",
|
|
6
6
|
"type": "commonjs",
|
package/src/block.ts
CHANGED
|
@@ -1321,7 +1321,7 @@ export class BlockParser {
|
|
|
1321
1321
|
* Not simply `offset`: a JavaScript string index counts UTF-16 units, so an
|
|
1322
1322
|
* astral character (emoji, rare CJK) would advance the column by two. A
|
|
1323
1323
|
* column means a character, so `\u{1F600} *x*` must report the same columns
|
|
1324
|
-
* in
|
|
1324
|
+
* in every runtime.
|
|
1325
1325
|
*
|
|
1326
1326
|
* Counted incrementally from the last offset already measured. `addChild`
|
|
1327
1327
|
* runs once per container opened, so counting from the start of the line
|
package/src/markdown.ts
CHANGED
|
@@ -236,4 +236,4 @@ export type { TranslationPart, TranslationParts } from './translate'
|
|
|
236
236
|
// VERSION is this package's version. It MUST equal package.json "version":
|
|
237
237
|
// the release orchestrator rewrites both, and the version test fails the
|
|
238
238
|
// build if they drift. Mirrors `const VERSION` in go/markdown.go.
|
|
239
|
-
const VERSION = '0.7.
|
|
239
|
+
const VERSION = '0.7.12'
|
package/src/translate.ts
CHANGED
|
@@ -11,6 +11,7 @@ type TranslationPart = Readonly<{
|
|
|
11
11
|
type TranslationParts = Readonly<{
|
|
12
12
|
manifest: string
|
|
13
13
|
lift?: TranslationPart
|
|
14
|
+
embed?: TranslationPart
|
|
14
15
|
render?: TranslationPart
|
|
15
16
|
}>
|
|
16
17
|
|
|
@@ -53,15 +54,26 @@ const TRANSLATION: TranslationParts = Object.freeze({
|
|
|
53
54
|
"tree"
|
|
54
55
|
],
|
|
55
56
|
"writes": "records",
|
|
57
|
+
"root": "array",
|
|
58
|
+
"schema": "markdown-ast",
|
|
56
59
|
"lift": "alchemy/lift.alc",
|
|
57
60
|
"render": "alchemy/render.alc",
|
|
58
61
|
"loss": [
|
|
59
|
-
"
|
|
60
|
-
"
|
|
62
|
+
"The rows are the elements of the root array, and a root of another kind is written as one row.",
|
|
63
|
+
"The columns are the first row's, an object's keys or an array's positions labelled 0, 1 and so on, so a member or position of a later row that the first row lacks is not written, and one the first row has and a later row lacks is an empty cell.",
|
|
64
|
+
"When the first row is a scalar there is one column, named value, and every row is written whole in it, an array or an object as its compact JSON text.",
|
|
65
|
+
"A table of no columns, such as the one an empty array or object makes, is written as the empty document, which reads back as the empty table.",
|
|
66
|
+
"Read as records, a document with no table is the empty table, of no columns and no rows.",
|
|
67
|
+
"Read as records, a document with several tables is its first table, and the tables after it are not read.",
|
|
68
|
+
"Inline markup in a cell is flattened to its text when it is read, an image to its alt text; a written cell escapes every character that can begin inline markup, so it reads back as the text it was.",
|
|
69
|
+
"A null and a missing cell are both written as an empty cell, so the two cannot be told apart, or from an empty string, when read back.",
|
|
70
|
+
"A nested array or object in a cell is written as its compact JSON text.",
|
|
71
|
+
"A number that is not finite is written as Infinity, -Infinity or NaN, and as null inside a nested array or object, since JSON has no spelling for one.",
|
|
72
|
+
"Every value is written as text, so a number or a boolean reads back as a string.",
|
|
61
73
|
"Column alignment is not kept.",
|
|
62
74
|
"A line break in a cell is written as a space.",
|
|
63
|
-
"
|
|
64
|
-
"A U+0000 in a cell is written as
|
|
75
|
+
"Whitespace at either end of a cell is not kept, as the reader trims it: the space, the tab, U+00A0, U+FEFF, U+2028, U+2029 and the other Unicode space separators, though not U+0085.",
|
|
76
|
+
"A U+0000 in a cell is written as U+FFFD, the character a Markdown reader puts in its place, so it reads back as U+FFFD."
|
|
65
77
|
]
|
|
66
78
|
}
|
|
67
79
|
}
|
|
@@ -91,26 +103,36 @@ const TRANSLATION: TranslationParts = Object.freeze({
|
|
|
91
103
|
; cell of text beside emphasis, a link, an image, inline HTML or an
|
|
92
104
|
; autolink is their texts run together, \`Bob *b*\` as \`Bob b\`.
|
|
93
105
|
;
|
|
94
|
-
;
|
|
95
|
-
; the
|
|
96
|
-
;
|
|
106
|
+
; A Markdown document is read as records through its table and nothing
|
|
107
|
+
; else, so the first table is the one read: a table after it is not
|
|
108
|
+
; read, its rows and cells passed over as any other node's. A document
|
|
109
|
+
; with no table is read as the empty table, a schema of no columns, no
|
|
110
|
+
; row and \`table-end\`, which the render writes back as the empty
|
|
111
|
+
; document. The manifest's loss lines say both.
|
|
97
112
|
;
|
|
98
113
|
; The state is one vector, [stack phase seen in-cell runs cells]:
|
|
99
114
|
; stack the open containers, one marker each: \`:array\`, \`:node\` for
|
|
100
115
|
; an object whose type is not known yet or is any other node,
|
|
101
116
|
; and \`:table\`, \`:row\` or \`:cell\` once its \`type\` has named
|
|
102
|
-
; one,
|
|
117
|
+
; one, or \`:later\` for a table after the first, so that its
|
|
118
|
+
; end is known when its object ends;
|
|
103
119
|
; phase \`:before\` the table, \`:header\` inside it until its first
|
|
104
|
-
; row ends, \`:body\` once the schema is written, \`:after\` it
|
|
120
|
+
; row ends, \`:body\` once the schema is written, \`:after\` it,
|
|
121
|
+
; and \`:later\` inside a table after it, which is not read;
|
|
105
122
|
; seen what the last key was, \`:type\`, \`:text\` (a \`value\` or an
|
|
106
|
-
; \`alt\`) or \`:other\`, so that the scalar after it is classified
|
|
123
|
+
; \`alt\`) or \`:other\`, so that the scalar after it is classified,
|
|
124
|
+
; and \`:none\` before the first event, so that events with no
|
|
125
|
+
; value at all are told from a document with no table;
|
|
107
126
|
; in-cell whether a cell is open, so that text under it is the cell's;
|
|
108
127
|
; runs the open cell's runs of text, in order;
|
|
109
128
|
; cells the open row's cells, as wide as one row.
|
|
110
129
|
; It grows with the document's nesting and with one row's width, never
|
|
111
|
-
; with the table's length: a row is emitted when its
|
|
112
|
-
;
|
|
113
|
-
;
|
|
130
|
+
; with the table's length or the document's: a row is emitted when its
|
|
131
|
+
; object ends and dropped, and a later table keeps nothing. Events no
|
|
132
|
+
; tree has (a key outside an object, an end with nothing open), and
|
|
133
|
+
; events of a node where the reader's tree never puts one (a row or a
|
|
134
|
+
; cell outside a table, a table inside one), fail with
|
|
135
|
+
; PROTOCOL_ORDER_ERROR, saying so.
|
|
114
136
|
|
|
115
137
|
; A column record of the TableRows protocol, as the standard library's
|
|
116
138
|
; \`public-column\` makes one.
|
|
@@ -150,31 +172,35 @@ def markdown-mark [marker stack]
|
|
|
150
172
|
push marker (pop stack)
|
|
151
173
|
|
|
152
174
|
; The scalar after \`type\`: the three nodes the lift reads leave their
|
|
153
|
-
; marker on the stack and move the phase;
|
|
175
|
+
; marker on the stack and move the phase; a table after the first leaves
|
|
176
|
+
; \`:later\`, and its rows and cells, like any other node, stay \`:node\`.
|
|
154
177
|
def markdown-node [name stack phase in-cell runs cells]
|
|
155
178
|
match name
|
|
156
179
|
case "table"
|
|
157
180
|
match phase
|
|
158
181
|
case :before (transition [(markdown-mark :table stack) :header :other in-cell runs cells] [])
|
|
159
|
-
case :after (
|
|
160
|
-
case _ (fail "the events hold a table inside a table, which the reader's tree never has")
|
|
182
|
+
case :after (transition [(markdown-mark :later stack) :later :other in-cell runs cells] [])
|
|
183
|
+
case _ (fail :protocol-order "the events hold a table inside a table, which the reader's tree never has")
|
|
161
184
|
case "tableRow"
|
|
162
185
|
match phase
|
|
163
|
-
case :before (fail "the events hold a table row outside a table, which the reader's tree never has")
|
|
164
|
-
case :after (fail "the events hold a table row outside a table, which the reader's tree never has")
|
|
186
|
+
case :before (fail :protocol-order "the events hold a table row outside a table, which the reader's tree never has")
|
|
187
|
+
case :after (fail :protocol-order "the events hold a table row outside a table, which the reader's tree never has")
|
|
188
|
+
case :later (transition [stack phase :other in-cell runs cells] [])
|
|
165
189
|
case _ (transition [(markdown-mark :row stack) phase :other in-cell runs []] [])
|
|
166
190
|
case "tableCell"
|
|
167
191
|
match phase
|
|
168
|
-
case :before (fail "the events hold a table cell outside a table, which the reader's tree never has")
|
|
169
|
-
case :after (fail "the events hold a table cell outside a table, which the reader's tree never has")
|
|
192
|
+
case :before (fail :protocol-order "the events hold a table cell outside a table, which the reader's tree never has")
|
|
193
|
+
case :after (fail :protocol-order "the events hold a table cell outside a table, which the reader's tree never has")
|
|
194
|
+
case :later (transition [stack phase :other in-cell runs cells] [])
|
|
170
195
|
case _
|
|
171
196
|
if in-cell
|
|
172
|
-
fail "the events hold a table cell inside a cell, which the reader's tree never has"
|
|
197
|
+
fail :protocol-order "the events hold a table cell inside a cell, which the reader's tree never has"
|
|
173
198
|
transition [(markdown-mark :cell stack) phase :other true [] cells] []
|
|
174
199
|
case _ (transition [stack phase :other in-cell runs cells] [])
|
|
175
200
|
|
|
176
201
|
; An object's end: a cell joins its row, a row is the schema or a
|
|
177
|
-
; record, the table is done, and any other
|
|
202
|
+
; record, the table is done, a later table is passed over, and any other
|
|
203
|
+
; node is dropped.
|
|
178
204
|
def markdown-close [stack phase in-cell runs cells]
|
|
179
205
|
match (markdown-top stack)
|
|
180
206
|
case :cell
|
|
@@ -187,9 +213,11 @@ def markdown-close [stack phase in-cell runs cells]
|
|
|
187
213
|
transition [(pop stack) phase :other in-cell runs []] [(row cells)]
|
|
188
214
|
case :table
|
|
189
215
|
transition [(pop stack) :after :other in-cell runs cells] []
|
|
216
|
+
case :later
|
|
217
|
+
transition [(pop stack) :after :other in-cell runs cells] []
|
|
190
218
|
case :node
|
|
191
219
|
transition [(pop stack) phase :other in-cell runs cells] []
|
|
192
|
-
case _ (fail "the events end an object that is not open, which a tree's never do")
|
|
220
|
+
case _ (fail :protocol-order "the events end an object that is not open, which a tree's never do")
|
|
193
221
|
|
|
194
222
|
def markdown-event [stack phase seen in-cell runs cells event]
|
|
195
223
|
match event
|
|
@@ -199,8 +227,8 @@ def markdown-event [stack phase seen in-cell runs cells event]
|
|
|
199
227
|
transition [(push :array stack) phase :other in-cell runs cells] []
|
|
200
228
|
case (key name)
|
|
201
229
|
match (markdown-top stack)
|
|
202
|
-
case :none (fail "the events hold a key outside an object, which a tree's never do")
|
|
203
|
-
case :array (fail "the events hold a key inside an array, which a tree's never do")
|
|
230
|
+
case :none (fail :protocol-order "the events hold a key outside an object, which a tree's never do")
|
|
231
|
+
case :array (fail :protocol-order "the events hold a key inside an array, which a tree's never do")
|
|
204
232
|
case _ (transition [stack phase (markdown-seen name) in-cell runs cells] [])
|
|
205
233
|
case (scalar value)
|
|
206
234
|
match seen
|
|
@@ -214,27 +242,34 @@ def markdown-event [stack phase seen in-cell runs cells event]
|
|
|
214
242
|
case array-end
|
|
215
243
|
match (markdown-top stack)
|
|
216
244
|
case :array (transition [(pop stack) phase :other in-cell runs cells] [])
|
|
217
|
-
case _ (fail "the events end an array that is not open, which a tree's never do")
|
|
245
|
+
case _ (fail :protocol-order "the events end an array that is not open, which a tree's never do")
|
|
218
246
|
|
|
219
247
|
def markdown-lift-step [s event]
|
|
220
248
|
match s
|
|
221
249
|
case [stack phase seen in-cell runs cells]
|
|
222
250
|
markdown-event stack phase seen in-cell runs cells event
|
|
223
251
|
|
|
252
|
+
; What the end of the events adds once every container is closed: the
|
|
253
|
+
; table's end, or, for a document with no table, the empty table.
|
|
254
|
+
def markdown-lift-end [stack outputs]
|
|
255
|
+
match (count stack)
|
|
256
|
+
case 0 outputs
|
|
257
|
+
case _ (fail :protocol-order "the events ended inside a container, which a tree's never do")
|
|
258
|
+
|
|
224
259
|
def markdown-lift-finish [s]
|
|
225
260
|
match s
|
|
226
261
|
case [stack phase seen in-cell runs cells]
|
|
227
|
-
match
|
|
228
|
-
case :
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
case
|
|
232
|
-
|
|
233
|
-
|
|
262
|
+
match seen
|
|
263
|
+
case :none (fail :protocol-order "the events hold no value, where a tree's hold one")
|
|
264
|
+
case _
|
|
265
|
+
match phase
|
|
266
|
+
case :after (markdown-lift-end stack [table-end])
|
|
267
|
+
case :before (markdown-lift-end stack [(schema []) table-end])
|
|
268
|
+
case _ (fail :protocol-order "the events ended inside a table, which a tree's never do")
|
|
234
269
|
|
|
235
270
|
; The lift: the document's events in, the table's records out.
|
|
236
271
|
def markdown-lift [input]
|
|
237
|
-
scan-emit [[] :before :
|
|
272
|
+
scan-emit [[] :before :none false [] []] markdown-lift-step markdown-lift-finish (events input)
|
|
238
273
|
` }),
|
|
239
274
|
render: Object.freeze({ entry: "markdown-render", source: `; Markdown's render: a table's records, the TableRows protocol (one
|
|
240
275
|
; \`schema\`, a \`row\` per record and \`table-end\`), written as one GFM pipe
|
|
@@ -247,45 +282,69 @@ def markdown-lift [input]
|
|
|
247
282
|
; \`| --- | --- |\`, and a row per record, each line ended by a line feed
|
|
248
283
|
; and every cell between \`| \` and \` |\`. A cell is its value's text as
|
|
249
284
|
; the CSV renderer writes it (\`scalar-text\`: a string as it is, a number
|
|
250
|
-
; by its lexeme,
|
|
285
|
+
; by its lexeme, or by its word, \`Infinity\`, \`-Infinity\` or \`NaN\`, when
|
|
286
|
+
; it is not finite, a boolean by its name, null and a missing cell as
|
|
251
287
|
; nothing, a vector or a record as its compact JSON text), with every
|
|
252
|
-
; backslash doubled and every
|
|
253
|
-
;
|
|
254
|
-
;
|
|
255
|
-
;
|
|
256
|
-
;
|
|
257
|
-
;
|
|
258
|
-
;
|
|
259
|
-
;
|
|
260
|
-
;
|
|
261
|
-
;
|
|
262
|
-
;
|
|
288
|
+
; backslash doubled, and every character that can begin inline markup
|
|
289
|
+
; escaped with a backslash, as CommonMark lets any ASCII punctuation be
|
|
290
|
+
; escaped: the pipe, which the reader's split skips after a backslash
|
|
291
|
+
; (so its escape holds only when a backslash before it is itself
|
|
292
|
+
; escaped), the backtick of a code span, the \`*\` and \`_\` of emphasis,
|
|
293
|
+
; the brackets of a link, an image or a footnote, the \`<\` of an autolink
|
|
294
|
+
; or of raw HTML, the \`&\` of an entity or numeric character reference,
|
|
295
|
+
; and the \`~\` of GFM's strikethrough. The reader turns each escape back
|
|
296
|
+
; into its character, so a written cell reads back as the text it was;
|
|
297
|
+
; a URL that GFM reads as an autolink reads back as its own text, which
|
|
298
|
+
; is the link's. Every line break is replaced by a space, since a row is
|
|
299
|
+
; one line, and a U+0000 is written as U+FFFD, the character CommonMark
|
|
300
|
+
; has every reader put in its place; the loss declaration says both.
|
|
301
|
+
; Alignment is not written: every column's delimiter is \`---\`.
|
|
302
|
+
;
|
|
303
|
+
; A table of no columns, the one an empty array or object makes, has no
|
|
304
|
+
; pipe table, since a row needs at least one cell: it is written as the
|
|
305
|
+
; empty document, nothing at all, and so are its rows, which have no
|
|
306
|
+
; cells. The lift reads that document back as the empty table, of no
|
|
307
|
+
; columns and no rows.
|
|
263
308
|
;
|
|
264
309
|
; The state is one marker: \`:start\` before the schema, the schema's
|
|
265
310
|
; width (a number) while rows may follow, and \`:ended\` after
|
|
266
311
|
; \`table-end\`, so that a stream which breaks the protocol (a row before
|
|
267
312
|
; the schema, a second schema, a row of another width, anything after
|
|
268
|
-
; the end, no end) fails with
|
|
269
|
-
; being written. The check is this file's rather than
|
|
270
|
-
; whose refusals speak of CSV.
|
|
271
|
-
; needs at least one cell, so such a table has no Markdown form.
|
|
313
|
+
; the end, no end) fails with PROTOCOL_ORDER_ERROR, saying so, rather
|
|
314
|
+
; than being written. The check is this file's rather than
|
|
315
|
+
; \`csv-table\`'s, whose refusals speak of CSV.
|
|
272
316
|
|
|
273
317
|
; What \`scalar-text\` reads: null and a missing cell are written as
|
|
274
318
|
; nothing, where the CSV renderer's \`csv-options\` map a missing cell to
|
|
275
|
-
; an error.
|
|
319
|
+
; an error, and a number that is not finite as its word.
|
|
276
320
|
def markdown-options
|
|
277
321
|
record
|
|
278
322
|
entry :null-text ""
|
|
279
323
|
entry :missing ""
|
|
324
|
+
entry :non-finite :literal
|
|
280
325
|
|
|
281
|
-
; A cell's text, as it stands between the pipes
|
|
326
|
+
; A cell's text, as it stands between the pipes: the backslashes doubled
|
|
327
|
+
; first, so that the escapes written after them stay single.
|
|
282
328
|
def markdown-cell [cell]
|
|
283
329
|
replace-text "\\r" " "
|
|
284
330
|
replace-text "\\n" " "
|
|
285
331
|
replace-text "\\r\\n" " "
|
|
286
|
-
replace-text "
|
|
287
|
-
|
|
288
|
-
|
|
332
|
+
replace-text "\\u0000" "\\ufffd"
|
|
333
|
+
markdown-escape
|
|
334
|
+
replace-text "\\\\" "\\\\\\\\"
|
|
335
|
+
scalar-text markdown-options cell
|
|
336
|
+
|
|
337
|
+
; Every character that can begin inline markup, escaped with a backslash.
|
|
338
|
+
def markdown-escape [cell-text]
|
|
339
|
+
replace-text "~" "\\\\~"
|
|
340
|
+
replace-text "&" "\\\\&"
|
|
341
|
+
replace-text "<" "\\\\<"
|
|
342
|
+
replace-text "]" "\\\\]"
|
|
343
|
+
replace-text "[" "\\\\["
|
|
344
|
+
replace-text "_" "\\\\_"
|
|
345
|
+
replace-text "*" "\\\\*"
|
|
346
|
+
replace-text "\`" "\\\\\`"
|
|
347
|
+
replace-text "|" "\\\\|" cell-text
|
|
289
348
|
|
|
290
349
|
def markdown-label [column]
|
|
291
350
|
markdown-cell (get :label column)
|
|
@@ -303,38 +362,45 @@ def markdown-delimiter [width]
|
|
|
303
362
|
repeat width "| --- "
|
|
304
363
|
"|\\n"
|
|
305
364
|
|
|
365
|
+
; A record's line in a table \`width\` columns wide, or none in a table of
|
|
366
|
+
; no columns, which is written as the empty document.
|
|
367
|
+
def markdown-row [width cells]
|
|
368
|
+
match width
|
|
369
|
+
case 0 []
|
|
370
|
+
case _ [(markdown-line (map markdown-cell cells))]
|
|
371
|
+
|
|
306
372
|
def markdown-render-step [s event]
|
|
307
373
|
match event
|
|
308
374
|
case (schema columns)
|
|
309
375
|
match s
|
|
310
376
|
case :start
|
|
311
377
|
match (count columns)
|
|
312
|
-
case 0 (
|
|
378
|
+
case 0 (transition 0 [])
|
|
313
379
|
case _
|
|
314
380
|
transition (count columns)
|
|
315
381
|
vector
|
|
316
382
|
markdown-line (map markdown-label columns)
|
|
317
383
|
markdown-delimiter (count columns)
|
|
318
|
-
case _ (fail "the events hold a second schema, where a table's hold one")
|
|
384
|
+
case _ (fail :protocol-order "the events hold a second schema, where a table's hold one")
|
|
319
385
|
case (row cells)
|
|
320
386
|
match s
|
|
321
|
-
case :start (fail "the events hold a row before the schema, which a table's never do")
|
|
322
|
-
case :ended (fail "the events hold a row after table-end, which a table's never do")
|
|
387
|
+
case :start (fail :protocol-order "the events hold a row before the schema, which a table's never do")
|
|
388
|
+
case :ended (fail :protocol-order "the events hold a row after table-end, which a table's never do")
|
|
323
389
|
case _
|
|
324
390
|
match (compare (count cells) s)
|
|
325
|
-
case :equal (transition s
|
|
326
|
-
case _ (fail "the events hold a row that is not as wide as the schema, which a table's never do")
|
|
391
|
+
case :equal (transition s (markdown-row s cells))
|
|
392
|
+
case _ (fail :protocol-order "the events hold a row that is not as wide as the schema, which a table's never do")
|
|
327
393
|
case table-end
|
|
328
394
|
match s
|
|
329
|
-
case :start (fail "the events end before the schema, which a table's never do")
|
|
330
|
-
case :ended (fail "the events hold a second table-end, which a table's never do")
|
|
395
|
+
case :start (fail :protocol-order "the events end before the schema, which a table's never do")
|
|
396
|
+
case :ended (fail :protocol-order "the events hold a second table-end, which a table's never do")
|
|
331
397
|
case _ (transition :ended [])
|
|
332
398
|
|
|
333
399
|
def markdown-render-finish [s]
|
|
334
400
|
match s
|
|
335
401
|
case :ended []
|
|
336
|
-
case :start (fail "the events hold no schema, where a table's hold one first")
|
|
337
|
-
case _ (fail "the events ended before table-end, which a table's never do")
|
|
402
|
+
case :start (fail :protocol-order "the events hold no schema, where a table's hold one first")
|
|
403
|
+
case _ (fail :protocol-order "the events ended before table-end, which a table's never do")
|
|
338
404
|
|
|
339
405
|
; The render: the table's records in, the pipe table's text out.
|
|
340
406
|
def markdown-render [input]
|