@thi.ng/hiccup-markdown 3.0.1 → 3.2.0
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/CHANGELOG.md +36 -1
- package/README.md +123 -50
- package/api.d.ts +33 -12
- package/package.json +8 -5
- package/parse.js +94 -57
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2023-03-
|
|
3
|
+
- **Last updated**: 2023-03-07T14:54:11Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,41 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
## [3.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hiccup-markdown@3.2.0) (2023-03-07)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- update parse grammar ([e0be40a](https://github.com/thi-ng/umbrella/commit/e0be40a))
|
|
17
|
+
- char escapes now usable in almost all situs
|
|
18
|
+
(excl. metadata for code/custom blocks)
|
|
19
|
+
- add support for these HTML tags:
|
|
20
|
+
- comments `<!-- ... -->`
|
|
21
|
+
- `<sub>` / `<sup>`
|
|
22
|
+
- add tests
|
|
23
|
+
- update parse grammar & handlers ([7bd4edb](https://github.com/thi-ng/umbrella/commit/7bd4edb))
|
|
24
|
+
- update TransformCtx, add .column & .align fields
|
|
25
|
+
- update table row/cell handlers
|
|
26
|
+
- update olitem handler (index now a string)
|
|
27
|
+
- this is to support alphabetical ordered lists
|
|
28
|
+
- add `<sub>`/`<sup>` handlers
|
|
29
|
+
- update tests
|
|
30
|
+
- update docs
|
|
31
|
+
- update char escapes & inline format nesting rules ([2fde69b](https://github.com/thi-ng/umbrella/commit/2fde69b))
|
|
32
|
+
- allow nested kbd/sub/sup elements
|
|
33
|
+
- update char escape rules for inline code, codeblocks, custom blocks & meta blocks
|
|
34
|
+
- update __trimBody() helper to remove isolate trailing WS
|
|
35
|
+
- add/update tests
|
|
36
|
+
|
|
37
|
+
## [3.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hiccup-markdown@3.1.0) (2023-03-05)
|
|
38
|
+
|
|
39
|
+
#### 🚀 Features
|
|
40
|
+
|
|
41
|
+
- add anchor ID syntax support for headings ([86ce79e](https://github.com/thi-ng/umbrella/commit/86ce79e))
|
|
42
|
+
- update parse grammar & hd parser
|
|
43
|
+
- support for `{#id}` suffixes for defining heading anchor IDs
|
|
44
|
+
- only auto-generate anchor IDs if not explicitly specified
|
|
45
|
+
- update tests
|
|
46
|
+
|
|
12
47
|
# [3.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hiccup-markdown@3.0.0) (2023-02-27)
|
|
13
48
|
|
|
14
49
|
#### 🛑 Breaking changes
|
package/README.md
CHANGED
|
@@ -13,10 +13,15 @@ This project is part of the
|
|
|
13
13
|
- [Parser](#parser)
|
|
14
14
|
- [Basic features](#basic-features)
|
|
15
15
|
- [Additional syntax & parser features/restrictions](#additional-syntax--parser-featuresrestrictions)
|
|
16
|
-
- [
|
|
17
|
-
- [Code block headers](#code-block-headers)
|
|
16
|
+
- [Code blocks](#code-blocks)
|
|
18
17
|
- [Custom blocks](#custom-blocks)
|
|
18
|
+
- [Escaping control characters](#escaping-control-characters)
|
|
19
|
+
- [Formatting](#formatting)
|
|
19
20
|
- [Headings with anchor IDs](#headings-with-anchor-ids)
|
|
21
|
+
- [Heading with anchor {#custom-id-123}](#heading-with-anchor-custom-id-123)
|
|
22
|
+
- [Images](#images)
|
|
23
|
+
- [Link formats](#link-formats)
|
|
24
|
+
- [Lists](#lists)
|
|
20
25
|
- [Metadata](#metadata)
|
|
21
26
|
- [Customizing tag transforms](#customizing-tag-transforms)
|
|
22
27
|
- [Serializing to HTML](#serializing-to-html)
|
|
@@ -25,6 +30,7 @@ This project is part of the
|
|
|
25
30
|
- [Behaviors](#behaviors)
|
|
26
31
|
- [Usage examples](#usage-examples)
|
|
27
32
|
- [Status](#status)
|
|
33
|
+
- [Related packages](#related-packages)
|
|
28
34
|
- [Installation](#installation)
|
|
29
35
|
- [Dependencies](#dependencies)
|
|
30
36
|
- [Usage examples](#usage-examples)
|
|
@@ -36,7 +42,8 @@ This project is part of the
|
|
|
36
42
|
|
|
37
43
|
Markdown parser & serializer from/to Hiccup format. This is a support package for [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup).
|
|
38
44
|
|
|
39
|
-
**⚠️ IMPORTANT: With v3.0.0 the parser implementation underwent a complete
|
|
45
|
+
**⚠️ IMPORTANT: With v3.0.0 the parser implementation underwent a complete
|
|
46
|
+
rewrite (with breaking changes, but lots of improvements). ⚠️**
|
|
40
47
|
|
|
41
48
|
This package provides both a customizable
|
|
42
49
|
[Markdown](https://en.wikipedia.org/wiki/Markdown)-to-[Hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup)
|
|
@@ -44,48 +51,47 @@ parser and an extensible Hiccup-to-Markdown converter.
|
|
|
44
51
|
|
|
45
52
|
## Parser
|
|
46
53
|
|
|
54
|
+
Sadly, none of the available Markdown flavors have ever been designed with much
|
|
55
|
+
consistency and/or ease-of-implementation/parsing aspects in mind. The result is
|
|
56
|
+
a proliferation of Markdown-ish flavors, even though there've been attempts to
|
|
57
|
+
standardize the syntax.
|
|
58
|
+
|
|
47
59
|
### Basic features
|
|
48
60
|
|
|
49
|
-
The parser
|
|
50
|
-
|
|
51
|
-
features and some useful [additional
|
|
61
|
+
The parser provided here is _not_ aimed at supporting **all** of Markdown's (or
|
|
62
|
+
CommonMark's) quirky syntax features, but restricts itself to a large _sane
|
|
63
|
+
subset_ of features and some useful [additional
|
|
52
64
|
features](#additional-syntax--parser-featuresrestrictions) not part of the
|
|
53
|
-
standard syntax.
|
|
54
|
-
|
|
55
|
-
| Feature | Comments
|
|
56
|
-
|
|
57
|
-
| Blockquotes | Nestable, support for inline formatting and forced line breaks (trailing
|
|
58
|
-
| Code blocks | GFM style only (triple backtick prefix), w/ mandatory language hint & optional extra headers information
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
65
|
+
standard/common syntax.
|
|
66
|
+
|
|
67
|
+
| Feature | Comments |
|
|
68
|
+
|---------------|-------------------------------------------------------------------------------------------------------------------------|
|
|
69
|
+
| Blockquotes | Nestable, support for inline formatting and forced line breaks (trailing backslash) |
|
|
70
|
+
| Code blocks | GFM style only (triple backtick prefix), w/ mandatory language hint & optional extra headers information |
|
|
71
|
+
| Escaping | Uniformly escape MD control characters via backslash, e.g. `\*` |
|
|
72
|
+
| Formatting | Nestable inline formats supported in paragraphs, headings, link labels, lists, blockquotes, tables: |
|
|
73
|
+
| | **bold**, _italic_, `code`, ~~strike~~ |
|
|
74
|
+
| | <kbd>Key</kbd>, <sub>subscript</sub> and <sup>super</sup> |
|
|
75
|
+
| Footnotes | Supported and stored separately in parse context for further processing |
|
|
76
|
+
| Headings | ATX-style only (`#` line prefix), optional anchor ID (via `{#custom-id}` suffix), levels 1-6 then fallback to paragraph |
|
|
77
|
+
| Horiz. Rulers | Only dash supported (e.g. `---`), min 3 chars required, length retained for downstream transformations |
|
|
78
|
+
| HTML elements | Only `<kbd>`, `<sub>` `<sup>` |
|
|
79
|
+
| Images | Alt text is required, image can be used in link labels, optional title suffix |
|
|
80
|
+
| Links | Supports `[label](target)`, `[label][ref]`, `[[page id]]` or `[[page id\|label]]` style links, inline formats in label |
|
|
81
|
+
| Lists | Ordered & unordered, nestable, inline formatting, line breaks, GFM todo list items |
|
|
82
|
+
| Paragraphs | Support for forced line breaks (trailing backslash) |
|
|
83
|
+
| Tables | Support for column alignments, nestable inline formatting (no nested block elements) |
|
|
84
|
+
|
|
85
|
+
**Please visit the [interactive Markdown parser/editor
|
|
86
|
+
playground](https://demo.thi.ng/umbrella/markdown/) for further
|
|
87
|
+
details/examples...**
|
|
69
88
|
|
|
70
89
|
### Additional syntax & parser features/restrictions
|
|
71
90
|
|
|
72
|
-
####
|
|
73
|
-
|
|
74
|
-
To avoid ambiguity and simplify nesting, only the following formatting syntax is
|
|
75
|
-
supported for bold & italic:
|
|
76
|
-
|
|
77
|
-
- `**bold**`
|
|
78
|
-
- `_italic_`
|
|
91
|
+
#### Code blocks
|
|
79
92
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
For keyboard commands `<kbd>` can be used, e.g.:\
|
|
83
|
-
`<kbd>Control</kbd> + <kbd>R</kbd>`
|
|
84
|
-
|
|
85
|
-
#### Code block headers
|
|
86
|
-
|
|
87
|
-
In addition to the mandatory language hint, code blocks support optional user
|
|
88
|
-
defined headers/metadata. Items will be separated by spaces (e.g. see
|
|
93
|
+
In addition to the **mandatory language hint**, code blocks support optional
|
|
94
|
+
user defined headers/metadata. Items will be separated by spaces (e.g. see
|
|
89
95
|
[@thi.ng/tangle](https://github.com/thi-ng/umbrella/tree/develop/packages/tangle)
|
|
90
96
|
for concrete use cases).
|
|
91
97
|
|
|
@@ -100,8 +106,8 @@ layout breakage)
|
|
|
100
106
|
|
|
101
107
|
#### Custom blocks
|
|
102
108
|
|
|
103
|
-
Since the parser does not directly transform Markdown into HTML, blocks of
|
|
104
|
-
freeform content can be used to define arbitrary data structures (e.g. UI
|
|
109
|
+
Since the parser does not directly transform Markdown into HTML, blocks of
|
|
110
|
+
custom freeform content can be used to define arbitrary data structures (e.g. UI
|
|
105
111
|
components, diagrams/visualizations etc.). Similarly to code blocks, custom
|
|
106
112
|
blocks are wrapped with `:::` and a type specifier:
|
|
107
113
|
|
|
@@ -128,30 +134,93 @@ transformer. The default handler merely creates an element like this:
|
|
|
128
134
|
**Tip:** Use a
|
|
129
135
|
[`defmulti()`](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
|
|
130
136
|
polymorphic function as tag transformer to elegantly handle multiple types of
|
|
131
|
-
custom blocks (in an extensible manner).
|
|
137
|
+
custom blocks (in an easily extensible manner).
|
|
138
|
+
|
|
139
|
+
#### Escaping control characters
|
|
140
|
+
|
|
141
|
+
Unlike the weird & hard-to-memorize escape rules in "standard" Markdown, here
|
|
142
|
+
we're taking a more uniform approach of exclusively using backslash escapes
|
|
143
|
+
(e.g. `\*`) to ensure various Markdown control characters are used verbatim.
|
|
144
|
+
Only the following minor exceptions apply:
|
|
145
|
+
|
|
146
|
+
1. In inline code sections only backticks (`\``) need to be escaped and
|
|
147
|
+
backslashes _can_ be escaped. All others chars are used as is.
|
|
148
|
+
2. In fenced code blocks only backticks can be escaped (e.g. if escaping the
|
|
149
|
+
triple-backtick block fence itself). Backslashes and others chars are used as is.
|
|
150
|
+
3. In custom blocks only colons (`:`) can be escaped (e.g. if escaping the
|
|
151
|
+
triple-colon block fence itself). All other chars are used as is.
|
|
152
|
+
4. In metadata blocks only `}` can be escaped. All other chars are used as is.
|
|
153
|
+
|
|
154
|
+
#### Formatting
|
|
155
|
+
|
|
156
|
+
To avoid ambiguity and simplify nesting, only the following formatting syntax is
|
|
157
|
+
supported for bold & italic:
|
|
158
|
+
|
|
159
|
+
- `**bold**`
|
|
160
|
+
- `_italic_`
|
|
161
|
+
- `code` (\`) and ~~strikethrough~~ (`~~`) as usual...
|
|
162
|
+
- `<kbd>` for keyboard shortcuts (e.g. <kbd>Control</kbd>)
|
|
163
|
+
- `<sub>` for <sub>subscript</sub>
|
|
164
|
+
- `<sup>` for <sup>superscript</sup>
|
|
132
165
|
|
|
133
166
|
#### Headings with anchor IDs
|
|
134
167
|
|
|
135
|
-
The
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
168
|
+
The parser supports `{#custom-id}`-style line suffixes for headings, which are
|
|
169
|
+
passed as separate `anchorID` param to the element handlers. If not specified in
|
|
170
|
+
the Markdown source, the parser auto-generates this ID (with no uniqueness
|
|
171
|
+
guarantee) based on
|
|
172
|
+
[slugifying](https://docs.thi.ng/umbrella/strings/functions/slugifyGH.html) the
|
|
173
|
+
heading's body content (Github readme compatible):
|
|
139
174
|
|
|
140
175
|
```text
|
|
141
176
|
# The **beautiful `code`**
|
|
177
|
+
|
|
178
|
+
## Heading with anchor {#custom-id-123}
|
|
142
179
|
```
|
|
143
180
|
|
|
144
181
|
Results in:
|
|
145
182
|
|
|
146
183
|
```js
|
|
147
184
|
// [
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
185
|
+
// [
|
|
186
|
+
// "h1",
|
|
187
|
+
// { id: "the-beautiful-code" },
|
|
188
|
+
// "The ",
|
|
189
|
+
// [ "strong", {}, "beautiful ", [ "code", {}, "code" ] ]
|
|
190
|
+
// ],
|
|
191
|
+
// [ "h2", { id: "custom-id-123" }, "Heading with anchor" ]
|
|
152
192
|
// ]
|
|
153
193
|
```
|
|
154
194
|
|
|
195
|
+
### Images
|
|
196
|
+
|
|
197
|
+
**Alt text for images is required**. Optional `title` attribute (e.g. for hover
|
|
198
|
+
tooltip or caption) can be given in quotes after the image URL. For example:
|
|
199
|
+
|
|
200
|
+
```markdown
|
|
201
|
+

|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Link formats
|
|
205
|
+
|
|
206
|
+
The following link formats are supported:
|
|
207
|
+
|
|
208
|
+
1. `[label](target)`
|
|
209
|
+
2. `[label](target "title")`
|
|
210
|
+
3. `[label][ref-id]` - the reference ID will have to provided somewhere else in
|
|
211
|
+
the document or pre-defined via options given to the parser
|
|
212
|
+
4. `[[page name]]` - Wiki-style page reference, non-standard Markdown
|
|
213
|
+
5. `[[page name|label]]` - like 4., but with added link label
|
|
214
|
+
|
|
215
|
+
### Lists
|
|
216
|
+
|
|
217
|
+
- Ordered and unordered lists are supported
|
|
218
|
+
- Fully nestable
|
|
219
|
+
- Ordered lists start with a `1.` (digit or letter followed by a dot) prefix
|
|
220
|
+
- Unordered lists **must** use a `-` line prefix
|
|
221
|
+
- [ ] TODO list items
|
|
222
|
+
- [x] ...are supported as well
|
|
223
|
+
|
|
155
224
|
#### Metadata
|
|
156
225
|
|
|
157
226
|
Arbitrary metadata can be assigned to _any_ block level element:
|
|
@@ -442,6 +511,10 @@ More info [here](http://thi.ng/hiccup-markdown).
|
|
|
442
511
|
|
|
443
512
|
[Search or submit any issues for this package](https://github.com/thi-ng/umbrella/issues?q=%5Bhiccup-markdown%5D+in%3Atitle)
|
|
444
513
|
|
|
514
|
+
## Related packages
|
|
515
|
+
|
|
516
|
+
- [@thi.ng/markdown-table](https://github.com/thi-ng/umbrella/tree/develop/packages/markdown-table) - Markdown table formatter/generator with support for column alignments
|
|
517
|
+
|
|
445
518
|
## Installation
|
|
446
519
|
|
|
447
520
|
```bash
|
|
@@ -462,7 +535,7 @@ For Node.js REPL:
|
|
|
462
535
|
const hiccupMarkdown = await import("@thi.ng/hiccup-markdown");
|
|
463
536
|
```
|
|
464
537
|
|
|
465
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 4.
|
|
538
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 4.62 KB
|
|
466
539
|
|
|
467
540
|
## Dependencies
|
|
468
541
|
|
package/api.d.ts
CHANGED
|
@@ -110,11 +110,11 @@ export interface TagTransforms {
|
|
|
110
110
|
*
|
|
111
111
|
* @param ctx
|
|
112
112
|
* @param level
|
|
113
|
-
* @param
|
|
113
|
+
* @param anchorID
|
|
114
114
|
* @param body
|
|
115
115
|
* @param meta
|
|
116
116
|
*/
|
|
117
|
-
heading(ctx: TransformCtx, level: number,
|
|
117
|
+
heading(ctx: TransformCtx, level: number, anchorID: string, body: any[], meta?: any): any;
|
|
118
118
|
/**
|
|
119
119
|
* Horizontal rule handler. Also receives number of dashes used (e.g. to
|
|
120
120
|
* create different representations/styling)
|
|
@@ -189,7 +189,8 @@ export interface TagTransforms {
|
|
|
189
189
|
ol(ctx: TransformCtx, items: any[], meta?: any): any;
|
|
190
190
|
/**
|
|
191
191
|
* Handler for a single list item in an ordered list. The `index` arg is the
|
|
192
|
-
*
|
|
192
|
+
* raw item index specified in the MD source code for that item (e.g. a
|
|
193
|
+
* digit or letter).
|
|
193
194
|
*
|
|
194
195
|
* @remarks
|
|
195
196
|
* If the `attribs` object has a `__todo` attrib, the item is a task list
|
|
@@ -200,7 +201,7 @@ export interface TagTransforms {
|
|
|
200
201
|
* @param index
|
|
201
202
|
* @param body
|
|
202
203
|
*/
|
|
203
|
-
olitem(ctx: TransformCtx, attribs: TodoAttribs, index:
|
|
204
|
+
olitem(ctx: TransformCtx, attribs: TodoAttribs, index: string, body: any[]): any;
|
|
204
205
|
/**
|
|
205
206
|
* Handler for a paragraph of body content.
|
|
206
207
|
*
|
|
@@ -217,36 +218,54 @@ export interface TagTransforms {
|
|
|
217
218
|
*/
|
|
218
219
|
strike(ctx: TransformCtx, body: any[]): any;
|
|
219
220
|
/**
|
|
220
|
-
* Handler for
|
|
221
|
+
* Handler for subscript inline content.
|
|
222
|
+
*
|
|
223
|
+
* @param ctx
|
|
224
|
+
* @param body
|
|
225
|
+
*/
|
|
226
|
+
sub(ctx: TransformCtx, body: string): any;
|
|
227
|
+
/**
|
|
228
|
+
* Handler for superscript inline content.
|
|
229
|
+
*
|
|
230
|
+
* @param ctx
|
|
231
|
+
* @param body
|
|
232
|
+
*/
|
|
233
|
+
sup(ctx: TransformCtx, body: string): any;
|
|
234
|
+
/**
|
|
235
|
+
* Handler for a table container. The alignment settings for each column can
|
|
236
|
+
* be accessed via given context's {@link TransformCtx.align} array.
|
|
221
237
|
*
|
|
222
238
|
* @param ctx
|
|
223
|
-
* @param align
|
|
224
239
|
* @param head
|
|
225
240
|
* @param rows
|
|
226
241
|
* @param meta
|
|
227
242
|
*/
|
|
228
|
-
table(ctx: TransformCtx,
|
|
243
|
+
table(ctx: TransformCtx, head: any[], rows: any[], meta?: any): any;
|
|
229
244
|
/**
|
|
230
|
-
* Handler for a single table cell in a non-header row.
|
|
245
|
+
* Handler for a single table cell in a non-header row. The current column index can
|
|
246
|
+
* be accessed via given context's {@link TransformCtx.column} property.
|
|
231
247
|
*
|
|
232
248
|
* @param ctx
|
|
233
249
|
* @param body
|
|
234
250
|
*/
|
|
235
251
|
tableCell(ctx: TransformCtx, body: any[]): any;
|
|
236
252
|
/**
|
|
237
|
-
* Handler for a single table cell in the header row.
|
|
253
|
+
* Handler for a single table cell in the header row. The current column index can
|
|
254
|
+
* be accessed via given context's {@link TransformCtx.column} property.
|
|
238
255
|
*
|
|
239
256
|
* @param ctx
|
|
240
257
|
* @param body
|
|
241
258
|
*/
|
|
242
259
|
tableHead(ctx: TransformCtx, body: any[]): any;
|
|
243
260
|
/**
|
|
244
|
-
* Handler for a single table row. The
|
|
261
|
+
* Handler for a single table row. The current row index can be accessed via
|
|
262
|
+
* given context's {@link TransformCtx.row} property. The header row will
|
|
263
|
+
* have `index=0`. The first data row `index=1`.
|
|
245
264
|
*
|
|
246
265
|
* @param ctx
|
|
247
266
|
* @param body
|
|
248
267
|
*/
|
|
249
|
-
tableRow(ctx: TransformCtx,
|
|
268
|
+
tableRow(ctx: TransformCtx, cells: any[]): any;
|
|
250
269
|
/**
|
|
251
270
|
* Handler for an unordered list wrapper.
|
|
252
271
|
*
|
|
@@ -266,7 +285,7 @@ export interface TagTransforms {
|
|
|
266
285
|
* @param attribs
|
|
267
286
|
* @param body
|
|
268
287
|
*/
|
|
269
|
-
ulitem(ctx: TransformCtx, attribs: TodoAttribs,
|
|
288
|
+
ulitem(ctx: TransformCtx, attribs: TodoAttribs, body: any[]): any;
|
|
270
289
|
/**
|
|
271
290
|
* Handler for `[[page name]]` or `[[page name|label]]-style links.
|
|
272
291
|
*
|
|
@@ -291,6 +310,8 @@ export interface TransformCtx {
|
|
|
291
310
|
}[];
|
|
292
311
|
hasFootnotes: boolean;
|
|
293
312
|
meta?: any;
|
|
313
|
+
align: ColumnAlign[];
|
|
314
|
+
column: number;
|
|
294
315
|
row: number;
|
|
295
316
|
opts: ParseOpts;
|
|
296
317
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/hiccup-markdown",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Markdown parser & serializer from/to Hiccup format",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -35,16 +35,16 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@thi.ng/api": "^8.7.3",
|
|
38
|
-
"@thi.ng/arrays": "^2.5.
|
|
38
|
+
"@thi.ng/arrays": "^2.5.7",
|
|
39
39
|
"@thi.ng/checks": "^3.3.9",
|
|
40
40
|
"@thi.ng/defmulti": "^2.1.31",
|
|
41
41
|
"@thi.ng/emoji": "^0.1.0",
|
|
42
42
|
"@thi.ng/errors": "^2.2.12",
|
|
43
|
-
"@thi.ng/hiccup": "^4.2.
|
|
43
|
+
"@thi.ng/hiccup": "^4.2.36",
|
|
44
44
|
"@thi.ng/logger": "^1.4.9",
|
|
45
45
|
"@thi.ng/parse": "^2.2.28",
|
|
46
46
|
"@thi.ng/strings": "^3.4.1",
|
|
47
|
-
"@thi.ng/text-canvas": "^2.4.
|
|
47
|
+
"@thi.ng/text-canvas": "^2.4.32"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@microsoft/api-extractor": "^7.34.2",
|
|
@@ -93,7 +93,10 @@
|
|
|
93
93
|
},
|
|
94
94
|
"thi.ng": {
|
|
95
95
|
"parent": "@thi.ng/hiccup",
|
|
96
|
+
"related": [
|
|
97
|
+
"markdown-table"
|
|
98
|
+
],
|
|
96
99
|
"year": 2018
|
|
97
100
|
},
|
|
98
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "31dd56eba72edd73a3ced5002c0f5145ce3d42d6\n"
|
|
99
102
|
}
|
package/parse.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Downloaded @ 2023-
|
|
2
|
-
// Source: https://demo.thi.ng/umbrella/parse-playground/#
|
|
1
|
+
// Downloaded @ 2023-03-07T13:30:37.046Z
|
|
2
|
+
// Source: https://demo.thi.ng/umbrella/parse-playground/#l9oQo0ROTDE6IDxETkw-KyA9PiBkaXNjYXJkIDsKRE5MMjogPE5MPnsyLH0gOwpsYnI6ICdcXCchIDxOTD4hIDsKZXNjOiAnXFwnISAoJ18nIHwgJyonIHwgJ2AnIHwgJ34nIHwgJzonIHwgJy0nIHwgJzwnIHwgJz4nIHwgJ1snIHwgJ10nIHwgJygnIHwgJyknIHwgJ3snIHwgJ30nIHwgJyMnIHwgJy4nIHwgJ3wnIHwgJ1xcJykgOwpjZXNjOiAnXFwnISAoJ2AnfCAnXFwnKSA7CmNiZXNjOiAnXFwnISAnYCcgOwpjdWVzYzogJ1xcJyEgJzonIDsKbWVzYzogJ1xcJyEgJ30nIDsKaWRlbGltOiAoIiFbIiB8ICdbJyB8ICIqKiIgfCAnXycgfCAnYCcgfCAnPCcgfCAifn4iIHwgIiA6IiB8IDxsYnI-KSA7CmRlbGltOiAoPGlkZWxpbT4gfCA8RE5MMj4pIDsKZWJvZHk6ICg8ZXNjPnwuKSA7CmNib2R5OiAoPGNlc2M-fC4pIDsKY2Jib2R5OiAoPGNiZXNjPnwuKSA7CmN1Ym9keTogKDxjdWVzYz58LikgOwptYm9keTogKDxtZXNjPnwuKSA7CmJvZHk6IDxlYm9keT4oPy08ZGVsaW0-ISkgPT4gam9pbiA7Cmlib2R5OiA8ZWJvZHk-KD8tPGlkZWxpbT4hKSA9PiBqb2luIDsKCmNvbW1lbnQ6ICI8IS0tIiEgLig_KyItLT4iKSA9PiBkaXNjYXJkIDsKd2lraXJlZjogIltbIiEgPGVib2R5Pig_KyJdXSIhKSA9PiBqb2luIDsKZm5yZWY6ICJbXiIhIDxsYWJlbD4gOwpmbm90ZTogPExTVEFSVD4gIlteIiEgPGZubGFiZWw-IDxXUzE-IDxwYXJhPiA7CmZubGFiZWw6IDxlYm9keT4oPysiXToiISkgPT4gam9pbiA7CmxhYmVsOiA8ZWJvZHk-KD8rJ10nISkgPT4gam9pbiA7CnRhcmdldDogPGVib2R5Pig_KycpJyEpID0-IGpvaW4gOwpsaW5rOiAnWychIDxsaW5rbGFiZWw-ICcoJyEgPHRhcmdldD4gOwpsaW5rcmVmOiAnWychIDxsaW5rbGFiZWw-ICdbJyEgPGxhYmVsPiA7CmxpbmtkZWY6IDxMU1RBUlQ-ICdbJyEgPGxhYmVsPiAnOichIDxXUzE-IDxsZHRhcmdldD4gOwpsZHRhcmdldDogPGVib2R5Pig_KzxETkwxPikgPT4gam9pbiA7CmxpbmtsYWJlbDogKDxpbWc-IHwgPGJvbGQ-IHwgPGl0YWxpYz4gfCA8c3RyaWtlPiB8IDxjb2RlPiB8IDxlbW9qaT4gfCA8a2JkPiB8IDxzdWI-IHwgPHN1cD4gfCA8bGlua2JvZHk-KSogJ10nISA7CmxpbmtkZWxpbTogKCIhWyIgfCAnWycgfCAiKioiIHwgJ18nIHwgIn5-IiB8ICdgJyB8ICddJykgOwpsaW5rYm9keTogPGVib2R5Pig_LTxsaW5rZGVsaW0-ISkgPT4gam9pbiA7CmltZzogIiFbIiEgPGxhYmVsPiAnKCchIDx0YXJnZXQ-IDsKYm9sZDogIioqIiEgKDx3aWtpcmVmPiB8IDxpbWc-IHwgPGZucmVmPiB8IDxsaW5rcmVmPiB8IDxsaW5rPiB8IDxpdGFsaWM-IHwgPHN0cmlrZT4gfCA8Y29kZT4gfCA8ZW1vamk-IHwgPGtiZD4gfCA8c3ViPiB8IDxzdXA-IHwgPGlib2R5PikqICIqKiIhIDsKaXRhbGljOiAnXychICg8d2lraXJlZj4gfCA8aW1nPiB8IDxmbnJlZj4gfCA8bGlua3JlZj4gfCA8bGluaz4gfCA8Ym9sZD4gfCA8c3RyaWtlPiB8IDxjb2RlPiB8IDxlbW9qaT4gfCA8a2JkPiB8IDxzdWI-IHwgPHN1cD4gfCA8aWJvZHk-KSogJ18nISA7CnN0cmlrZTogIn5-IiEgKDx3aWtpcmVmPiB8IDxpbWc-IHwgPGZucmVmPiB8IDxsaW5rcmVmPiB8IDxsaW5rPiB8IDxib2xkPiB8IDxpdGFsaWM-IHwgPGNvZGU-IHwgPGVtb2ppPiB8IDxrYmQ-IHwgPHN1Yj4gfCA8c3VwPiB8IDxpYm9keT4pKiAifn4iISA7CmNvZGU6ICdgJyEgPGNib2R5Pig_KydgJyEpID0-IGpvaW4gOwprYmQ6ICI8a2JkPiIhIDxlYm9keT4oPysiPC9rYmQ-IiEpID0-IGpvaW4gOwpzdWI6ICI8c3ViPiIhIDxlYm9keT4oPysiPC9zdWI-IiEpID0-IGpvaW4gOwpzdXA6ICI8c3VwPiIhIDxlYm9keT4oPysiPC9zdXA-IiEpID0-IGpvaW4gOwplbW9qaTogJyAnPyAnOichICg8QUxQSEFfTlVNPiB8ICcrJykoPysnOichKSA9PiBqb2luIDsKcGFyYTogKDx3aWtpcmVmPiB8IDxpbWc-IHwgPGZucmVmPiB8IDxsaW5rcmVmPiB8IDxsaW5rPiB8IDxib2xkPiB8IDxpdGFsaWM-IHwgPHN0cmlrZT4gfCA8Y29kZT4gfCA8a2JkPiB8IDxzdWI-IHwgPHN1cD4gfCA8ZW1vamk-IHwgPGxicj4gfCA8Y29tbWVudD4gfCA8Ym9keT4pKiA8RE5MMj4hIDsKCmhkbGV2ZWw6ICcjJysgPT4gY291bnQgOwpoZGlkOiAieyMiISAoPEFMUEhBX05VTT4gfCAnLScpKyAnfSchID0-IGpvaW4gOwpoZGRlbGltOiAoPGlkZWxpbT4gfCA8Tkw-IHwgInsjIikgOwpoZGJvZHk6IDxlYm9keT4oPy08aGRkZWxpbT4hKSA9PiBqb2luIDsKaGQ6IDxMU1RBUlQ-IDxoZGxldmVsPiA8V1MwPgogICAgKDx3aWtpcmVmPiB8IDxpbWc-IHwgPGZucmVmPiB8IDxsaW5rPiB8IDxib2xkPiB8IDxpdGFsaWM-IHwgPHN0cmlrZT4gfCA8Y29kZT4gfCA8ZW1vamk-IHwgPGtiZD4gfCA8c3ViPiB8IDxzdXA-IHwgPGhkYm9keT4pKiA8aGRpZD4_IDxETkwxPiA7CgpsaWxldmVsOiAnICcqID0-IGNvdW50IDsKb2xpZDogKDxBTFBIQT4rfDxESUdJVD4rKSA9PiBqb2luIDsKdWxpbml0OiA8RE5MPiA8V1MwPiAnLSchIDsKb2xpbml0OiA8RE5MPiA8V1MwPiA8b2xpZD4hICcuJyEgOwpsaWRlbGltOiAoPGRlbGltPiB8IDx1bGluaXQ-IHwgPG9saW5pdD4pIDsKbGlib2R5OiA8ZWJvZHk-KD8tPGxpZGVsaW0-ISkgPT4gam9pbiA7CnRvZG86ICdbJyEgWyB4WF0gJ10nISA8V1MxPiA9PiBob2lzdFIgOwp1bGl0ZW06IDxMU1RBUlQ-IDxsaWxldmVsPiAiLSAiISA8dG9kbz4_CiAgICAgICAgKDx3aWtpcmVmPiB8IDxpbWc-IHwgPGZucmVmPiB8IDxsaW5rPiB8IDxib2xkPiB8IDxpdGFsaWM-IHwgPHN0cmlrZT4gfCA8Y29kZT4gfCA8ZW1vamk-IHwgPGtiZD4gfCA8c3ViPiB8IDxzdXA-IHwgPGxpYm9keT4gKSogPEROTD4gOwpvbGl0ZW06IDxMU1RBUlQ-IDxsaWxldmVsPiA8b2xpZD4gIi4gIiEgPHRvZG8-PwogICAgICAgICg8d2lraXJlZj4gfCA8aW1nPiB8IDxmbnJlZj4gfCA8bGluaz4gfCA8Ym9sZD4gfCA8aXRhbGljPiB8IDxzdHJpa2U-IHwgPGNvZGU-IHwgPGVtb2ppPiB8IDxrYmQ-IHwgPHN1Yj4gfCA8c3VwPiB8IDxsaWJvZHk-ICkqIDxETkw-IDsKbGlzdDogKDx1bGl0ZW0-IHwgPG9saXRlbT4pKyA8RE5MMT4gOwoKY2JkZWxpbTogPExTVEFSVD4gImBgYCIhIDsKY29kZWJsb2NrOiA8Y2JkZWxpbT4hIDxjb2RlbWV0YT4gPGNvZGVib2R5PiA8RE5MMT4gOwpjb2RlbWV0YTogLig_KzxOTD4hKSA9PiBqb2luIDsKY29kZWJvZHk6IDxjYmJvZHk-KD8rPGNiZGVsaW0-KSA9PiBqb2luIDsKCmN1ZGVsaW06IDxMU1RBUlQ-ICI6OjoiISA7CmN1c3RvbWJsb2NrOiA8Y3VkZWxpbT4hIDxjdXN0b21tZXRhPiA8Y3VzdG9tYm9keT4gPEROTDE-IDsKY3VzdG9tbWV0YTogLig_KzxOTD4hKSA9PiBqb2luIDsKY3VzdG9tYm9keTogPGN1Ym9keT4oPys8Y3VkZWxpbT4pID0-IGpvaW4gOwoKbWV0YWJsb2NrOiA8TFNUQVJUPiAie3t7IiEgPG1ldGFib2R5PiA8RE5MMT4gOwptZXRhYm9keTogPG1ib2R5Pig_KzxtZXRhZW5kPiEpID0-IGpvaW4gOwptZXRhZW5kOiAifX19IiA8TEVORD4gOwoKYnFsZXZlbDogJz4nKyA9PiBjb3VudCA7CmJxZGVsaW06ICg8aWRlbGltPiB8IDxOTD4pIDsKYnFib2R5OiA8ZWJvZHk-KD8tPGJxZGVsaW0-ISkgPT4gam9pbiA7CmJxbGluZTogPExTVEFSVD4gPGJxbGV2ZWw-ICcgJz8hCiAgICAgICAgKDx3aWtpcmVmPiB8IDxpbWc-IHwgPGZucmVmPiB8IDxsaW5rPiB8IDxib2xkPiB8IDxpdGFsaWM-IHwgPHN0cmlrZT4gfCA8Y29kZT4gfCA8ZW1vamk-IHwgPGtiZD4gfCA8c3ViPiB8IDxzdXA-IHwgPGJxbGJyPiB8IDxicWJvZHk-KSogPEROTD4gOwpicWxicjogJ1xcJyEoPy08RE5MPikgOwpicXVvdGU6IDxicWxpbmU-KyA8RE5MMT4gOwoKdGRlbGltOiAoPGlkZWxpbT4gfCAnfCcgKSA7CnRib2R5OiA8ZWJvZHk-KD8tPHRkZWxpbT4hKSA9PiBqb2luIDsKdGNlbGw6IDxXUzA-ICg8d2lraXJlZj4gfCA8aW1nPiB8IDxmbnJlZj4gfCA8bGluaz4gfCA8Ym9sZD4gfCA8aXRhbGljPiB8IDxzdHJpa2U-IHwgPGNvZGU-IHwgPGVtb2ppPiB8IDxrYmQ-IHwgPHN1Yj4gfCA8c3VwPiB8IDx0Ym9keT4gKSogJ3wnISA7CnRyb3c6IDxMU1RBUlQ-ICd8JyEgPHRjZWxsPig_KzxETkw-KSA7CnRhYmxlOiA8dHJvdz4rIDxETkwxPiA7CgpocjogIi0tIiAnLScrIDxETkwxPiA9PiBqb2luIDsKCm1haW46IDxXUzA-ICg8aGQ-IHwgPGxpc3Q-IHwgPGJxdW90ZT4gfCA8Y29kZWJsb2NrPiB8IDxjdXN0b21ibG9jaz4gfCA8bWV0YWJsb2NrPiB8IDx0YWJsZT4gfCA8aHI-IHwgPGZub3RlPiB8IDxsaW5rZGVmPiB8IDxjb21tZW50PiB8IDxwYXJhPiApKiA7pG1haW7aAtQjIEhlbGxvIFwhXFsgOndvcmxkOjpzbWlsZTpbXmFiY10geyNoZDF9CgojIyBhYmMgeyNoZDJ9CiMjIGRlZiA8c3VwPkNvbnRyb2w8L3N1cD4KCmEgXDwgYgoKTGV0IGBleHAyKHgpID0gMioqeGAKClByZXNzIDxrYmQ-Q29udHJvbDwva2JkPiArIDxrYmQ-Ujwva2JkPiB0byA8IS0tc2tpcC0tPiByZWxvYWQuCgo6OjphbGVydApUZXN0IFtsYWJlbF1bcmVmcmVmXQo6OjoKCi0tLQoKe3t7IHsiaWQiOiAxMjMsICJwcm90ZWN0ZWQiOiB0cnVlIH0gfX19ClNvIFtbc21pbGVfZm9vMTJdXSDwn5iNIHdoYXQncyBbdGhpc10oLi90aGlzLm1kKVteMl0gdGhlbjoKCkEgW2xpbmsgX3dpdGggKipuZXN0ZWQgfn5mb3JtYXR-fioqIGFuZCBgcmVmZXJlbmNlYF9dW3JlZnJlZl0uLi4KCmBgYHRzIHRhbmdsZTpubyBsbjp5ZXMKY29uc3QgcmUgPSAvW1xuXHJdKy9nOwovLyB0aGUgZW5kCmBgYAoKMS4gZm9vCiAgNC4gYmFyCiAgICAgYmF6IGFuZCBzbyBvbgogICAgIG11bHRpbGluZQoyLiBbIF0gdGFzawozLiBbeF0gKipkb25lKioKCj4gYmxvY2txdW90ZQo-IG11bHRpbGluZSB0b29cCj4-IG5lc3RlZAo-Pj4gbGV2ZWwgMwo-IC0tIHNvdXJjZQoKfCBmb28gfCBiYXIgfAp8Oi06fC06fAp8IFtbcmVmIzIyXV0gfCBgb25gICoqb2ZmKiogfAoKW15hYmNdOiBGb28gX2Jhcl8gYmF6CgpbXjJdOiBUT0RPCgpbcmVmcmVmXTogaHR0cDovL3RoaS5uZy8KW2Zvb106IC4vZm9vLm1kI2JhcgoK2VA8IS0tCmlnbm9yZQptdWx0aWxpbmUKLS0-CgoxMS4gYWJjCiAgLSB4eXoKMjEuIHh4eAogIGEuIGZvbwogICAgYi4gYmFyCjMxLiB5eXkKCtlSfCBjb2wxIHwgY29sMiB8CnwgLS0tLSB8IC0tLS06fAp8IDxrYmQ-Q3RybDwva2JkPiB8IDxzdXA-Ujwvc3VwPiBgW1thYmNcfGlkXV1gIHwKCrkqKjp3YXJuOiBhYmMKZGVmIDpvazoqKgoK2Ug-IGxpbmUxCj4-ICoqbGluZSAyKipcCj4-IGxpbmUgMmEKPj4gbGluZSAyYgo-PiAKPj4gbGluZSAyYwo-Pj4gbGluZSAzCgo
|
|
3
3
|
import { peek } from "@thi.ng/arrays/peek";
|
|
4
4
|
import { isArray } from "@thi.ng/checks/is-array";
|
|
5
5
|
import { isPlainObject } from "@thi.ng/checks/is-plain-object";
|
|
@@ -15,81 +15,97 @@ export const GRAMMAR = defGrammar(`
|
|
|
15
15
|
DNL1: <DNL>+ => discard ;
|
|
16
16
|
DNL2: <NL>{2,} ;
|
|
17
17
|
lbr: '\\\\'! <NL>! ;
|
|
18
|
-
esc: '\\\\'! ( '<' | '[' | '
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
esc: '\\\\'! ('_' | '*' | '\`' | '~' | ':' | '-' | '<' | '>' | '[' | ']' | '(' | ')' | '{' | '}' | '#' | '.' | '|' | '\\\\') ;
|
|
19
|
+
cesc: '\\\\'! ('\`'| '\\\\') ;
|
|
20
|
+
cbesc: '\\\\'! '\`' ;
|
|
21
|
+
cuesc: '\\\\'! ':' ;
|
|
22
|
+
mesc: '\\\\'! '}' ;
|
|
23
|
+
idelim: ("![" | '[' | "**" | '_' | '\`' | '<' | "~~" | " :" | <lbr>) ;
|
|
24
|
+
delim: (<idelim> | <DNL2>) ;
|
|
25
|
+
ebody: (<esc>|.) ;
|
|
26
|
+
cbody: (<cesc>|.) ;
|
|
27
|
+
cbbody: (<cbesc>|.) ;
|
|
28
|
+
cubody: (<cuesc>|.) ;
|
|
29
|
+
mbody: (<mesc>|.) ;
|
|
30
|
+
body: <ebody>(?-<delim>!) => join ;
|
|
31
|
+
ibody: <ebody>(?-<idelim>!) => join ;
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
comment: "<!--"! .(?+"-->") => discard ;
|
|
34
|
+
wikiref: "[["! <ebody>(?+"]]"!) => join ;
|
|
26
35
|
fnref: "[^"! <label> ;
|
|
27
36
|
fnote: <LSTART> "[^"! <fnlabel> <WS1> <para> ;
|
|
28
|
-
fnlabel:
|
|
29
|
-
label:
|
|
30
|
-
target:
|
|
37
|
+
fnlabel: <ebody>(?+"]:"!) => join ;
|
|
38
|
+
label: <ebody>(?+']'!) => join ;
|
|
39
|
+
target: <ebody>(?+')'!) => join ;
|
|
31
40
|
link: '['! <linklabel> '('! <target> ;
|
|
32
41
|
linkref: '['! <linklabel> '['! <label> ;
|
|
33
42
|
linkdef: <LSTART> '['! <label> ':'! <WS1> <ldtarget> ;
|
|
34
|
-
ldtarget:
|
|
35
|
-
linklabel: (<img> | <bold> | <italic> | <strike> | <code> | <emoji> | <linkbody>)* ']'! ;
|
|
36
|
-
linkdelim: (
|
|
37
|
-
linkbody:
|
|
43
|
+
ldtarget: <ebody>(?+<DNL1>) => join ;
|
|
44
|
+
linklabel: (<img> | <bold> | <italic> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <linkbody>)* ']'! ;
|
|
45
|
+
linkdelim: ("![" | '[' | "**" | '_' | "~~" | '\`' | ']') ;
|
|
46
|
+
linkbody: <ebody>(?-<linkdelim>!) => join ;
|
|
38
47
|
img: "!["! <label> '('! <target> ;
|
|
39
|
-
bold: "**"! (<wikiref> | <img> | <fnref> | <linkref> | <link> | <italic> | <strike> | <code> | <emoji> | <
|
|
40
|
-
italic: '_'! (<wikiref> | <img> | <fnref> | <linkref> | <link> | <bold> | <strike> | <code> | <emoji> | <
|
|
41
|
-
strike: "~~"! (<wikiref> | <img> | <fnref> | <linkref> | <link> | <bold> | <italic> | <code> | <emoji> | <
|
|
42
|
-
code: '\`'!
|
|
43
|
-
kbd: "<kbd>"!
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
bold: "**"! (<wikiref> | <img> | <fnref> | <linkref> | <link> | <italic> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <ibody>)* "**"! ;
|
|
49
|
+
italic: '_'! (<wikiref> | <img> | <fnref> | <linkref> | <link> | <bold> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <ibody>)* '_'! ;
|
|
50
|
+
strike: "~~"! (<wikiref> | <img> | <fnref> | <linkref> | <link> | <bold> | <italic> | <code> | <emoji> | <kbd> | <sub> | <sup> | <ibody>)* "~~"! ;
|
|
51
|
+
code: '\`'! <cbody>(?+'\`'!) => join ;
|
|
52
|
+
kbd: "<kbd>"! <ebody>(?+"</kbd>"!) => join ;
|
|
53
|
+
sub: "<sub>"! <ebody>(?+"</sub>"!) => join ;
|
|
54
|
+
sup: "<sup>"! <ebody>(?+"</sup>"!) => join ;
|
|
55
|
+
emoji: ' '? ':'! (<ALPHA_NUM> | '+')(?+':'!) => join ;
|
|
56
|
+
para: (<wikiref> | <img> | <fnref> | <linkref> | <link> | <bold> | <italic> | <strike> | <code> | <kbd> | <sub> | <sup> | <emoji> | <lbr> | <comment> | <body>)* <DNL2>! ;
|
|
46
57
|
|
|
47
58
|
hdlevel: '#'+ => count ;
|
|
59
|
+
hdid: "{#"! (<ALPHA_NUM> | '-')+ '}'! => join ;
|
|
60
|
+
hddelim: (<idelim> | <NL> | "{#") ;
|
|
61
|
+
hdbody: <ebody>(?-<hddelim>!) => join ;
|
|
48
62
|
hd: <LSTART> <hdlevel> <WS0>
|
|
49
|
-
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <
|
|
63
|
+
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <hdbody>)* <hdid>? <DNL1> ;
|
|
50
64
|
|
|
51
65
|
lilevel: ' '* => count ;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
lidelim: (
|
|
56
|
-
libody:
|
|
66
|
+
olid: (<ALPHA>+|<DIGIT>+) => join ;
|
|
67
|
+
ulinit: <DNL> <WS0> '-'! ;
|
|
68
|
+
olinit: <DNL> <WS0> <olid>! '.'! ;
|
|
69
|
+
lidelim: (<delim> | <ulinit> | <olinit>) ;
|
|
70
|
+
libody: <ebody>(?-<lidelim>!) => join ;
|
|
57
71
|
todo: '['! [ xX] ']'! <WS1> => hoistR ;
|
|
58
72
|
ulitem: <LSTART> <lilevel> "- "! <todo>?
|
|
59
|
-
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <libody> )* <DNL> ;
|
|
60
|
-
olitem: <LSTART> <lilevel> <
|
|
61
|
-
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <libody> )* <DNL> ;
|
|
73
|
+
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <libody> )* <DNL> ;
|
|
74
|
+
olitem: <LSTART> <lilevel> <olid> ". "! <todo>?
|
|
75
|
+
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <libody> )* <DNL> ;
|
|
62
76
|
list: (<ulitem> | <olitem>)+ <DNL1> ;
|
|
63
77
|
|
|
64
78
|
cbdelim: <LSTART> "\`\`\`"! ;
|
|
65
79
|
codeblock: <cbdelim>! <codemeta> <codebody> <DNL1> ;
|
|
66
80
|
codemeta: .(?+<NL>!) => join ;
|
|
67
|
-
codebody:
|
|
81
|
+
codebody: <cbbody>(?+<cbdelim>) => join ;
|
|
68
82
|
|
|
69
|
-
|
|
70
|
-
customblock: <
|
|
83
|
+
cudelim: <LSTART> ":::"! ;
|
|
84
|
+
customblock: <cudelim>! <custommeta> <custombody> <DNL1> ;
|
|
71
85
|
custommeta: .(?+<NL>!) => join ;
|
|
72
|
-
custombody:
|
|
86
|
+
custombody: <cubody>(?+<cudelim>) => join ;
|
|
73
87
|
|
|
74
88
|
metablock: <LSTART> "{{{"! <metabody> <DNL1> ;
|
|
75
|
-
metabody:
|
|
89
|
+
metabody: <mbody>(?+<metaend>!) => join ;
|
|
76
90
|
metaend: "}}}" <LEND> ;
|
|
77
91
|
|
|
78
92
|
bqlevel: '>'+ => count ;
|
|
93
|
+
bqdelim: (<idelim> | <NL>) ;
|
|
94
|
+
bqbody: <ebody>(?-<bqdelim>!) => join ;
|
|
79
95
|
bqline: <LSTART> <bqlevel> ' '?!
|
|
80
|
-
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <bqlbr> | <
|
|
96
|
+
(<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <bqlbr> | <bqbody>)* <DNL> ;
|
|
81
97
|
bqlbr: '\\\\'!(?-<DNL>) ;
|
|
82
98
|
bquote: <bqline>+ <DNL1> ;
|
|
83
99
|
|
|
84
|
-
tdelim: (<
|
|
85
|
-
tbody:
|
|
86
|
-
tcell: <WS0> (<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <tbody> )* '|'! ;
|
|
100
|
+
tdelim: (<idelim> | '|' ) ;
|
|
101
|
+
tbody: <ebody>(?-<tdelim>!) => join ;
|
|
102
|
+
tcell: <WS0> (<wikiref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <kbd> | <sub> | <sup> | <tbody> )* '|'! ;
|
|
87
103
|
trow: <LSTART> '|'! <tcell>(?+<DNL>) ;
|
|
88
104
|
table: <trow>+ <DNL1> ;
|
|
89
105
|
|
|
90
106
|
hr: "--" '-'+ <DNL1> => join ;
|
|
91
107
|
|
|
92
|
-
main: <WS0> (<hd> | <list> | <bquote> | <codeblock> | <customblock> | <metablock> | <table> | <hr> | <fnote> | <linkdef> | <para>)* ;
|
|
108
|
+
main: <WS0> (<hd> | <list> | <bquote> | <codeblock> | <customblock> | <metablock> | <table> | <hr> | <fnote> | <linkdef> | <comment> | <para> )* ;
|
|
93
109
|
`);
|
|
94
110
|
export const DEFAULT_TAG_TRANSFORMS = {
|
|
95
111
|
bold: (_, body) => ["strong", {}, ...body],
|
|
@@ -154,15 +170,17 @@ export const DEFAULT_TAG_TRANSFORMS = {
|
|
|
154
170
|
ol: (_, items, meta) => ["ol", withMeta({}, meta), ...items],
|
|
155
171
|
para: (_, body, meta) => ["p", withMeta({}, meta), ...body],
|
|
156
172
|
strike: (_, body) => ["s", {}, ...body],
|
|
157
|
-
|
|
173
|
+
sub: (_, body) => ["sub", {}, body],
|
|
174
|
+
sup: (_, body) => ["sup", {}, body],
|
|
175
|
+
table: (ctx, head, rows, meta) => [
|
|
158
176
|
"table",
|
|
159
|
-
withMeta({ __align }, meta),
|
|
177
|
+
withMeta({ __align: ctx.align }, meta),
|
|
160
178
|
["thead", {}, head],
|
|
161
179
|
["tbody", {}, ...rows],
|
|
162
180
|
],
|
|
163
181
|
tableCell: (_, body) => ["td", {}, ...body],
|
|
164
182
|
tableHead: (_, body) => ["th", {}, ...body],
|
|
165
|
-
tableRow: (_,
|
|
183
|
+
tableRow: (_, cells) => ["tr", {}, ...cells],
|
|
166
184
|
ul: (_, items, meta) => ["ul", withMeta({}, meta), ...items],
|
|
167
185
|
ulitem: (_, attribs, body) => ["li", attribs, ...body],
|
|
168
186
|
wikiref: (_, id, label) => [
|
|
@@ -237,6 +255,8 @@ export const defTransformContext = (tags, opts, linkRefs, logger) => ({
|
|
|
237
255
|
hasFootnotes: false,
|
|
238
256
|
logger,
|
|
239
257
|
meta: null,
|
|
258
|
+
align: [],
|
|
259
|
+
column: 0,
|
|
240
260
|
row: 0,
|
|
241
261
|
opts: {
|
|
242
262
|
escape: false,
|
|
@@ -256,9 +276,11 @@ export const transformScope = defmulti((x, ctx) => {
|
|
|
256
276
|
ctx.logger && ctx.logger.debug(x);
|
|
257
277
|
return x.id;
|
|
258
278
|
}, {
|
|
259
|
-
|
|
279
|
+
bqbody: "body",
|
|
260
280
|
bqlbr: "lbr",
|
|
261
281
|
bqline: "repeat0",
|
|
282
|
+
hdbody: "body",
|
|
283
|
+
ibody: "body",
|
|
262
284
|
label: "body",
|
|
263
285
|
libody: "body",
|
|
264
286
|
linkbody: "body",
|
|
@@ -336,7 +358,6 @@ export const transformScope = defmulti((x, ctx) => {
|
|
|
336
358
|
}
|
|
337
359
|
__collect(acc, ctx.tags.emoji(ctx, result));
|
|
338
360
|
},
|
|
339
|
-
esc: (scope, ctx, acc) => acc.push(__escape(ctx, scope.children[0].result)),
|
|
340
361
|
fnote: ({ children }, ctx) => {
|
|
341
362
|
const body = [];
|
|
342
363
|
const id = children[0].result;
|
|
@@ -353,9 +374,10 @@ export const transformScope = defmulti((x, ctx) => {
|
|
|
353
374
|
const body = [];
|
|
354
375
|
const level = children[0].result;
|
|
355
376
|
transformScope(children[1], ctx, body);
|
|
356
|
-
ctx.headings.push({ level, body });
|
|
357
377
|
__trimBody(body);
|
|
358
|
-
|
|
378
|
+
const slug = children[2]?.result || slugifyGH(extractBody(body).join(""));
|
|
379
|
+
ctx.headings.push({ level, body });
|
|
380
|
+
__collect(acc, ctx.tags.heading(ctx, level, slug, body, ctx.meta));
|
|
359
381
|
ctx.meta = null;
|
|
360
382
|
},
|
|
361
383
|
hr: (scope, ctx, acc) => {
|
|
@@ -364,7 +386,7 @@ export const transformScope = defmulti((x, ctx) => {
|
|
|
364
386
|
},
|
|
365
387
|
img: ({ children }, ctx, acc) => __collect(acc, ctx.tags.img(ctx, __escape(ctx, children[0].result.trim()), ...__linkTitle(children[1].result))),
|
|
366
388
|
italic: (scope, ctx, acc) => __collect(acc, ctx.tags.italic(ctx, __children(ctx, scope.children))),
|
|
367
|
-
kbd: (scope, ctx, acc) =>
|
|
389
|
+
kbd: (scope, ctx, acc) => __collectPrim(scope, ctx, acc, "kbd"),
|
|
368
390
|
lbr: (_, ctx, acc) => __collect(acc, ctx.tags.br(ctx)),
|
|
369
391
|
link: ({ children }, ctx, acc) => __collect(acc, ctx.tags.link(ctx, ...__linkTitle(children[1].result), __children(ctx, children[0].children))),
|
|
370
392
|
linkdef: ({ children }, ctx) => {
|
|
@@ -430,28 +452,37 @@ export const transformScope = defmulti((x, ctx) => {
|
|
|
430
452
|
ctx.meta = null;
|
|
431
453
|
},
|
|
432
454
|
strike: (scope, ctx, acc) => __collect(acc, ctx.tags.strike(ctx, __children(ctx, scope.children))),
|
|
455
|
+
sub: (scope, ctx, acc) => __collectPrim(scope, ctx, acc, "sub"),
|
|
456
|
+
sup: (scope, ctx, acc) => __collectPrim(scope, ctx, acc, "sup"),
|
|
433
457
|
table: (scope, ctx, acc) => {
|
|
434
458
|
const children = scope.children[0].children;
|
|
435
459
|
const head = [];
|
|
436
460
|
const rows = [];
|
|
437
461
|
ctx.row = 0;
|
|
438
|
-
transformScope(children[0], ctx, head);
|
|
439
|
-
let align;
|
|
440
462
|
if (children.length > 1) {
|
|
441
|
-
align = __columnAlignments(children[1].children[0].children);
|
|
463
|
+
ctx.align = __columnAlignments(children[1].children[0].children);
|
|
442
464
|
for (let i = 2, n = children.length; i < n; i++) {
|
|
443
465
|
ctx.row = i - 1;
|
|
444
466
|
transformScope(children[i], ctx, rows);
|
|
445
467
|
}
|
|
446
468
|
}
|
|
447
469
|
else {
|
|
448
|
-
align = new Array(children[0].children[0].children.length).fill("left");
|
|
470
|
+
ctx.align = new Array(children[0].children[0].children.length).fill("left");
|
|
449
471
|
}
|
|
450
|
-
|
|
472
|
+
ctx.row = 0;
|
|
473
|
+
transformScope(children[0], ctx, head);
|
|
474
|
+
__collect(acc, ctx.tags.table(ctx, head[0], rows, ctx.meta));
|
|
451
475
|
ctx.meta = null;
|
|
452
476
|
},
|
|
453
477
|
tcell: ({ children }, ctx, acc) => __collect(acc, (ctx.row > 0 ? ctx.tags.tableCell : ctx.tags.tableHead)(ctx, __trimBody(__children(ctx, children)))),
|
|
454
|
-
trow: (
|
|
478
|
+
trow: (scope, ctx, acc) => {
|
|
479
|
+
const cells = [];
|
|
480
|
+
scope.children[0].children.forEach((c, i) => {
|
|
481
|
+
ctx.column = i;
|
|
482
|
+
transformScope(c, ctx, cells);
|
|
483
|
+
});
|
|
484
|
+
__collect(acc, ctx.tags.tableRow(ctx, cells));
|
|
485
|
+
},
|
|
455
486
|
ulitem: ({ children }, ctx, acc) => {
|
|
456
487
|
const body = [];
|
|
457
488
|
transformScope(children[2], ctx, body);
|
|
@@ -463,7 +494,7 @@ export const transformScope = defmulti((x, ctx) => {
|
|
|
463
494
|
},
|
|
464
495
|
wikiref: (scope, ctx, acc) => {
|
|
465
496
|
const [id, label] = scope.result.split("|");
|
|
466
|
-
__collect(acc, ctx.tags.wikiref(ctx, id, label));
|
|
497
|
+
__collect(acc, ctx.tags.wikiref(ctx, id.trim(), label?.trim()));
|
|
467
498
|
},
|
|
468
499
|
});
|
|
469
500
|
/**
|
|
@@ -496,6 +527,7 @@ export const extractBody = (body, acc = []) => {
|
|
|
496
527
|
};
|
|
497
528
|
/** @internal */
|
|
498
529
|
const __collect = (acc, x) => x != null && acc.push(x);
|
|
530
|
+
const __collectPrim = (scope, ctx, acc, tag) => __collect(acc, ctx.tags[tag](ctx, scope.result));
|
|
499
531
|
/** @internal */
|
|
500
532
|
const __children = (ctx, children, acc = []) => {
|
|
501
533
|
for (let c of children)
|
|
@@ -515,6 +547,11 @@ const __listItemAttribs = (scope) => scope?.id === "todo"
|
|
|
515
547
|
const __trimBody = (body) => {
|
|
516
548
|
if (body.length === 1 && isString(body[0]))
|
|
517
549
|
body[0] = body[0].trim();
|
|
550
|
+
else {
|
|
551
|
+
const last = peek(body);
|
|
552
|
+
if (isString(last) && /^\s+$/.test(last))
|
|
553
|
+
body.pop();
|
|
554
|
+
}
|
|
518
555
|
return body;
|
|
519
556
|
};
|
|
520
557
|
/** @internal */
|