@tabnas/markdown 0.2.1 → 0.4.2
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 +10 -38
- package/dist/markdown.d.ts +88 -28
- package/dist/markdown.js +692 -551
- package/dist/markdown.js.map +1 -1
- package/package.json +13 -9
- package/src/markdown.ts +754 -629
package/README.md
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
# @tabnas/markdown (TypeScript)
|
|
2
2
|
|
|
3
|
-
A [Tabnas](https://github.com/tabnas/parser) grammar plugin that parses
|
|
4
|
-
delimited record text — a header row, comma-separated fields, one record per
|
|
5
|
-
line, with RFC-4180 quoting — into arrays of objects or arrays. Despite the
|
|
6
|
-
name it is a configurable CSV/TSV-family reader, with support for headers,
|
|
7
|
-
quoted fields, custom delimiters, streaming, and strict / non-strict modes.
|
|
3
|
+
A [Tabnas](https://github.com/tabnas/parser) grammar plugin that parses **CommonMark / GFM Markdown** into a JSON AST. Built on the bare `@tabnas/parser` engine.
|
|
8
4
|
|
|
9
5
|
[](https://npmjs.com/package/@tabnas/markdown)
|
|
10
6
|
[](https://github.com/tabnas/markdown/actions/workflows/build.yml)
|
|
@@ -15,50 +11,26 @@ quoted fields, custom delimiters, streaming, and strict / non-strict modes.
|
|
|
15
11
|
## Install
|
|
16
12
|
|
|
17
13
|
```bash
|
|
18
|
-
npm install @tabnas/markdown @tabnas/parser
|
|
14
|
+
npm install @tabnas/markdown @tabnas/parser
|
|
19
15
|
```
|
|
20
16
|
|
|
21
|
-
`@tabnas/parser` (>=
|
|
22
|
-
Node >=24.
|
|
17
|
+
`@tabnas/parser` (>=0) is the only peer dependency. Requires Node >=24.
|
|
23
18
|
|
|
24
19
|
## Example
|
|
25
20
|
|
|
26
21
|
```js
|
|
27
22
|
import { Tabnas } from '@tabnas/parser'
|
|
28
|
-
import { jsonic } from '@tabnas/jsonic'
|
|
29
23
|
import { Markdown } from '@tabnas/markdown'
|
|
30
24
|
|
|
31
|
-
const j = new Tabnas().use(
|
|
25
|
+
const j = new Tabnas().use(Markdown)
|
|
32
26
|
|
|
33
|
-
j.parse('
|
|
34
|
-
|
|
35
|
-
// quoted fields use "" to escape a quote:
|
|
36
|
-
j.parse('a\n"b""c"') // => [{ a: 'b"c' }]
|
|
27
|
+
j.parse('# Hello\n\nHello *world*') // => { type: 'document', children: [{ type: 'heading', depth: 1, children: [{ type: 'text', value: 'Hello' }] }, { type: 'paragraph', children: [{ type: 'text', value: 'Hello ' }, { type: 'emphasis', children: [{ type: 'text', value: 'world' }] }] }] }
|
|
28
|
+
j.parse('# Hello') // => { type: 'document', children: [{ type: 'heading', depth: 1, children: [{ type: 'text', value: 'Hello' }] }] }
|
|
37
29
|
```
|
|
38
30
|
|
|
39
31
|
## Documentation
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
- [
|
|
44
|
-
- [
|
|
45
|
-
- [Reference](doc/reference.md) — the full API, every option, and the grammar accepted.
|
|
46
|
-
- [Concepts](doc/concepts.md) — how the plugin works on the engine and why.
|
|
47
|
-
|
|
48
|
-
For the Go version, see [../go/README.md](../go/README.md).
|
|
49
|
-
|
|
50
|
-
## Grammar diagram
|
|
51
|
-
|
|
52
|
-
The live grammar as a railroad diagram (regenerated with
|
|
53
|
-
[`@tabnas/railroad`](https://github.com/tabnas/railroad)):
|
|
54
|
-
|
|
55
|
-

|
|
56
|
-
|
|
57
|
-
ASCII version: [`doc/grammar.txt`](doc/grammar.txt). The grammar source is the
|
|
58
|
-
top-level [`markdown-grammar.jsonic`](../markdown-grammar.jsonic), embedded by
|
|
59
|
-
[`embed-grammar.js`](embed-grammar.js) during `npm run build`.
|
|
60
|
-
|
|
61
|
-
## License
|
|
62
|
-
|
|
63
|
-
Copyright (c) 2021-2025 Richard Rodger and other contributors,
|
|
64
|
-
[MIT License](LICENSE).
|
|
33
|
+
- [Tutorial](doc/tutorial.md) — first parse in 5 minutes.
|
|
34
|
+
- [How-to guide](doc/guide.md) — task recipes.
|
|
35
|
+
- [Reference](doc/reference.md) — API + options + AST.
|
|
36
|
+
- [Concepts](doc/concepts.md) — how it works.
|
package/dist/markdown.d.ts
CHANGED
|
@@ -1,30 +1,90 @@
|
|
|
1
|
-
import { Plugin
|
|
2
|
-
type MarkdownOptions = {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
header: boolean;
|
|
8
|
-
object: boolean;
|
|
9
|
-
stream: null | ((what: string, record?: Record<string, any> | Error) => void);
|
|
10
|
-
strict: boolean;
|
|
11
|
-
field: {
|
|
12
|
-
separation: null | string;
|
|
13
|
-
nonameprefix: string;
|
|
14
|
-
empty: any;
|
|
15
|
-
names: undefined | string[];
|
|
16
|
-
exact: boolean;
|
|
17
|
-
};
|
|
18
|
-
record: {
|
|
19
|
-
separators: null | string;
|
|
20
|
-
empty: boolean;
|
|
21
|
-
};
|
|
22
|
-
string: {
|
|
23
|
-
quote: string;
|
|
24
|
-
markdown: null | boolean;
|
|
25
|
-
};
|
|
1
|
+
import { Plugin } from '@tabnas/parser';
|
|
2
|
+
export type MarkdownOptions = {
|
|
3
|
+
/** Enable GFM extensions (strikethrough `~~`, task lists, tables — tables deferred, see dx-report). */
|
|
4
|
+
gfm?: boolean;
|
|
5
|
+
/** When true, a single soft break becomes a hard break. Default false. */
|
|
6
|
+
breaks?: boolean;
|
|
26
7
|
};
|
|
8
|
+
export type DocumentNode = {
|
|
9
|
+
type: 'document';
|
|
10
|
+
children: Block[];
|
|
11
|
+
};
|
|
12
|
+
export type Block = HeadingNode | ParagraphNode | BlockquoteNode | ListNode | ListItemNode | CodeNode | HtmlNode | ThematicBreakNode;
|
|
13
|
+
export type HeadingNode = {
|
|
14
|
+
type: 'heading';
|
|
15
|
+
depth: 1 | 2 | 3 | 4 | 5 | 6;
|
|
16
|
+
children: Inline[];
|
|
17
|
+
};
|
|
18
|
+
export type ParagraphNode = {
|
|
19
|
+
type: 'paragraph';
|
|
20
|
+
children: Inline[];
|
|
21
|
+
};
|
|
22
|
+
export type BlockquoteNode = {
|
|
23
|
+
type: 'blockquote';
|
|
24
|
+
children: Block[];
|
|
25
|
+
};
|
|
26
|
+
export type ListNode = {
|
|
27
|
+
type: 'list';
|
|
28
|
+
ordered: boolean;
|
|
29
|
+
start: number | null;
|
|
30
|
+
spread: boolean;
|
|
31
|
+
children: ListItemNode[];
|
|
32
|
+
};
|
|
33
|
+
export type ListItemNode = {
|
|
34
|
+
type: 'listItem';
|
|
35
|
+
spread: boolean;
|
|
36
|
+
children: Block[];
|
|
37
|
+
};
|
|
38
|
+
export type CodeNode = {
|
|
39
|
+
type: 'code';
|
|
40
|
+
lang: string | null;
|
|
41
|
+
meta: string | null;
|
|
42
|
+
value: string;
|
|
43
|
+
};
|
|
44
|
+
export type HtmlNode = {
|
|
45
|
+
type: 'html';
|
|
46
|
+
value: string;
|
|
47
|
+
};
|
|
48
|
+
export type ThematicBreakNode = {
|
|
49
|
+
type: 'thematicBreak';
|
|
50
|
+
};
|
|
51
|
+
export type Inline = TextNode | EmphasisNode | StrongNode | InlineCodeNode | LinkNode | ImageNode | BreakNode | DeleteNode;
|
|
52
|
+
export type TextNode = {
|
|
53
|
+
type: 'text';
|
|
54
|
+
value: string;
|
|
55
|
+
};
|
|
56
|
+
export type EmphasisNode = {
|
|
57
|
+
type: 'emphasis';
|
|
58
|
+
children: Inline[];
|
|
59
|
+
};
|
|
60
|
+
export type StrongNode = {
|
|
61
|
+
type: 'strong';
|
|
62
|
+
children: Inline[];
|
|
63
|
+
};
|
|
64
|
+
export type InlineCodeNode = {
|
|
65
|
+
type: 'inlineCode';
|
|
66
|
+
value: string;
|
|
67
|
+
};
|
|
68
|
+
export type LinkNode = {
|
|
69
|
+
type: 'link';
|
|
70
|
+
url: string;
|
|
71
|
+
title: string | null;
|
|
72
|
+
children: Inline[];
|
|
73
|
+
};
|
|
74
|
+
export type ImageNode = {
|
|
75
|
+
type: 'image';
|
|
76
|
+
url: string;
|
|
77
|
+
title: string | null;
|
|
78
|
+
alt: string;
|
|
79
|
+
};
|
|
80
|
+
export type BreakNode = {
|
|
81
|
+
type: 'break';
|
|
82
|
+
};
|
|
83
|
+
export type DeleteNode = {
|
|
84
|
+
type: 'delete';
|
|
85
|
+
children: Inline[];
|
|
86
|
+
};
|
|
87
|
+
declare function parseInline(text: string, opts: Required<MarkdownOptions>): Inline[];
|
|
88
|
+
declare function parseDocument(src: string, opts: Required<MarkdownOptions>): DocumentNode;
|
|
27
89
|
declare const Markdown: Plugin;
|
|
28
|
-
|
|
29
|
-
export { Markdown, buildMarkdownStringMatcher };
|
|
30
|
-
export type { MarkdownOptions };
|
|
90
|
+
export { Markdown, parseDocument, parseInline, };
|