@tanstack/markdown 0.0.13 → 0.0.15
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 +22 -2
- package/dist/extensions/callouts.d.ts.map +1 -1
- package/dist/extensions/callouts.js +0 -5
- package/dist/extensions/comment-components.d.ts.map +1 -1
- package/dist/extensions/comment-components.js +16 -34
- package/dist/extensions/headings.js +8 -7
- package/dist/extensions/shared.d.ts.map +1 -1
- package/dist/extensions/shared.js +2 -9
- package/dist/extensions/tabs.d.ts.map +1 -1
- package/dist/extensions/tabs.js +11 -18
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +33 -34
- package/dist/inline.d.ts.map +1 -1
- package/dist/inline.js +106 -212
- package/dist/octane.d.ts.map +1 -1
- package/dist/octane.js +28 -23
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +166 -194
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +45 -37
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +6 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +37 -25
- package/package.json +11 -1
- package/skills/custom-extensions/SKILL.md +11 -4
- package/skills/docs-features/SKILL.md +1 -1
- package/skills/docs-features/references/docs-metadata.md +1 -1
- package/skills/octane-rendering/SKILL.md +1 -1
- package/skills/production-pipelines/SKILL.md +10 -2
- package/skills/react-rendering/SKILL.md +1 -1
- package/skills/render-markdown/SKILL.md +1 -1
- package/skills/render-markdown/references/ast-and-options.md +8 -3
package/README.md
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source
|
|
4
|
+
media="(prefers-color-scheme: dark)"
|
|
5
|
+
srcset="https://tanstack.com/api/readme/markdown.png?theme=dark"
|
|
6
|
+
/>
|
|
7
|
+
<source
|
|
8
|
+
media="(prefers-color-scheme: light)"
|
|
9
|
+
srcset="https://tanstack.com/api/readme/markdown.png"
|
|
10
|
+
/>
|
|
11
|
+
<img
|
|
12
|
+
src="https://tanstack.com/api/readme/markdown.png"
|
|
13
|
+
alt="TanStack Markdown"
|
|
14
|
+
width="900"
|
|
15
|
+
/>
|
|
16
|
+
</picture>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
1
19
|
# TanStack Markdown
|
|
2
20
|
|
|
3
21
|
A tiny, fast, deterministic Markdown parser and renderer for blogs and documentation.
|
|
4
22
|
|
|
5
|
-
-
|
|
6
|
-
- 6.
|
|
23
|
+
- 5.0 KB gzip parser
|
|
24
|
+
- 6.8 KB gzip HTML renderer
|
|
7
25
|
- 6.7 KB gzip React adapter
|
|
8
26
|
- 6.7 KB gzip Octane adapter
|
|
9
27
|
- zero runtime dependencies
|
|
@@ -12,6 +30,8 @@ A tiny, fast, deterministic Markdown parser and renderer for blogs and documenta
|
|
|
12
30
|
- optional docs extensions and external syntax highlighting
|
|
13
31
|
- optional AI streaming profile
|
|
14
32
|
|
|
33
|
+
Bundle sizes include the parser and exclude framework runtimes and syntax highlighters.
|
|
34
|
+
|
|
15
35
|
```bash
|
|
16
36
|
pnpm add @tanstack/markdown
|
|
17
37
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callouts.d.ts","sourceRoot":"","sources":["../../src/extensions/callouts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEjE,wBAAgB,iBAAiB,IAAI,iBAAiB,CAKrD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"callouts.d.ts","sourceRoot":"","sources":["../../src/extensions/callouts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEjE,wBAAgB,iBAAiB,IAAI,iBAAiB,CAKrD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,SAAS,CAyB/H"}
|
|
@@ -15,11 +15,6 @@ export function parseCalloutBlock(context) {
|
|
|
15
15
|
let cursor = context.index + 1;
|
|
16
16
|
while (cursor < context.lines.length) {
|
|
17
17
|
const line = context.lines[cursor] ?? '';
|
|
18
|
-
if (/^\s*$/.test(line)) {
|
|
19
|
-
body.push('');
|
|
20
|
-
cursor++;
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
18
|
const quoted = line.match(/^ {0,3}>\s?(.*)$/);
|
|
24
19
|
if (!quoted)
|
|
25
20
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment-components.d.ts","sourceRoot":"","sources":["../../src/extensions/comment-components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEnE,MAAM,WAAW,uBAAuB;IACtC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,aAAa,CAAA;CAC5D;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,uBAA4B,GAAG,iBAAiB,CAKnG;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACpE,OAAO,GAAE,uBAA4B,GACpC,aAAa,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"comment-components.d.ts","sourceRoot":"","sources":["../../src/extensions/comment-components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEnE,MAAM,WAAW,uBAAuB;IACtC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,aAAa,CAAA;CAC5D;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,uBAA4B,GAAG,iBAAiB,CAKnG;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACpE,OAAO,GAAE,uBAA4B,GACpC,aAAa,GAAG,SAAS,CA0B3B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAQhF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOrE"}
|
|
@@ -9,35 +9,26 @@ export function parseCommentComponentBlock(context, options = {}) {
|
|
|
9
9
|
const start = parseComponentComment(line);
|
|
10
10
|
if (!start)
|
|
11
11
|
return undefined;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let cursor = context.index + 1;
|
|
23
|
-
let foundEnd = false;
|
|
24
|
-
while (cursor < context.lines.length) {
|
|
25
|
-
const candidate = context.lines[cursor] ?? '';
|
|
26
|
-
if (isEndComment(candidate, start.name)) {
|
|
27
|
-
foundEnd = true;
|
|
28
|
-
cursor++;
|
|
29
|
-
break;
|
|
12
|
+
let body;
|
|
13
|
+
let consumed = 1;
|
|
14
|
+
if (start.block) {
|
|
15
|
+
const end = new RegExp(`^ {0,3}<!--\\s*::end:${start.name}\\s*-->\\s*$`, 'i');
|
|
16
|
+
for (let cursor = context.index + 1; cursor < context.lines.length; cursor++) {
|
|
17
|
+
if (end.test(context.lines[cursor])) {
|
|
18
|
+
body = context.lines.slice(context.index + 1, cursor).join('\n');
|
|
19
|
+
consumed = cursor - context.index + 1;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
30
22
|
}
|
|
31
|
-
body.push(candidate);
|
|
32
|
-
cursor++;
|
|
33
23
|
}
|
|
34
|
-
context.consume(
|
|
35
|
-
|
|
24
|
+
context.consume(consumed);
|
|
25
|
+
const node = {
|
|
36
26
|
type: 'component',
|
|
37
27
|
name: start.name,
|
|
38
28
|
attributes: start.attributes,
|
|
39
|
-
children:
|
|
40
|
-
}
|
|
29
|
+
children: body === undefined ? [] : context.parseBlocks(body),
|
|
30
|
+
};
|
|
31
|
+
return options.transformComponent?.(node) ?? node;
|
|
41
32
|
}
|
|
42
33
|
export function parseComponentComment(line) {
|
|
43
34
|
const match = line.match(/^ {0,3}<!--\s*::(start:)?([A-Za-z][\w-]*)(.*?)\s*-->\s*$/);
|
|
@@ -50,19 +41,10 @@ export function parseComponentComment(line) {
|
|
|
50
41
|
};
|
|
51
42
|
}
|
|
52
43
|
export function parseAttributes(value) {
|
|
53
|
-
const attrs =
|
|
44
|
+
const attrs = Object.create(null);
|
|
54
45
|
const regex = /([A-Za-z_][\w:-]*)(?:=(?:"([^"]*)"|'([^']*)'|([^\s"']+)))?/g;
|
|
55
46
|
for (const match of value.matchAll(regex)) {
|
|
56
47
|
attrs[match[1]] = match[2] ?? match[3] ?? match[4] ?? 'true';
|
|
57
48
|
}
|
|
58
49
|
return attrs;
|
|
59
50
|
}
|
|
60
|
-
function transform(node, options) {
|
|
61
|
-
return options.transformComponent?.(node) ?? node;
|
|
62
|
-
}
|
|
63
|
-
function isEndComment(line, name) {
|
|
64
|
-
return new RegExp(`^ {0,3}<!--\\s*::end:${escapeRegex(name)}\\s*-->\\s*$`, 'i').test(line);
|
|
65
|
-
}
|
|
66
|
-
function escapeRegex(value) {
|
|
67
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
68
|
-
}
|
|
@@ -13,13 +13,13 @@ export function headingCollectionExtension(options = {}) {
|
|
|
13
13
|
export function collectMarkdownHeadings(document, options = {}) {
|
|
14
14
|
const headings = [];
|
|
15
15
|
const skip = new Set(options.skipComponentNames ?? ['tabs']);
|
|
16
|
-
collectFromBlocks(document.children, headings, undefined,
|
|
16
|
+
collectFromBlocks(document.children, headings, undefined, skip);
|
|
17
17
|
return headings;
|
|
18
18
|
}
|
|
19
|
-
function collectFromBlocks(blocks, headings, framework,
|
|
19
|
+
function collectFromBlocks(blocks, headings, framework, skipComponentNames) {
|
|
20
20
|
for (const block of blocks) {
|
|
21
21
|
if (block.type === 'heading') {
|
|
22
|
-
if (
|
|
22
|
+
if (block.id) {
|
|
23
23
|
const heading = {
|
|
24
24
|
id: block.id,
|
|
25
25
|
text: plainText(block.children),
|
|
@@ -34,18 +34,19 @@ function collectFromBlocks(blocks, headings, framework, insideSkippedComponent,
|
|
|
34
34
|
}
|
|
35
35
|
if (block.type === 'list') {
|
|
36
36
|
for (const item of block.items)
|
|
37
|
-
collectFromBlocks(item.children, headings, framework,
|
|
37
|
+
collectFromBlocks(item.children, headings, framework, skipComponentNames);
|
|
38
38
|
continue;
|
|
39
39
|
}
|
|
40
40
|
if (block.type === 'blockquote' || block.type === 'callout') {
|
|
41
|
-
collectFromBlocks(block.children, headings, framework,
|
|
41
|
+
collectFromBlocks(block.children, headings, framework, skipComponentNames);
|
|
42
42
|
continue;
|
|
43
43
|
}
|
|
44
44
|
if (block.type === 'component') {
|
|
45
45
|
const name = block.name.toLowerCase();
|
|
46
|
-
|
|
46
|
+
if (skipComponentNames.has(name))
|
|
47
|
+
continue;
|
|
47
48
|
const nextFramework = block.tagName === 'md-framework-panel' ? block.properties?.['data-framework'] ?? framework : framework;
|
|
48
|
-
collectFromBlocks(block.children, headings, nextFramework,
|
|
49
|
+
collectFromBlocks(block.children, headings, nextFramework, skipComponentNames);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/extensions/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/extensions/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG3D,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,SAAS,EAAE,CAAA;CACtB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAsBxD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,CAqB5F;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAWtD;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CA4BzF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,UAEnD"}
|
|
@@ -23,8 +23,7 @@ export function blocksToText(blocks) {
|
|
|
23
23
|
.join('\n');
|
|
24
24
|
}
|
|
25
25
|
export function splitByHeading(children, forcedDepth) {
|
|
26
|
-
const
|
|
27
|
-
const depth = forcedDepth ?? Math.min(...headings.map(heading => heading.depth));
|
|
26
|
+
const depth = forcedDepth ?? children.reduce((depth, child) => child.type === 'heading' ? Math.min(depth, child.depth) : depth, Infinity);
|
|
28
27
|
if (!Number.isFinite(depth))
|
|
29
28
|
return [];
|
|
30
29
|
const sections = [];
|
|
@@ -63,7 +62,7 @@ export function markFrameworkHeadings(blocks, framework) {
|
|
|
63
62
|
framework,
|
|
64
63
|
};
|
|
65
64
|
}
|
|
66
|
-
if (block.type === 'blockquote' || block.type === 'callout') {
|
|
65
|
+
if (block.type === 'blockquote' || block.type === 'callout' || block.type === 'component') {
|
|
67
66
|
return {
|
|
68
67
|
...block,
|
|
69
68
|
children: markFrameworkHeadings(block.children, framework),
|
|
@@ -78,12 +77,6 @@ export function markFrameworkHeadings(blocks, framework) {
|
|
|
78
77
|
})),
|
|
79
78
|
};
|
|
80
79
|
}
|
|
81
|
-
if (block.type === 'component') {
|
|
82
|
-
return {
|
|
83
|
-
...block,
|
|
84
|
-
children: markFrameworkHeadings(block.children, framework),
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
80
|
return block;
|
|
88
81
|
});
|
|
89
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/extensions/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,aAAa,CAAA;AAK3D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAQzE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAkCpE;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/extensions/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,aAAa,CAAA;AAK3D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAQzE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAkCpE;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CA0B9E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAgCvE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CA2BvE"}
|
package/dist/extensions/tabs.js
CHANGED
|
@@ -45,16 +45,13 @@ export function transformFileTabs(node) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
export function transformPackageManagerTabs(node) {
|
|
48
|
-
const packagesByFramework =
|
|
48
|
+
const packagesByFramework = Object.create(null);
|
|
49
49
|
for (const line of blocksToText(node.children).split('\n')) {
|
|
50
|
-
const
|
|
51
|
-
if (!trimmed)
|
|
52
|
-
continue;
|
|
53
|
-
const colon = trimmed.indexOf(':');
|
|
50
|
+
const colon = line.indexOf(':');
|
|
54
51
|
if (colon === -1)
|
|
55
52
|
continue;
|
|
56
|
-
const framework =
|
|
57
|
-
const packages =
|
|
53
|
+
const framework = line.slice(0, colon).trim().toLowerCase();
|
|
54
|
+
const packages = line.slice(colon + 1).trim().split(/\s+/).filter(Boolean);
|
|
58
55
|
if (!framework || packages.length === 0)
|
|
59
56
|
continue;
|
|
60
57
|
packagesByFramework[framework] ??= [];
|
|
@@ -76,13 +73,13 @@ export function transformPackageManagerTabs(node) {
|
|
|
76
73
|
}
|
|
77
74
|
export function transformBundlerTabs(node) {
|
|
78
75
|
const sections = splitByHeading(node.children);
|
|
79
|
-
const selected =
|
|
76
|
+
const selected = bundlers.flatMap(bundler => {
|
|
77
|
+
const section = sections.find(section => section.name.toLowerCase() === bundler);
|
|
78
|
+
return section ? [section] : [];
|
|
79
|
+
});
|
|
80
80
|
if (!selected.length)
|
|
81
81
|
return node;
|
|
82
|
-
const tabs =
|
|
83
|
-
.map(bundler => selected.find(section => section.name.toLowerCase() === bundler))
|
|
84
|
-
.filter((section) => Boolean(section))
|
|
85
|
-
.map(section => ({ slug: section.name.toLowerCase(), name: section.name.toLowerCase() }));
|
|
82
|
+
const tabs = selected.map(section => ({ slug: section.name.toLowerCase(), name: section.name.toLowerCase() }));
|
|
86
83
|
return {
|
|
87
84
|
...node,
|
|
88
85
|
properties: {
|
|
@@ -90,15 +87,14 @@ export function transformBundlerTabs(node) {
|
|
|
90
87
|
'data-attributes': JSON.stringify({ tabs }),
|
|
91
88
|
'data-bundler-meta': JSON.stringify({ bundlers: tabs.map(tab => tab.slug) }),
|
|
92
89
|
},
|
|
93
|
-
children:
|
|
94
|
-
const section = selected.find(section => section.name.toLowerCase() === tab.slug);
|
|
90
|
+
children: selected.map((section, index) => {
|
|
95
91
|
return {
|
|
96
92
|
type: 'component',
|
|
97
93
|
name: 'tab-panel',
|
|
98
94
|
tagName: 'md-tab-panel',
|
|
99
95
|
attributes: {},
|
|
100
96
|
properties: {
|
|
101
|
-
'data-tab-slug':
|
|
97
|
+
'data-tab-slug': section.name.toLowerCase(),
|
|
102
98
|
'data-tab-index': String(index),
|
|
103
99
|
'data-content': section.children.length === 1 && section.children[0]?.type === 'code' ? 'code-only' : 'mixed',
|
|
104
100
|
},
|
|
@@ -140,6 +136,3 @@ function resolveInstallMode(value) {
|
|
|
140
136
|
return mode;
|
|
141
137
|
return 'install';
|
|
142
138
|
}
|
|
143
|
-
function isBundler(value) {
|
|
144
|
-
return bundlers.includes(value);
|
|
145
|
-
}
|
package/dist/html.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAA8E,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAGlM,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAGpF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA0ChF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA4BlF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAE9F"}
|
package/dist/html.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseMarkdown } from './parser.js';
|
|
2
|
-
import { escapeAttr, escapeHtml } from './utils.js';
|
|
2
|
+
import { escapeAttr, escapeHtml, footnoteReferenceId } from './utils.js';
|
|
3
3
|
export function renderHtml(input, options = {}) {
|
|
4
4
|
const document = typeof input === 'string' ? parseMarkdown(input, options) : input;
|
|
5
5
|
return document.children.map(node => renderBlock(node, options)).join('\n');
|
|
@@ -20,7 +20,7 @@ export function renderBlock(node, options = {}) {
|
|
|
20
20
|
return renderCodeBlock(node, options);
|
|
21
21
|
case 'list': {
|
|
22
22
|
const tag = node.ordered ? 'ol' : 'ul';
|
|
23
|
-
const start = node.ordered && node.start && node.start !== 1 ? ` start="${node.start}"` : '';
|
|
23
|
+
const start = node.ordered && node.start !== undefined && node.start !== 1 ? ` start="${node.start}"` : '';
|
|
24
24
|
const items = node.items.map(item => `<li>${renderListItemChildren(item.children, item.checked, node.loose, options)}</li>`).join('\n');
|
|
25
25
|
return `<${tag}${start}>\n${items}\n</${tag}>`;
|
|
26
26
|
}
|
|
@@ -63,7 +63,7 @@ export function renderInline(node, options = {}) {
|
|
|
63
63
|
case 'strike':
|
|
64
64
|
return `<del>${renderInlines(node.children, options)}</del>`;
|
|
65
65
|
case 'footnoteReference':
|
|
66
|
-
return `<sup><a id="user-content-fnref-${escapeAttr(footnoteReferenceId(node))}" data-footnote-ref="" aria-describedby="footnote-label" href="#user-content-fn-${escapeAttr(node.id)}">${node.number}</a></sup>`;
|
|
66
|
+
return `<sup><a id="user-content-fnref-${escapeAttr(footnoteReferenceId(node.id, node.referenceIndex))}" data-footnote-ref="" aria-describedby="footnote-label" href="#user-content-fn-${escapeAttr(node.id)}">${node.number}</a></sup>`;
|
|
67
67
|
case 'link':
|
|
68
68
|
return `<a href="${escapeAttr(node.href)}"${node.title ? ` title="${escapeAttr(node.title)}"` : ''}>${renderInlines(node.children, options)}</a>`;
|
|
69
69
|
case 'image':
|
|
@@ -72,6 +72,8 @@ export function renderInline(node, options = {}) {
|
|
|
72
72
|
return '<br>';
|
|
73
73
|
case 'inlineHtml':
|
|
74
74
|
return options.allowHtml ? node.value : escapeHtml(node.value);
|
|
75
|
+
case 'inlineComponent':
|
|
76
|
+
return renderComponent(node, options);
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
export function renderDocument(document, options = {}) {
|
|
@@ -82,16 +84,13 @@ function renderInlines(nodes, options) {
|
|
|
82
84
|
}
|
|
83
85
|
function renderCodeBlock(node, options) {
|
|
84
86
|
const lang = node.lang ?? 'plaintext';
|
|
85
|
-
const preAttrs =
|
|
86
|
-
`
|
|
87
|
-
`data-
|
|
88
|
-
node.
|
|
89
|
-
node.
|
|
90
|
-
node.framework ? `data-framework="${escapeAttr(node.framework)}"` : '',
|
|
91
|
-
]
|
|
92
|
-
.filter(Boolean)
|
|
93
|
-
.join(' ');
|
|
87
|
+
const preAttrs = `class="tm-code${options.codeLineNumbers ? ' tm-code--line-numbers' : ''}" data-lang="${escapeAttr(lang)}"`
|
|
88
|
+
+ (node.meta ? ` data-meta="${escapeAttr(node.meta)}"` : '')
|
|
89
|
+
+ (node.title ? ` data-code-title="${escapeAttr(node.title)}"` : '')
|
|
90
|
+
+ (node.file ? ` data-filename="${escapeAttr(node.file)}"` : '')
|
|
91
|
+
+ (node.framework ? ` data-framework="${escapeAttr(node.framework)}"` : '');
|
|
94
92
|
const html = options.highlighter?.(node.value, lang, {
|
|
93
|
+
...(node.meta && { meta: node.meta }),
|
|
95
94
|
...(node.highlightLines && { highlightLines: node.highlightLines }),
|
|
96
95
|
...(options.codeLineNumbers !== undefined && { lineNumbers: options.codeLineNumbers }),
|
|
97
96
|
}) ?? escapeHtml(node.value);
|
|
@@ -101,14 +100,18 @@ function renderCodeBlock(node, options) {
|
|
|
101
100
|
return `<figure class="tm-code-frame" data-lang="${escapeAttr(lang)}"><figcaption>${escapeHtml(node.title)}</figcaption>${pre}</figure>`;
|
|
102
101
|
}
|
|
103
102
|
function renderListItemChildren(children, checked, loose, options) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
let result = checked === undefined ? '' : `<input type="checkbox" disabled${checked ? ' checked' : ''}> `;
|
|
104
|
+
for (let index = 0; index < children.length; index++) {
|
|
105
|
+
const child = children[index];
|
|
106
|
+
if (child.type === 'paragraph' && (!loose || index === 0)) {
|
|
107
|
+
result += renderInlines(child.children, options);
|
|
108
|
+
if (loose)
|
|
109
|
+
result = `<p>${result}</p>`;
|
|
110
|
+
}
|
|
111
|
+
else
|
|
112
|
+
result += (index ? '\n' : '') + renderBlock(child, options);
|
|
110
113
|
}
|
|
111
|
-
return
|
|
114
|
+
return result;
|
|
112
115
|
}
|
|
113
116
|
function renderCallout(node, options) {
|
|
114
117
|
const kind = node.kind.toLowerCase();
|
|
@@ -122,33 +125,32 @@ function renderFootnotes(items, options) {
|
|
|
122
125
|
function renderFootnoteItem(item, options) {
|
|
123
126
|
const backref = renderFootnoteBackrefs(item);
|
|
124
127
|
const lastIndex = item.children.length - 1;
|
|
125
|
-
|
|
126
|
-
return `<p>${backref.trimStart()}</p>`;
|
|
127
|
-
return item.children
|
|
128
|
+
const result = item.children
|
|
128
129
|
.map((child, index) => {
|
|
129
130
|
if (index === lastIndex && child.type === 'paragraph') {
|
|
130
131
|
return `<p>${renderInlines(child.children, options)}${backref}</p>`;
|
|
131
132
|
}
|
|
132
133
|
return renderBlock(child, options);
|
|
133
|
-
})
|
|
134
|
-
|
|
134
|
+
});
|
|
135
|
+
if (item.children[lastIndex]?.type !== 'paragraph')
|
|
136
|
+
result.push(`<p>${backref.trimStart()}</p>`);
|
|
137
|
+
return result.join('\n');
|
|
135
138
|
}
|
|
136
139
|
function renderFootnoteBackrefs(item) {
|
|
137
140
|
let result = '';
|
|
138
141
|
for (let index = 1; index <= (item.referenceCount ?? 1); index++) {
|
|
139
|
-
const referenceId =
|
|
142
|
+
const referenceId = footnoteReferenceId(item.id, index);
|
|
140
143
|
const label = index === 1 ? `${item.number}` : `${item.number}-${index}`;
|
|
141
144
|
result += ` <a data-footnote-backref="" aria-label="Back to reference ${label}" class="data-footnote-backref" href="#user-content-fnref-${escapeAttr(referenceId)}">↩</a>`;
|
|
142
145
|
}
|
|
143
146
|
return result;
|
|
144
147
|
}
|
|
145
|
-
function footnoteReferenceId(node) {
|
|
146
|
-
return node.referenceIndex && node.referenceIndex > 1 ? `${node.id}-${node.referenceIndex}` : node.id;
|
|
147
|
-
}
|
|
148
148
|
function renderComponent(node, options) {
|
|
149
|
-
const tag = node.tagName ?? 'md-comment-component';
|
|
149
|
+
const tag = node.tagName ?? (node.type === 'inlineComponent' ? 'span' : 'md-comment-component');
|
|
150
150
|
const attrs = renderComponentAttrs(node);
|
|
151
|
-
const children = node.
|
|
151
|
+
const children = node.type === 'inlineComponent'
|
|
152
|
+
? renderInlines(node.children, options)
|
|
153
|
+
: node.children.map(child => renderBlock(child, options)).join('\n');
|
|
152
154
|
return `<${tag}${attrs}>${children}</${tag}>`;
|
|
153
155
|
}
|
|
154
156
|
function renderTableCell(tag, cell, align, options) {
|
|
@@ -183,8 +185,5 @@ function renderComponentAttrs(node) {
|
|
|
183
185
|
if (!props['data-attributes'])
|
|
184
186
|
props['data-attributes'] = JSON.stringify(node.attributes);
|
|
185
187
|
}
|
|
186
|
-
|
|
187
|
-
if (!entries.length)
|
|
188
|
-
return '';
|
|
189
|
-
return ` ${entries.map(([key, value]) => `${key}="${escapeAttr(value)}"`).join(' ')}`;
|
|
188
|
+
return Object.entries(props).map(([key, value]) => ` ${key}="${escapeAttr(value)}"`).join('');
|
|
190
189
|
}
|
package/dist/inline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,UAAU,EAAE,CAQnF"}
|