@azerion/bunosaurus-mdx-loader 0.0.0-stage → 4.0.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/README.md +57 -2
- package/lib/createMDXLoader.d.ts +14 -0
- package/lib/createMDXLoader.d.ts.map +1 -0
- package/lib/createMDXLoader.js +52 -0
- package/lib/createMDXLoader.js.map +1 -0
- package/lib/format.d.ts +14 -0
- package/lib/format.d.ts.map +1 -0
- package/lib/format.js +41 -0
- package/lib/format.js.map +1 -0
- package/lib/frontMatter.d.ts +13 -0
- package/lib/frontMatter.d.ts.map +1 -0
- package/lib/frontMatter.js +23 -0
- package/lib/frontMatter.js.map +1 -0
- package/lib/index.d.ts +35 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +15 -0
- package/lib/index.js.map +1 -0
- package/lib/loader.d.ts +11 -0
- package/lib/loader.d.ts.map +1 -0
- package/lib/loader.js +170 -0
- package/lib/loader.js.map +1 -0
- package/lib/options.d.ts +35 -0
- package/lib/options.d.ts.map +1 -0
- package/lib/options.js +9 -0
- package/lib/options.js.map +1 -0
- package/lib/preprocessor.d.ts +18 -0
- package/lib/preprocessor.d.ts.map +1 -0
- package/lib/preprocessor.js +34 -0
- package/lib/preprocessor.js.map +1 -0
- package/lib/processor.d.ts +49 -0
- package/lib/processor.d.ts.map +1 -0
- package/lib/processor.js +209 -0
- package/lib/processor.js.map +1 -0
- package/lib/remark/admonitions/index.d.ts +11 -0
- package/lib/remark/admonitions/index.d.ts.map +1 -0
- package/lib/remark/admonitions/index.js +107 -0
- package/lib/remark/admonitions/index.js.map +1 -0
- package/lib/remark/contentTitle/index.d.ts +13 -0
- package/lib/remark/contentTitle/index.d.ts.map +1 -0
- package/lib/remark/contentTitle/index.js +62 -0
- package/lib/remark/contentTitle/index.js.map +1 -0
- package/lib/remark/details/index.d.ts +10 -0
- package/lib/remark/details/index.d.ts.map +1 -0
- package/lib/remark/details/index.js +22 -0
- package/lib/remark/details/index.js.map +1 -0
- package/lib/remark/head/index.d.ts +10 -0
- package/lib/remark/head/index.d.ts.map +1 -0
- package/lib/remark/head/index.js +22 -0
- package/lib/remark/head/index.js.map +1 -0
- package/lib/remark/headings/index.d.ts +14 -0
- package/lib/remark/headings/index.d.ts.map +1 -0
- package/lib/remark/headings/index.js +126 -0
- package/lib/remark/headings/index.js.map +1 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.d.ts +11 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.d.ts.map +1 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.js +30 -0
- package/lib/remark/mdx1Compat/codeCompatPlugin.js.map +1 -0
- package/lib/remark/mermaid/index.d.ts +10 -0
- package/lib/remark/mermaid/index.d.ts.map +1 -0
- package/lib/remark/mermaid/index.js +34 -0
- package/lib/remark/mermaid/index.js.map +1 -0
- package/lib/remark/resolveMarkdownLinks/index.d.ts +33 -0
- package/lib/remark/resolveMarkdownLinks/index.d.ts.map +1 -0
- package/lib/remark/resolveMarkdownLinks/index.js +87 -0
- package/lib/remark/resolveMarkdownLinks/index.js.map +1 -0
- package/lib/remark/toc/index.d.ts +14 -0
- package/lib/remark/toc/index.d.ts.map +1 -0
- package/lib/remark/toc/index.js +115 -0
- package/lib/remark/toc/index.js.map +1 -0
- package/lib/remark/toc/types.d.ts +22 -0
- package/lib/remark/toc/types.d.ts.map +1 -0
- package/lib/remark/toc/types.js +9 -0
- package/lib/remark/toc/types.js.map +1 -0
- package/lib/remark/toc/utils.d.ts +26 -0
- package/lib/remark/toc/utils.d.ts.map +1 -0
- package/lib/remark/toc/utils.js +184 -0
- package/lib/remark/toc/utils.js.map +1 -0
- package/lib/remark/transformImage/index.d.ts +17 -0
- package/lib/remark/transformImage/index.d.ts.map +1 -0
- package/lib/remark/transformImage/index.js +187 -0
- package/lib/remark/transformImage/index.js.map +1 -0
- package/lib/remark/transformLinks/index.d.ts +17 -0
- package/lib/remark/transformLinks/index.d.ts.map +1 -0
- package/lib/remark/transformLinks/index.js +205 -0
- package/lib/remark/transformLinks/index.js.map +1 -0
- package/lib/remark/unusedDirectives/index.d.ts +9 -0
- package/lib/remark/unusedDirectives/index.d.ts.map +1 -0
- package/lib/remark/unusedDirectives/index.js +125 -0
- package/lib/remark/unusedDirectives/index.js.map +1 -0
- package/lib/remark/utils/index.d.ts +18 -0
- package/lib/remark/utils/index.d.ts.map +1 -0
- package/lib/remark/utils/index.js +93 -0
- package/lib/remark/utils/index.js.map +1 -0
- package/lib/serializeJS.d.ts +17 -0
- package/lib/serializeJS.d.ts.map +1 -0
- package/lib/serializeJS.js +24 -0
- package/lib/serializeJS.js.map +1 -0
- package/lib/utils.d.ts +35 -0
- package/lib/utils.d.ts.map +1 -0
- package/lib/utils.js +97 -0
- package/lib/utils.js.map +1 -0
- package/package.json +65 -4
- package/src/createMDXLoader.ts +65 -0
- package/src/format.ts +50 -0
- package/src/frontMatter.ts +31 -0
- package/src/index.ts +44 -0
- package/src/loader.ts +227 -0
- package/src/options.ts +37 -0
- package/src/preprocessor.ts +47 -0
- package/src/processor.ts +306 -0
- package/src/remark/admonitions/LICENSE +45 -0
- package/src/remark/admonitions/README.md +3 -0
- package/src/remark/admonitions/index.ts +138 -0
- package/src/remark/contentTitle/index.ts +76 -0
- package/src/remark/details/index.ts +23 -0
- package/src/remark/head/index.ts +23 -0
- package/src/remark/headings/index.ts +158 -0
- package/src/remark/mdx1Compat/codeCompatPlugin.ts +35 -0
- package/src/remark/mermaid/index.ts +35 -0
- package/src/remark/resolveMarkdownLinks/index.ts +137 -0
- package/src/remark/toc/index.ts +183 -0
- package/src/remark/toc/types.ts +29 -0
- package/src/remark/toc/utils.ts +243 -0
- package/src/remark/transformImage/index.ts +268 -0
- package/src/remark/transformLinks/index.ts +291 -0
- package/src/remark/unusedDirectives/index.ts +171 -0
- package/src/remark/utils/index.ts +99 -0
- package/src/serializeJS.ts +22 -0
- package/src/types.d.mts +40 -0
- package/src/utils.ts +134 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {visit} from 'unist-util-visit';
|
|
9
|
+
import {toString} from 'mdast-util-to-string';
|
|
10
|
+
import {
|
|
11
|
+
addTocSliceImportIfNeeded,
|
|
12
|
+
createTOCExportNodeAST,
|
|
13
|
+
findDefaultImportName,
|
|
14
|
+
getImportDeclarations,
|
|
15
|
+
isMarkdownImport,
|
|
16
|
+
isNamedExport,
|
|
17
|
+
} from './utils';
|
|
18
|
+
import type {Heading, Root} from 'mdast';
|
|
19
|
+
import type {Plugin, Transformer} from 'unified';
|
|
20
|
+
import type {MdxjsEsm, MdxJsxFlowElement} from 'mdast-util-mdx';
|
|
21
|
+
import type {TOCItems} from './types';
|
|
22
|
+
import type {ImportDeclaration} from 'estree';
|
|
23
|
+
|
|
24
|
+
interface PluginOptions {
|
|
25
|
+
name?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ComponentName (default export) => ImportDeclaration mapping
|
|
29
|
+
type MarkdownImports = Map<string, {declaration: ImportDeclaration}>;
|
|
30
|
+
|
|
31
|
+
// MdxjsEsm node representing an already existing "export const toc" declaration
|
|
32
|
+
type ExistingTOCExport = MdxjsEsm | null;
|
|
33
|
+
|
|
34
|
+
function createTocSliceImportName({
|
|
35
|
+
tocExportName,
|
|
36
|
+
componentName,
|
|
37
|
+
}: {
|
|
38
|
+
tocExportName: string;
|
|
39
|
+
componentName: string;
|
|
40
|
+
}) {
|
|
41
|
+
// The name of the toc slice import alias doesn't matter much
|
|
42
|
+
// We just need to ensure it's valid and won't conflict with other names
|
|
43
|
+
return `__${tocExportName}${componentName}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function collectImportsExports({
|
|
47
|
+
root,
|
|
48
|
+
tocExportName,
|
|
49
|
+
}: {
|
|
50
|
+
root: Root;
|
|
51
|
+
tocExportName: string;
|
|
52
|
+
}): {
|
|
53
|
+
markdownImports: MarkdownImports;
|
|
54
|
+
existingTocExport: ExistingTOCExport;
|
|
55
|
+
} {
|
|
56
|
+
const markdownImports = new Map<string, {declaration: ImportDeclaration}>();
|
|
57
|
+
let existingTocExport: MdxjsEsm | null = null;
|
|
58
|
+
|
|
59
|
+
visit(root, 'mdxjsEsm', (node) => {
|
|
60
|
+
if (!node.data?.estree) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (isNamedExport(node, tocExportName)) {
|
|
64
|
+
existingTocExport = node;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getImportDeclarations(node.data.estree).forEach((declaration) => {
|
|
68
|
+
if (!isMarkdownImport(declaration)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const componentName = findDefaultImportName(declaration);
|
|
72
|
+
if (!componentName) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
markdownImports.set(componentName, {
|
|
76
|
+
declaration,
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return {markdownImports, existingTocExport};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function collectTOCItems({
|
|
85
|
+
root,
|
|
86
|
+
tocExportName,
|
|
87
|
+
markdownImports,
|
|
88
|
+
}: {
|
|
89
|
+
root: Root;
|
|
90
|
+
tocExportName: string;
|
|
91
|
+
markdownImports: MarkdownImports;
|
|
92
|
+
}): {
|
|
93
|
+
// The toc items we collected in the tree
|
|
94
|
+
tocItems: TOCItems;
|
|
95
|
+
} {
|
|
96
|
+
const tocItems: TOCItems = [];
|
|
97
|
+
|
|
98
|
+
visit(root, (child) => {
|
|
99
|
+
if (child.type === 'heading') {
|
|
100
|
+
visitHeading(child);
|
|
101
|
+
} else if (child.type === 'mdxJsxFlowElement') {
|
|
102
|
+
visitJSXElement(child);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return {tocItems};
|
|
107
|
+
|
|
108
|
+
// Visit Markdown headings
|
|
109
|
+
function visitHeading(node: Heading) {
|
|
110
|
+
const value = toString(node);
|
|
111
|
+
// depth:1 headings are titles and not included in the TOC
|
|
112
|
+
if (!value || node.depth < 2) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
tocItems.push({
|
|
116
|
+
type: 'heading',
|
|
117
|
+
heading: node,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Visit JSX elements, such as <Partial/>
|
|
122
|
+
function visitJSXElement(node: MdxJsxFlowElement) {
|
|
123
|
+
const componentName = node.name;
|
|
124
|
+
if (!componentName) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const importDeclaration = markdownImports.get(componentName)?.declaration;
|
|
128
|
+
if (!importDeclaration) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const tocSliceImportName = createTocSliceImportName({
|
|
133
|
+
tocExportName,
|
|
134
|
+
componentName,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
tocItems.push({
|
|
138
|
+
type: 'slice',
|
|
139
|
+
importName: tocSliceImportName,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
addTocSliceImportIfNeeded({
|
|
143
|
+
importDeclaration,
|
|
144
|
+
tocExportName,
|
|
145
|
+
tocSliceImportName,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const plugin: Plugin<PluginOptions[], Root> = function plugin(
|
|
151
|
+
options = {},
|
|
152
|
+
): Transformer<Root> {
|
|
153
|
+
const tocExportName = options.name || 'toc';
|
|
154
|
+
|
|
155
|
+
return (root) => {
|
|
156
|
+
const {markdownImports, existingTocExport} = collectImportsExports({
|
|
157
|
+
root,
|
|
158
|
+
tocExportName,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// If user explicitly writes "export const toc" in his mdx file
|
|
162
|
+
// We keep it as is do not override their explicit toc structure
|
|
163
|
+
// See https://github.com/facebook/docusaurus/pull/7530#discussion_r1458087876
|
|
164
|
+
if (existingTocExport) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const {tocItems} = collectTOCItems({
|
|
169
|
+
root,
|
|
170
|
+
tocExportName,
|
|
171
|
+
markdownImports,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
root.children.push(
|
|
175
|
+
createTOCExportNodeAST({
|
|
176
|
+
tocExportName,
|
|
177
|
+
tocItems,
|
|
178
|
+
}),
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export default plugin;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {Heading} from 'mdast';
|
|
9
|
+
|
|
10
|
+
// Note: this type is exported from mdx-loader and used in theme
|
|
11
|
+
// Need to keep it retro compatible
|
|
12
|
+
export type TOCItem = {
|
|
13
|
+
readonly value: string;
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly level: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type TOCHeading = {
|
|
19
|
+
readonly type: 'heading';
|
|
20
|
+
readonly heading: Heading;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// A TOC slice represents a TOCItem[] imported from a partial
|
|
24
|
+
export type TOCSlice = {
|
|
25
|
+
readonly type: 'slice';
|
|
26
|
+
readonly importName: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type TOCItems = (TOCHeading | TOCSlice)[];
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {toString} from 'mdast-util-to-string';
|
|
9
|
+
import {valueToEstree} from 'estree-util-value-to-estree';
|
|
10
|
+
import escapeHtml from 'escape-html';
|
|
11
|
+
import type {Node, Parent} from 'unist';
|
|
12
|
+
import type {
|
|
13
|
+
MdxjsEsm,
|
|
14
|
+
MdxJsxAttribute,
|
|
15
|
+
MdxJsxTextElement,
|
|
16
|
+
} from 'mdast-util-mdx';
|
|
17
|
+
import type {TOCHeading, TOCItem, TOCItems, TOCSlice} from './types';
|
|
18
|
+
import type {
|
|
19
|
+
Program,
|
|
20
|
+
SpreadElement,
|
|
21
|
+
ImportDeclaration,
|
|
22
|
+
ImportSpecifier,
|
|
23
|
+
} from 'estree';
|
|
24
|
+
import type {Heading, PhrasingContent} from 'mdast';
|
|
25
|
+
|
|
26
|
+
export function getImportDeclarations(program: Program): ImportDeclaration[] {
|
|
27
|
+
return program.body.filter(
|
|
28
|
+
(item): item is ImportDeclaration => item.type === 'ImportDeclaration',
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isMarkdownImport(node: Node): node is ImportDeclaration {
|
|
33
|
+
if (node.type !== 'ImportDeclaration') {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const importPath = (node as ImportDeclaration).source.value;
|
|
37
|
+
return typeof importPath === 'string' && /\.mdx?$/.test(importPath);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function findDefaultImportName(
|
|
41
|
+
importDeclaration: ImportDeclaration,
|
|
42
|
+
): string | undefined {
|
|
43
|
+
return importDeclaration.specifiers.find(
|
|
44
|
+
(o: Node) => o.type === 'ImportDefaultSpecifier',
|
|
45
|
+
)?.local.name;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function findNamedImportSpecifier(
|
|
49
|
+
importDeclaration: ImportDeclaration,
|
|
50
|
+
localName: string,
|
|
51
|
+
): ImportSpecifier | undefined {
|
|
52
|
+
return importDeclaration?.specifiers.find(
|
|
53
|
+
(specifier): specifier is ImportSpecifier =>
|
|
54
|
+
specifier.type === 'ImportSpecifier' &&
|
|
55
|
+
specifier.local.name === localName,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Before: import Partial from "partial"
|
|
60
|
+
// After: import Partial, {toc as __tocPartial} from "partial"
|
|
61
|
+
export function addTocSliceImportIfNeeded({
|
|
62
|
+
importDeclaration,
|
|
63
|
+
tocExportName,
|
|
64
|
+
tocSliceImportName,
|
|
65
|
+
}: {
|
|
66
|
+
importDeclaration: ImportDeclaration;
|
|
67
|
+
tocExportName: string;
|
|
68
|
+
tocSliceImportName: string;
|
|
69
|
+
}): void {
|
|
70
|
+
// We only add the toc slice named import if it doesn't exist already
|
|
71
|
+
if (!findNamedImportSpecifier(importDeclaration, tocSliceImportName)) {
|
|
72
|
+
importDeclaration.specifiers.push({
|
|
73
|
+
type: 'ImportSpecifier',
|
|
74
|
+
imported: {type: 'Identifier', name: tocExportName},
|
|
75
|
+
local: {type: 'Identifier', name: tocSliceImportName},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function isNamedExport(
|
|
81
|
+
node: Node,
|
|
82
|
+
exportName: string,
|
|
83
|
+
): node is MdxjsEsm {
|
|
84
|
+
if (node.type !== 'mdxjsEsm') {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const program = (node as MdxjsEsm).data?.estree;
|
|
88
|
+
if (!program) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
if (program.body.length !== 1) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
const exportDeclaration = program.body[0]!;
|
|
95
|
+
if (exportDeclaration.type !== 'ExportNamedDeclaration') {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const variableDeclaration = exportDeclaration.declaration;
|
|
99
|
+
if (variableDeclaration?.type !== 'VariableDeclaration') {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const {id} = variableDeclaration.declarations[0]!;
|
|
103
|
+
if (id.type !== 'Identifier') {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return id.name === exportName;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function createTOCExportNodeAST({
|
|
111
|
+
tocExportName,
|
|
112
|
+
tocItems,
|
|
113
|
+
}: {
|
|
114
|
+
tocExportName: string;
|
|
115
|
+
tocItems: TOCItems;
|
|
116
|
+
}): MdxjsEsm {
|
|
117
|
+
function createTOCSliceAST(tocSlice: TOCSlice): SpreadElement {
|
|
118
|
+
return {
|
|
119
|
+
type: 'SpreadElement',
|
|
120
|
+
argument: {type: 'Identifier', name: tocSlice.importName},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function createTOCHeadingAST({heading}: TOCHeading) {
|
|
125
|
+
const value: TOCItem = {
|
|
126
|
+
value: toHeadingHTMLValue(heading),
|
|
127
|
+
id: heading.data!.id!,
|
|
128
|
+
level: heading.depth,
|
|
129
|
+
};
|
|
130
|
+
return valueToEstree(value);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function createTOCItemAST(tocItem: TOCItems[number]) {
|
|
134
|
+
switch (tocItem.type) {
|
|
135
|
+
case 'slice':
|
|
136
|
+
return createTOCSliceAST(tocItem);
|
|
137
|
+
case 'heading':
|
|
138
|
+
return createTOCHeadingAST(tocItem);
|
|
139
|
+
default: {
|
|
140
|
+
throw new Error(`unexpected toc item type`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
type: 'mdxjsEsm',
|
|
147
|
+
value: '', // See https://github.com/facebook/docusaurus/pull/9684#discussion_r1457595181
|
|
148
|
+
data: {
|
|
149
|
+
estree: {
|
|
150
|
+
type: 'Program',
|
|
151
|
+
body: [
|
|
152
|
+
{
|
|
153
|
+
type: 'ExportNamedDeclaration',
|
|
154
|
+
attributes: [],
|
|
155
|
+
declaration: {
|
|
156
|
+
type: 'VariableDeclaration',
|
|
157
|
+
declarations: [
|
|
158
|
+
{
|
|
159
|
+
type: 'VariableDeclarator',
|
|
160
|
+
id: {
|
|
161
|
+
type: 'Identifier',
|
|
162
|
+
name: tocExportName,
|
|
163
|
+
},
|
|
164
|
+
init: {
|
|
165
|
+
type: 'ArrayExpression',
|
|
166
|
+
elements: tocItems.map(createTOCItemAST),
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
kind: 'const',
|
|
171
|
+
},
|
|
172
|
+
specifiers: [],
|
|
173
|
+
source: null,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
sourceType: 'module',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function stringifyChildren(node: Parent): string {
|
|
183
|
+
return (node.children as PhrasingContent[])
|
|
184
|
+
.map(toHeadingHTMLValue)
|
|
185
|
+
.join('')
|
|
186
|
+
.trim();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// TODO This is really a workaround, and not super reliable
|
|
190
|
+
// For now we only support serializing tagName, className and content
|
|
191
|
+
// Can we implement the TOC with real JSX nodes instead of html strings later?
|
|
192
|
+
function mdxJsxTextElementToHtml(element: MdxJsxTextElement): string {
|
|
193
|
+
const tag = element.name;
|
|
194
|
+
|
|
195
|
+
// See https://github.com/facebook/docusaurus/issues/11003#issuecomment-2733925363
|
|
196
|
+
if (tag === 'img') {
|
|
197
|
+
return '';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const attributes = element.attributes.filter(
|
|
201
|
+
(child): child is MdxJsxAttribute => child.type === 'mdxJsxAttribute',
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
const classAttribute =
|
|
205
|
+
attributes.find((attr) => attr.name === 'className') ??
|
|
206
|
+
attributes.find((attr) => attr.name === 'class');
|
|
207
|
+
|
|
208
|
+
const classAttributeString = classAttribute
|
|
209
|
+
? `class="${escapeHtml(String(classAttribute.value))}"`
|
|
210
|
+
: ``;
|
|
211
|
+
|
|
212
|
+
const allAttributes = classAttributeString ? ` ${classAttributeString}` : '';
|
|
213
|
+
|
|
214
|
+
const content = stringifyChildren(element);
|
|
215
|
+
|
|
216
|
+
return `<${tag}${allAttributes}>${content}</${tag}>`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function toHeadingHTMLValue(
|
|
220
|
+
node: PhrasingContent | Heading | MdxJsxTextElement,
|
|
221
|
+
): string {
|
|
222
|
+
switch (node.type) {
|
|
223
|
+
case 'mdxJsxTextElement': {
|
|
224
|
+
return mdxJsxTextElementToHtml(node as MdxJsxTextElement);
|
|
225
|
+
}
|
|
226
|
+
case 'text':
|
|
227
|
+
return escapeHtml(node.value);
|
|
228
|
+
case 'heading':
|
|
229
|
+
return stringifyChildren(node);
|
|
230
|
+
case 'inlineCode':
|
|
231
|
+
return `<code>${escapeHtml(node.value)}</code>`;
|
|
232
|
+
case 'emphasis':
|
|
233
|
+
return `<em>${stringifyChildren(node)}</em>`;
|
|
234
|
+
case 'strong':
|
|
235
|
+
return `<strong>${stringifyChildren(node)}</strong>`;
|
|
236
|
+
case 'delete':
|
|
237
|
+
return `<del>${stringifyChildren(node)}</del>`;
|
|
238
|
+
case 'link':
|
|
239
|
+
return stringifyChildren(node);
|
|
240
|
+
default:
|
|
241
|
+
return toString(node);
|
|
242
|
+
}
|
|
243
|
+
}
|