@tanstack/markdown 0.0.12 → 0.0.14
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.js +25 -32
- package/dist/inline.d.ts.map +1 -1
- package/dist/inline.js +108 -207
- package/dist/octane.d.ts.map +1 -1
- package/dist/octane.js +20 -21
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +51 -72
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +20 -21
- package/dist/utils.d.ts +6 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +33 -23
- package/package.json +28 -25
- package/skills/custom-extensions/SKILL.md +1 -1
- package/skills/docs-features/SKILL.md +1 -1
- package/skills/octane-rendering/SKILL.md +1 -1
- package/skills/production-pipelines/SKILL.md +2 -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 +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
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
23
|
- 4.9 KB gzip parser
|
|
6
24
|
- 6.7 KB gzip HTML renderer
|
|
7
|
-
- 6.
|
|
8
|
-
- 6.
|
|
25
|
+
- 6.6 KB gzip React adapter
|
|
26
|
+
- 6.6 KB gzip Octane adapter
|
|
9
27
|
- zero runtime dependencies
|
|
10
28
|
- serializable AST
|
|
11
29
|
- safe defaults for raw HTML and executable URLs
|
|
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.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':
|
|
@@ -82,15 +82,10 @@ function renderInlines(nodes, options) {
|
|
|
82
82
|
}
|
|
83
83
|
function renderCodeBlock(node, options) {
|
|
84
84
|
const lang = node.lang ?? 'plaintext';
|
|
85
|
-
const preAttrs =
|
|
86
|
-
|
|
87
|
-
`data-
|
|
88
|
-
node.
|
|
89
|
-
node.file ? `data-filename="${escapeAttr(node.file)}"` : '',
|
|
90
|
-
node.framework ? `data-framework="${escapeAttr(node.framework)}"` : '',
|
|
91
|
-
]
|
|
92
|
-
.filter(Boolean)
|
|
93
|
-
.join(' ');
|
|
85
|
+
const preAttrs = `class="tm-code${options.codeLineNumbers ? ' tm-code--line-numbers' : ''}" data-lang="${escapeAttr(lang)}"`
|
|
86
|
+
+ (node.title ? ` data-code-title="${escapeAttr(node.title)}"` : '')
|
|
87
|
+
+ (node.file ? ` data-filename="${escapeAttr(node.file)}"` : '')
|
|
88
|
+
+ (node.framework ? ` data-framework="${escapeAttr(node.framework)}"` : '');
|
|
94
89
|
const html = options.highlighter?.(node.value, lang, {
|
|
95
90
|
...(node.highlightLines && { highlightLines: node.highlightLines }),
|
|
96
91
|
...(options.codeLineNumbers !== undefined && { lineNumbers: options.codeLineNumbers }),
|
|
@@ -101,14 +96,18 @@ function renderCodeBlock(node, options) {
|
|
|
101
96
|
return `<figure class="tm-code-frame" data-lang="${escapeAttr(lang)}"><figcaption>${escapeHtml(node.title)}</figcaption>${pre}</figure>`;
|
|
102
97
|
}
|
|
103
98
|
function renderListItemChildren(children, checked, loose, options) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
99
|
+
let result = checked === undefined ? '' : `<input type="checkbox" disabled${checked ? ' checked' : ''}> `;
|
|
100
|
+
for (let index = 0; index < children.length; index++) {
|
|
101
|
+
const child = children[index];
|
|
102
|
+
if (child.type === 'paragraph' && (!loose || index === 0)) {
|
|
103
|
+
result += renderInlines(child.children, options);
|
|
104
|
+
if (loose)
|
|
105
|
+
result = `<p>${result}</p>`;
|
|
106
|
+
}
|
|
107
|
+
else
|
|
108
|
+
result += (index ? '\n' : '') + renderBlock(child, options);
|
|
110
109
|
}
|
|
111
|
-
return
|
|
110
|
+
return result;
|
|
112
111
|
}
|
|
113
112
|
function renderCallout(node, options) {
|
|
114
113
|
const kind = node.kind.toLowerCase();
|
|
@@ -122,29 +121,26 @@ function renderFootnotes(items, options) {
|
|
|
122
121
|
function renderFootnoteItem(item, options) {
|
|
123
122
|
const backref = renderFootnoteBackrefs(item);
|
|
124
123
|
const lastIndex = item.children.length - 1;
|
|
125
|
-
|
|
126
|
-
return `<p>${backref.trimStart()}</p>`;
|
|
127
|
-
return item.children
|
|
124
|
+
const result = item.children
|
|
128
125
|
.map((child, index) => {
|
|
129
126
|
if (index === lastIndex && child.type === 'paragraph') {
|
|
130
127
|
return `<p>${renderInlines(child.children, options)}${backref}</p>`;
|
|
131
128
|
}
|
|
132
129
|
return renderBlock(child, options);
|
|
133
|
-
})
|
|
134
|
-
|
|
130
|
+
});
|
|
131
|
+
if (item.children[lastIndex]?.type !== 'paragraph')
|
|
132
|
+
result.push(`<p>${backref.trimStart()}</p>`);
|
|
133
|
+
return result.join('\n');
|
|
135
134
|
}
|
|
136
135
|
function renderFootnoteBackrefs(item) {
|
|
137
136
|
let result = '';
|
|
138
137
|
for (let index = 1; index <= (item.referenceCount ?? 1); index++) {
|
|
139
|
-
const referenceId =
|
|
138
|
+
const referenceId = footnoteReferenceId(item.id, index);
|
|
140
139
|
const label = index === 1 ? `${item.number}` : `${item.number}-${index}`;
|
|
141
140
|
result += ` <a data-footnote-backref="" aria-label="Back to reference ${label}" class="data-footnote-backref" href="#user-content-fnref-${escapeAttr(referenceId)}">↩</a>`;
|
|
142
141
|
}
|
|
143
142
|
return result;
|
|
144
143
|
}
|
|
145
|
-
function footnoteReferenceId(node) {
|
|
146
|
-
return node.referenceIndex && node.referenceIndex > 1 ? `${node.id}-${node.referenceIndex}` : node.id;
|
|
147
|
-
}
|
|
148
144
|
function renderComponent(node, options) {
|
|
149
145
|
const tag = node.tagName ?? 'md-comment-component';
|
|
150
146
|
const attrs = renderComponentAttrs(node);
|
|
@@ -183,8 +179,5 @@ function renderComponentAttrs(node) {
|
|
|
183
179
|
if (!props['data-attributes'])
|
|
184
180
|
props['data-attributes'] = JSON.stringify(node.attributes);
|
|
185
181
|
}
|
|
186
|
-
|
|
187
|
-
if (!entries.length)
|
|
188
|
-
return '';
|
|
189
|
-
return ` ${entries.map(([key, value]) => `${key}="${escapeAttr(value)}"`).join(' ')}`;
|
|
182
|
+
return Object.entries(props).map(([key, value]) => ` ${key}="${escapeAttr(value)}"`).join('');
|
|
190
183
|
}
|
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"}
|