@thi.ng/hiccup-markdown 2.1.49 → 3.0.1
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 +106 -1
- package/README.md +261 -169
- package/api.d.ts +348 -17
- package/emoji.d.ts +11 -0
- package/emoji.js +1914 -0
- package/package.json +12 -12
- package/parse.d.ts +73 -5
- package/parse.js +522 -211
- package/parser.d.ts +65 -0
- package/parser.js +379 -0
- package/serialize.d.ts +2 -1
- package/serialize.js +43 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2023-
|
|
3
|
+
- **Last updated**: 2023-03-02T18:09:03Z
|
|
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,111 @@ 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.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hiccup-markdown@3.0.0) (2023-02-27)
|
|
13
|
+
|
|
14
|
+
#### 🛑 Breaking changes
|
|
15
|
+
|
|
16
|
+
- replace parser ([e425e87](https://github.com/thi-ng/umbrella/commit/e425e87))
|
|
17
|
+
- BREAKING CHANGE: replace parser implementation
|
|
18
|
+
- switch to new parser (non-transducer based):
|
|
19
|
+
- [dcb7b193f](https://github.com/thi-ng/umbrella/commit/dcb7b193f)
|
|
20
|
+
- [5d030ad9c](https://github.com/thi-ng/umbrella/commit/5d030ad9c)
|
|
21
|
+
- [656b90be3](https://github.com/thi-ng/umbrella/commit/656b90be3)
|
|
22
|
+
- [8b215c690](https://github.com/thi-ng/umbrella/commit/8b215c690)
|
|
23
|
+
- add/update parser types/interfaces
|
|
24
|
+
- add/update tests
|
|
25
|
+
- update deps
|
|
26
|
+
|
|
27
|
+
#### 🚀 Features
|
|
28
|
+
|
|
29
|
+
- add new parser (incomplete WIP) ([dcb7b19](https://github.com/thi-ng/umbrella/commit/dcb7b19))
|
|
30
|
+
- update/extend new parser ([5d030ad](https://github.com/thi-ng/umbrella/commit/5d030ad))
|
|
31
|
+
- update blockquote handling
|
|
32
|
+
- add emoji support (& dependency)
|
|
33
|
+
- update/improve metablock format/handling
|
|
34
|
+
- add meta type/syntax identifier
|
|
35
|
+
- TODO meta data parsing
|
|
36
|
+
- update TagTransforms to accept meta data
|
|
37
|
+
- update horizontal rule parser (keep track of length)
|
|
38
|
+
- update/extend new parser ([656b90b](https://github.com/thi-ng/umbrella/commit/656b90b))
|
|
39
|
+
- add support for all outstanding elements:
|
|
40
|
+
- code blocks
|
|
41
|
+
- footnotes
|
|
42
|
+
- link refs
|
|
43
|
+
- tables
|
|
44
|
+
- update metablock handling (add tag handler to tx raw string)
|
|
45
|
+
- update all tag handlers to accept parse ctx as 1st arg
|
|
46
|
+
- allow all tag handlers to return nothing to exclude elem in result
|
|
47
|
+
- collect footnotes, link refs & headings separately in parse ctx
|
|
48
|
+
- update parser, add img & logger support ([8b215c6](https://github.com/thi-ng/umbrella/commit/8b215c6))
|
|
49
|
+
- add logger support for tracing parse scopes
|
|
50
|
+
- trim codeblock body
|
|
51
|
+
- fix footnote handling/appending
|
|
52
|
+
- fix hd tag handler if level>6
|
|
53
|
+
- fix table column alignment parsing
|
|
54
|
+
- update pkg deps
|
|
55
|
+
- update/extend parser ([27c4084](https://github.com/thi-ng/umbrella/commit/27c4084))
|
|
56
|
+
- update parser grammar
|
|
57
|
+
- add support for nested inline formats in:
|
|
58
|
+
- headings
|
|
59
|
+
- paragraphs
|
|
60
|
+
- blockquotes
|
|
61
|
+
- link labels
|
|
62
|
+
- lists
|
|
63
|
+
- tables
|
|
64
|
+
- add support for escaping format chars
|
|
65
|
+
- add support for explicit linebreaks in paragraphs & blockquotes
|
|
66
|
+
- add `<kbd>` support
|
|
67
|
+
- add parse option to auto-escape chars as HTML entities
|
|
68
|
+
- update TagTransforms
|
|
69
|
+
- extract DEFAULT_TAG_TRANSFORMS
|
|
70
|
+
- update parse() signature, add parseRaw()
|
|
71
|
+
- refactor/improve reuse for various internal parse helpers
|
|
72
|
+
- update tests
|
|
73
|
+
- add escaped char support ([6671b73](https://github.com/thi-ng/umbrella/commit/6671b73))
|
|
74
|
+
- update parser ([33aea4e](https://github.com/thi-ng/umbrella/commit/33aea4e))
|
|
75
|
+
- add wikiref link parser/handler
|
|
76
|
+
- fix codeblock & customblock handlers
|
|
77
|
+
- add slugified ID attrib for headings
|
|
78
|
+
- expose withMeta() & extractBody() utils for custom handlers
|
|
79
|
+
- update img & link parsers ([8750fbd](https://github.com/thi-ng/umbrella/commit/8750fbd))
|
|
80
|
+
- add support for optional title attrib for links & images
|
|
81
|
+
(eg. `[label](url "title")`)
|
|
82
|
+
- fix linkref handling
|
|
83
|
+
- add/update tests
|
|
84
|
+
- update/extend parser (blockquotes, formats) ([13cb309](https://github.com/thi-ng/umbrella/commit/13cb309))
|
|
85
|
+
- update grammar & handler to support nested blockquotes
|
|
86
|
+
- update inline formats to allow links & images in body
|
|
87
|
+
- update tests
|
|
88
|
+
- update parser & tag transforms ([a6c0b36](https://github.com/thi-ng/umbrella/commit/a6c0b36))
|
|
89
|
+
- auto-compute heading ID in parser and provide as new arg to tag transform
|
|
90
|
+
- add row index as new arg for tableRow transform
|
|
91
|
+
- add tableHead tag transform (for 1st row cells)
|
|
92
|
+
- update lazy value handling in linkRef tag transform
|
|
93
|
+
- update tests
|
|
94
|
+
- update pkg deps
|
|
95
|
+
- add metadata support for <hr> tags ([d5c84c9](https://github.com/thi-ng/umbrella/commit/d5c84c9))
|
|
96
|
+
- update parser types/fns, add docs ([0208a53](https://github.com/thi-ng/umbrella/commit/0208a53))
|
|
97
|
+
- add ParseResult
|
|
98
|
+
- rename MDParseContext => TransformCtx
|
|
99
|
+
- rename walk => transformScope
|
|
100
|
+
- update parse() args
|
|
101
|
+
- add docstrings
|
|
102
|
+
- update tests
|
|
103
|
+
|
|
104
|
+
#### 🩹 Bug fixes
|
|
105
|
+
|
|
106
|
+
- add/update tests ([f444506](https://github.com/thi-ng/umbrella/commit/f444506))
|
|
107
|
+
- update emoji parse grammar ([b7c310f](https://github.com/thi-ng/umbrella/commit/b7c310f))
|
|
108
|
+
|
|
109
|
+
#### ♻️ Refactoring
|
|
110
|
+
|
|
111
|
+
- update serializer ([a489c0e](https://github.com/thi-ng/umbrella/commit/a489c0e))
|
|
112
|
+
- add support for nested blockquotes
|
|
113
|
+
- add support for link labels
|
|
114
|
+
- rename internal fns
|
|
115
|
+
- update tests
|
|
116
|
+
|
|
12
117
|
## [2.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hiccup-markdown@2.1.0) (2021-11-17)
|
|
13
118
|
|
|
14
119
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -10,21 +10,25 @@ This project is part of the
|
|
|
10
10
|
[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo.
|
|
11
11
|
|
|
12
12
|
- [About](#about)
|
|
13
|
-
- [Status](#status)
|
|
14
|
-
- [Installation](#installation)
|
|
15
|
-
- [Dependencies](#dependencies)
|
|
16
|
-
- [Usage examples](#usage-examples)
|
|
17
|
-
- [API](#api)
|
|
18
13
|
- [Parser](#parser)
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
|
|
14
|
+
- [Basic features](#basic-features)
|
|
15
|
+
- [Additional syntax & parser features/restrictions](#additional-syntax--parser-featuresrestrictions)
|
|
16
|
+
- [Formatting](#formatting)
|
|
17
|
+
- [Code block headers](#code-block-headers)
|
|
18
|
+
- [Custom blocks](#custom-blocks)
|
|
19
|
+
- [Headings with anchor IDs](#headings-with-anchor-ids)
|
|
20
|
+
- [Metadata](#metadata)
|
|
21
|
+
- [Customizing tag transforms](#customizing-tag-transforms)
|
|
22
22
|
- [Serializing to HTML](#serializing-to-html)
|
|
23
|
-
- [Customizing tags](#customizing-tags)
|
|
24
23
|
- [Serializer (Hiccup to Markdown)](#serializer-hiccup-to-markdown)
|
|
25
24
|
- [Features](#features)
|
|
26
25
|
- [Behaviors](#behaviors)
|
|
27
26
|
- [Usage examples](#usage-examples)
|
|
27
|
+
- [Status](#status)
|
|
28
|
+
- [Installation](#installation)
|
|
29
|
+
- [Dependencies](#dependencies)
|
|
30
|
+
- [Usage examples](#usage-examples)
|
|
31
|
+
- [API](#api)
|
|
28
32
|
- [Authors](#authors)
|
|
29
33
|
- [License](#license)
|
|
30
34
|
|
|
@@ -32,203 +36,233 @@ This project is part of the
|
|
|
32
36
|
|
|
33
37
|
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).
|
|
34
38
|
|
|
39
|
+
**⚠️ IMPORTANT: With v3.0.0 the parser implementation underwent a complete rewrite (with breaking changes, but lots of improvements). ⚠️**
|
|
40
|
+
|
|
35
41
|
This package provides both a customizable
|
|
36
42
|
[Markdown](https://en.wikipedia.org/wiki/Markdown)-to-[Hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup)
|
|
37
43
|
parser and an extensible Hiccup-to-Markdown converter.
|
|
38
44
|
|
|
39
|
-
##
|
|
45
|
+
## Parser
|
|
40
46
|
|
|
41
|
-
|
|
47
|
+
### Basic features
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
The parser itself is not aimed at supporting **all** of Markdown's
|
|
50
|
+
(CommonMark's) quirky syntax features, but restricts itself to a sane subset of
|
|
51
|
+
features and some useful [additional
|
|
52
|
+
features](#additional-syntax--parser-featuresrestrictions) not part of the
|
|
53
|
+
standard syntax.
|
|
44
54
|
|
|
45
|
-
|
|
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
|
+
| Formatting | Nestable **bold**, _italic_, `code`, ~~strike~~, <kbd>Key</kbd> supported in paragraphs, headings, link labels, lists, blockquotes, tables |
|
|
60
|
+
| Footnotes | Supported and stored separately in parse context |
|
|
61
|
+
| Headings | ATX-style only (`#` line prefix), any level |
|
|
62
|
+
| Horiz. Rulers | Only dash supported (e.g. `---`), min 2 chars required, length retained for downstream transformations |
|
|
63
|
+
| HTML elements | Unsupported |
|
|
64
|
+
| Images | Alt text is required, image can be used in link labels |
|
|
65
|
+
| Links | Supports `[label](target)`, `[label][ref]`, `[[page id]]` or `[[page id|label]]` style links, inline formats in label |
|
|
66
|
+
| Lists | Ordered & unordered, nestable, inline formatting, line breaks, GFM task list items |
|
|
67
|
+
| Paragraphs | Support for forced line breaks (trailing `\`) |
|
|
68
|
+
| Tables | Support for column alignments, nestable inline formatting |
|
|
46
69
|
|
|
47
|
-
|
|
48
|
-
yarn add @thi.ng/hiccup-markdown
|
|
49
|
-
```
|
|
70
|
+
### Additional syntax & parser features/restrictions
|
|
50
71
|
|
|
51
|
-
|
|
72
|
+
#### Formatting
|
|
52
73
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
```
|
|
74
|
+
To avoid ambiguity and simplify nesting, only the following formatting syntax is
|
|
75
|
+
supported for bold & italic:
|
|
56
76
|
|
|
57
|
-
|
|
77
|
+
- `**bold**`
|
|
78
|
+
- `_italic_`
|
|
58
79
|
|
|
59
|
-
|
|
80
|
+
`code` (\`) and ~~strikethrough~~ (`~~`) as usual...
|
|
60
81
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```
|
|
82
|
+
For keyboard commands `<kbd>` can be used, e.g.:\
|
|
83
|
+
`<kbd>Control</kbd> + <kbd>R</kbd>`
|
|
64
84
|
|
|
65
|
-
|
|
85
|
+
#### Code block headers
|
|
66
86
|
|
|
67
|
-
|
|
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
|
|
89
|
+
[@thi.ng/tangle](https://github.com/thi-ng/umbrella/tree/develop/packages/tangle)
|
|
90
|
+
for concrete use cases).
|
|
68
91
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
|
|
72
|
-
- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
|
|
73
|
-
- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
|
|
74
|
-
- [@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/develop/packages/fsm)
|
|
75
|
-
- [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup)
|
|
76
|
-
- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/develop/packages/strings)
|
|
77
|
-
- [@thi.ng/text-canvas](https://github.com/thi-ng/umbrella/tree/develop/packages/text-canvas)
|
|
78
|
-
- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers)
|
|
92
|
+
(Note: the GFM codeblock fences are only shown escaped here to avoid GH
|
|
93
|
+
layout breakage)
|
|
79
94
|
|
|
80
|
-
|
|
95
|
+
```text
|
|
96
|
+
\`\`\`language extra=data even=more
|
|
97
|
+
// code...
|
|
98
|
+
\`\`\`
|
|
99
|
+
```
|
|
81
100
|
|
|
82
|
-
|
|
83
|
-
[/examples](https://github.com/thi-ng/umbrella/tree/develop/examples)
|
|
84
|
-
directory are using this package.
|
|
101
|
+
#### Custom blocks
|
|
85
102
|
|
|
86
|
-
|
|
103
|
+
Since the parser does not directly transform Markdown into HTML, blocks of custom
|
|
104
|
+
freeform content can be used to define arbitrary data structures (e.g. UI
|
|
105
|
+
components, diagrams/visualizations etc.). Similarly to code blocks, custom
|
|
106
|
+
blocks are wrapped with `:::` and a type specifier:
|
|
87
107
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
108
|
+
```text
|
|
109
|
+
:::csv some=optional extra=data
|
|
110
|
+
city,lat,lon
|
|
111
|
+
berlin,52.5167,13.3833
|
|
112
|
+
new york,40.6943,-73.9249
|
|
113
|
+
tokyo,35.6897,139.6922
|
|
114
|
+
:::
|
|
115
|
+
```
|
|
91
116
|
|
|
92
|
-
|
|
117
|
+
How such a custom block is transformed is entirely down to the user provided tag
|
|
118
|
+
transformer. The default handler merely creates an element like this:
|
|
93
119
|
|
|
94
|
-
|
|
120
|
+
```js
|
|
121
|
+
[
|
|
122
|
+
"custom",
|
|
123
|
+
{ type: "csv", __head: [ "some=optional", "extra=data" ] },
|
|
124
|
+
"city,lat,lon\nberlin,52.5167,13.3833\nnew york,40.6943,-73.9249\ntokyo,35.6897,139.6922"
|
|
125
|
+
]
|
|
126
|
+
```
|
|
95
127
|
|
|
96
|
-
|
|
128
|
+
**Tip:** Use a
|
|
129
|
+
[`defmulti()`](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
|
|
130
|
+
polymorphic function as tag transformer to elegantly handle multiple types of
|
|
131
|
+
custom blocks (in an extensible manner).
|
|
97
132
|
|
|
98
|
-
|
|
133
|
+
#### Headings with anchor IDs
|
|
99
134
|
|
|
100
|
-
The
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
| Feature | Comments |
|
|
105
|
-
|-------------|-----------------------------------------------------------------------------------------------------|
|
|
106
|
-
| Heading | ATX only (`#` line prefix), levels 1-6, then downgrade to paragraph |
|
|
107
|
-
| Paragraph | no support for `\` line breaks |
|
|
108
|
-
| Blockquote | Respects newlines |
|
|
109
|
-
| Format | **bold**, _emphasis_, `code`, ~~strikethrough~~ in paragraphs, headings, lists, blockquotes, tables |
|
|
110
|
-
| Link | no support for inline formats in label |
|
|
111
|
-
| Image | no image links |
|
|
112
|
-
| List | only unordered (`- ` line prefix), no nesting, supports line breaks |
|
|
113
|
-
| Table | no support for column alignment |
|
|
114
|
-
| Code block | GFM only (triple backtick prefix), w/ optional language hint |
|
|
115
|
-
| Horiz. Rule | only dash supported (e.g. `---`), min 3 chars required |
|
|
116
|
-
|
|
117
|
-
**Note: Because of MD's line break handling and the fact the parser only
|
|
118
|
-
consumes single characters from an iterable without knowledge of further
|
|
119
|
-
values, the last heading, paragraph, blockquote, list or table requires
|
|
120
|
-
an additional newline.**
|
|
121
|
-
|
|
122
|
-
### Current issues & limitations
|
|
123
|
-
|
|
124
|
-
Paragraphs, headings and blockquotes ending with a character involved w/
|
|
125
|
-
inline formatting (e.g. `!`, `~`, `*`, `_`) either require an additional
|
|
126
|
-
space or 2 empty lines (instead of just one) between the next paragraph.
|
|
127
|
-
See [#156](https://github.com/thi-ng/umbrella/issues/156) for details.
|
|
128
|
-
|
|
129
|
-
Also, these MD features (and probably many more) are currently **not**
|
|
130
|
-
supported:
|
|
131
|
-
|
|
132
|
-
- inline HTML
|
|
133
|
-
- nested inline formats (e.g. **bold** inside _italic_)
|
|
134
|
-
- inline formats within link labels
|
|
135
|
-
- image links
|
|
136
|
-
- footnotes
|
|
137
|
-
- link references
|
|
138
|
-
- nested / ordered / numbered / todo lists
|
|
139
|
-
|
|
140
|
-
Some of these are considered, though currently not high priority... Pull
|
|
141
|
-
requests are welcome, though!
|
|
142
|
-
|
|
143
|
-
### Other parser features
|
|
144
|
-
|
|
145
|
-
- **Functional:** parser entirely built using
|
|
146
|
-
[transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers)
|
|
147
|
-
(specifically those defined in
|
|
148
|
-
[@thi.ng/fsm](https://github.com/thi-ng/umbrella/tree/develop/packages/fsm))
|
|
149
|
-
& function composition. Use the parser in a transducer pipeline to
|
|
150
|
-
easily apply post-processing of the emitted results
|
|
151
|
-
- **Declarative:** parsing rules defined declaratively with only minimal
|
|
152
|
-
state/context handling needed
|
|
153
|
-
- **No regex:** consumes input character-wise and produces an iterator
|
|
154
|
-
of hiccup-style tree nodes, ready to be used with
|
|
155
|
-
[@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom),
|
|
156
|
-
[@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup)
|
|
157
|
-
or the serializer of this package for back conversion to MD
|
|
158
|
-
- **Customizable:** supports custom tag factory functions to override
|
|
159
|
-
default behavior / representation of each parsed result element
|
|
160
|
-
- **Fast (enough):** parses this markdown file (5.9KB) in ~5ms on MBP2016 / Chrome 71
|
|
161
|
-
- **Small:** minified + gzipped ~2.5KB (parser sub-module incl. deps)
|
|
135
|
+
The default tag transform for headlines auto-generates ID attributes using that
|
|
136
|
+
headline's body and
|
|
137
|
+
[slugifying](https://docs.thi.ng/umbrella/strings/functions/slugifyGH.html) it
|
|
138
|
+
(Github readme compatible):
|
|
162
139
|
|
|
163
|
-
|
|
140
|
+
```text
|
|
141
|
+
# The **beautiful `code`**
|
|
142
|
+
```
|
|
164
143
|
|
|
165
|
-
|
|
166
|
-
import { iterator } from "@thi.ng/transducers";
|
|
167
|
-
import { serialize } from "@thi.ng/hiccup";
|
|
144
|
+
Results in:
|
|
168
145
|
|
|
169
|
-
|
|
146
|
+
```js
|
|
147
|
+
// [
|
|
148
|
+
// "h1",
|
|
149
|
+
// { id: "the-beautiful-code" },
|
|
150
|
+
// "The ",
|
|
151
|
+
// [ "strong", {}, "beautiful ", [ "code", {}, "code" ] ]
|
|
152
|
+
// ]
|
|
153
|
+
```
|
|
170
154
|
|
|
171
|
-
|
|
172
|
-
# Hello world
|
|
155
|
+
#### Metadata
|
|
173
156
|
|
|
174
|
-
|
|
157
|
+
Arbitrary metadata can be assigned to _any_ block level element:
|
|
175
158
|
|
|
176
|
-
|
|
159
|
+
- code blocks
|
|
160
|
+
- custom blocks
|
|
161
|
+
- footnotes
|
|
162
|
+
- headings
|
|
163
|
+
- lists
|
|
164
|
+
- paragraphs
|
|
165
|
+
- tables
|
|
166
|
+
|
|
167
|
+
This metadata is given within a block element itself which must directly precede
|
|
168
|
+
the target element (no empty lines in between). A custom tag handler can be
|
|
169
|
+
defined to transform that metadata before it's being handed to the target's tag
|
|
170
|
+
handler.
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
{{{ Hello metadata }}}
|
|
174
|
+
- item 1
|
|
175
|
+
- item 2
|
|
176
|
+
```
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
[...iterator(parse(), src)]
|
|
180
|
-
// [ [ 'h1', ' Hello world ' ],
|
|
181
|
-
// [ 'p',
|
|
182
|
-
// [ 'a', { href: 'http://example.com' }, 'This' ],
|
|
183
|
-
// ' is a ',
|
|
184
|
-
// [ 'em', 'test' ],
|
|
185
|
-
// '. ' ] ]
|
|
178
|
+
Using the default tag handlers, this snippet will translate to:
|
|
186
179
|
|
|
187
|
-
|
|
188
|
-
|
|
180
|
+
```js
|
|
181
|
+
[
|
|
182
|
+
"ul",
|
|
183
|
+
{ __meta: "Hello metadata" },
|
|
184
|
+
[ "li", {}, "item 1" ],
|
|
185
|
+
[ "li", {}, "item 2" ]
|
|
186
|
+
]
|
|
187
|
+
```
|
|
189
188
|
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
Using structured data as body of these metadata blocks is more powerful and (as
|
|
190
|
+
mentioned above) can be dealt with using a custom tag handler, e.g. here we
|
|
191
|
+
interpret the body as JSON:
|
|
192
|
+
|
|
193
|
+
```text
|
|
194
|
+
{{{
|
|
195
|
+
{
|
|
196
|
+
"task:status": "waiting-on",
|
|
197
|
+
"task:due": "2023-02-28"
|
|
198
|
+
}
|
|
199
|
+
}}}
|
|
200
|
+
# Chapter 3
|
|
192
201
|
```
|
|
193
202
|
|
|
194
|
-
|
|
203
|
+
```js
|
|
204
|
+
parse(src, { tags: { meta: (_, body) => JSON.parse(body) }}).result
|
|
205
|
+
// [
|
|
206
|
+
// [
|
|
207
|
+
// "h1",
|
|
208
|
+
// { id: "chapter-3", __meta: { "task:status": "waiting-on", "task:due": "2023-02-28" } },
|
|
209
|
+
// "Chapter 3"
|
|
210
|
+
// ]
|
|
211
|
+
// ]
|
|
212
|
+
```
|
|
195
213
|
|
|
196
|
-
|
|
197
|
-
elements. User implementations / overrides can be given to the
|
|
198
|
-
`parse()` transducer to customize output.
|
|
214
|
+
### Customizing tag transforms
|
|
199
215
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
heading(level, children: any[]): any[];
|
|
207
|
-
hr(): any[];
|
|
208
|
-
img(src: string, alt: string): any[];
|
|
209
|
-
li(children: any[]): any[];
|
|
210
|
-
link(href: string, body: string): any[];
|
|
211
|
-
list(type: string, items: any[]): any[];
|
|
212
|
-
paragraph(children: any[]): any[];
|
|
213
|
-
strike(body: string): any[];
|
|
214
|
-
strong(body: string): any[];
|
|
215
|
-
table(rows: any[]): any[];
|
|
216
|
-
td(i: number, children: any[]): any[];
|
|
217
|
-
tr(i: number, cells: any[]): any[];
|
|
218
|
-
}
|
|
219
|
-
```
|
|
216
|
+
The
|
|
217
|
+
[`TagTransforms`](https://docs.thi.ng/umbrella/hiccup-markdown/interfaces/TagTransforms.html)
|
|
218
|
+
interface defines transformation functions for all supported elements and can be
|
|
219
|
+
used to completely customize the parser's result data. User implementations can
|
|
220
|
+
be given to the `parse()` function to selectively customize/override
|
|
221
|
+
defaults/outputs.
|
|
220
222
|
|
|
221
223
|
Example with custom link elements:
|
|
222
224
|
|
|
223
225
|
```ts
|
|
224
|
-
const tags = {
|
|
225
|
-
link: (href, body) => ["a.link.blue", { href }, body]
|
|
226
|
+
const tags: Partial<TagTransforms> = {
|
|
227
|
+
link: (ctx, href, body) => ["a.link.blue", { href }, ...body]
|
|
226
228
|
};
|
|
227
229
|
|
|
228
|
-
|
|
230
|
+
// parse with custom tag transform overrides
|
|
231
|
+
parse("[label](url)", { tags }).result;
|
|
232
|
+
// [
|
|
233
|
+
// ["p", {}, ["a.link.blue", { href: "url" }, "label"]]
|
|
234
|
+
// ]
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Serializing to HTML
|
|
229
238
|
|
|
230
|
-
|
|
231
|
-
|
|
239
|
+
```ts
|
|
240
|
+
import { serialize } from "@thi.ng/hiccup";
|
|
241
|
+
import { parse } from "@thi.ng/hiccup-markdown";
|
|
242
|
+
|
|
243
|
+
const src = `# Hello world\n[This is a _test_](http://example.com) :smile:`;
|
|
244
|
+
|
|
245
|
+
// convert to hiccup tree
|
|
246
|
+
parse(src).result
|
|
247
|
+
// [
|
|
248
|
+
// [ "h1", { id: "hello-world" }, "Hello world" ],
|
|
249
|
+
// [
|
|
250
|
+
// "p",
|
|
251
|
+
// {},
|
|
252
|
+
// [
|
|
253
|
+
// "a",
|
|
254
|
+
// { href: "http://example.com" },
|
|
255
|
+
// "This is a ",
|
|
256
|
+
// [ "em", {}, "test" ]
|
|
257
|
+
// ],
|
|
258
|
+
// " ",
|
|
259
|
+
// "😄"
|
|
260
|
+
// ]
|
|
261
|
+
// ]
|
|
262
|
+
|
|
263
|
+
// or serialize to HTML
|
|
264
|
+
serialize(parse(src).result);
|
|
265
|
+
// <h1 id="hello-world">Hello world</h1><p><a href="http://example.com">This is a <em>test</em></a> 😄</p>
|
|
232
266
|
```
|
|
233
267
|
|
|
234
268
|
## Serializer (Hiccup to Markdown)
|
|
@@ -358,10 +392,10 @@ import { serialize } from "@thi.ng/hiccup-markdown";
|
|
|
358
392
|
|
|
359
393
|
> So long and thanks for all the fish.
|
|
360
394
|
|
|
361
|
-
| **ID**
|
|
362
|
-
|
|
363
|
-
| 1
|
|
364
|
-
| 2
|
|
395
|
+
| **ID** | **Name** |
|
|
396
|
+
|--------|------------------|
|
|
397
|
+
| 1 | Alice B. Charles |
|
|
398
|
+
| 2 | Bart Simpson |
|
|
365
399
|
|
|
366
400
|
_Table #1_
|
|
367
401
|
|
|
@@ -391,10 +425,10 @@ import { serialize } from "@thi.ng/hiccup-markdown";
|
|
|
391
425
|
|
|
392
426
|
> So long and thanks for all the fish.
|
|
393
427
|
|
|
394
|
-
| **ID**
|
|
395
|
-
|
|
396
|
-
| 1
|
|
397
|
-
| 2
|
|
428
|
+
| **ID** | **Name** |
|
|
429
|
+
|--------|------------------|
|
|
430
|
+
| 1 | Alice B. Charles |
|
|
431
|
+
| 2 | Bart Simpson |
|
|
398
432
|
|
|
399
433
|
_Table #1_
|
|
400
434
|
|
|
@@ -402,6 +436,64 @@ More info [here](http://thi.ng/hiccup-markdown).
|
|
|
402
436
|
|
|
403
437
|
---
|
|
404
438
|
|
|
439
|
+
## Status
|
|
440
|
+
|
|
441
|
+
**STABLE** - used in production
|
|
442
|
+
|
|
443
|
+
[Search or submit any issues for this package](https://github.com/thi-ng/umbrella/issues?q=%5Bhiccup-markdown%5D+in%3Atitle)
|
|
444
|
+
|
|
445
|
+
## Installation
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
yarn add @thi.ng/hiccup-markdown
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
ES module import:
|
|
452
|
+
|
|
453
|
+
```html
|
|
454
|
+
<script type="module" src="https://cdn.skypack.dev/@thi.ng/hiccup-markdown"></script>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
[Skypack documentation](https://docs.skypack.dev/)
|
|
458
|
+
|
|
459
|
+
For Node.js REPL:
|
|
460
|
+
|
|
461
|
+
```js
|
|
462
|
+
const hiccupMarkdown = await import("@thi.ng/hiccup-markdown");
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 4.35 KB
|
|
466
|
+
|
|
467
|
+
## Dependencies
|
|
468
|
+
|
|
469
|
+
- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
|
|
470
|
+
- [@thi.ng/arrays](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays)
|
|
471
|
+
- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
|
|
472
|
+
- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
|
|
473
|
+
- [@thi.ng/emoji](https://github.com/thi-ng/umbrella/tree/develop/packages/emoji)
|
|
474
|
+
- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
|
|
475
|
+
- [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup)
|
|
476
|
+
- [@thi.ng/logger](https://github.com/thi-ng/umbrella/tree/develop/packages/logger)
|
|
477
|
+
- [@thi.ng/parse](https://github.com/thi-ng/umbrella/tree/develop/packages/parse)
|
|
478
|
+
- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/develop/packages/strings)
|
|
479
|
+
- [@thi.ng/text-canvas](https://github.com/thi-ng/umbrella/tree/develop/packages/text-canvas)
|
|
480
|
+
|
|
481
|
+
## Usage examples
|
|
482
|
+
|
|
483
|
+
Several demos in this repo's
|
|
484
|
+
[/examples](https://github.com/thi-ng/umbrella/tree/develop/examples)
|
|
485
|
+
directory are using this package.
|
|
486
|
+
|
|
487
|
+
A selection:
|
|
488
|
+
|
|
489
|
+
| Screenshot | Description | Live demo | Source |
|
|
490
|
+
|:-----------------------------------------------------------------------------------------------------------------------|:------------------------------------------------|:-----------------------------------------------|:----------------------------------------------------------------------------|
|
|
491
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/markdown-parser.jpg" width="240"/> | Markdown to Hiccup to HTML parser / transformer | [Demo](https://demo.thi.ng/umbrella/markdown/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/markdown) |
|
|
492
|
+
|
|
493
|
+
## API
|
|
494
|
+
|
|
495
|
+
[Generated API docs](https://docs.thi.ng/umbrella/hiccup-markdown/)
|
|
496
|
+
|
|
405
497
|
## Authors
|
|
406
498
|
|
|
407
499
|
- [Karsten Schmidt](https://thi.ng)
|