@docusaurus/mdx-loader 3.1.1 → 3.2.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/lib/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { mdxLoader } from './loader';
8
- import type { TOCItem as TOCItemImported } from './remark/toc';
8
+ import type { TOCItem as TOCItemImported } from './remark/toc/types';
9
9
  export default mdxLoader;
10
10
  export type TOCItem = TOCItemImported;
11
11
  export type Format = 'md' | 'mdx';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AAEnC,OAAO,KAAK,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,cAAc,CAAC;AAE7D,eAAe,SAAS,CAAC;AAEzB,MAAM,MAAM,OAAO,GAAG,eAAe,CAAC;AAEtC,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,gBAAgB,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,IAAI;IACxE,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,sCAAsC;IACtC,QAAQ,CAAC,GAAG,EAAE,SAAS,OAAO,EAAE,CAAC;IACjC,yCAAyC;IACzC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,IAAI,GAAG,CAAC,OAAO,CAAC;CACjB,CAAC;AAEF,YAAY,EAAC,OAAO,EAAE,SAAS,EAAC,MAAM,UAAU,CAAC;AACjD,YAAY,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AAEnC,OAAO,KAAK,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAEnE,eAAe,SAAS,CAAC;AAEzB,MAAM,MAAM,OAAO,GAAG,eAAe,CAAC;AAEtC,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,gBAAgB,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,IAAI;IACxE,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,sCAAsC;IACtC,QAAQ,CAAC,GAAG,EAAE,SAAS,OAAO,EAAE,CAAC;IACjC,yCAAyC;IACzC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,IAAI,GAAG,CAAC,OAAO,CAAC;CACjB,CAAC;AAEF,YAAY,EAAC,OAAO,EAAE,SAAS,EAAC,MAAM,UAAU,CAAC;AACjD,YAAY,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/remark/contentTitle/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,KAAK,MAAM,GAAG,GAAG,CAAC;AAMlB;;;;GAIG;AACH,QAAA,MAAM,MAAM,EAAE,MA0Bb,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/remark/contentTitle/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,KAAK,MAAM,GAAG,GAAG,CAAC;AAMlB;;;;GAIG;AACH,QAAA,MAAM,MAAM,EAAE,MAiCb,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -17,17 +17,24 @@ const plugin = function plugin(options = {}) {
17
17
  return async (root, vfile) => {
18
18
  const { toString } = await import('mdast-util-to-string');
19
19
  const { visit, EXIT } = await import('unist-util-visit');
20
- visit(root, 'heading', (headingNode, index, parent) => {
21
- if (headingNode.depth === 1) {
22
- vfile.data.contentTitle = toString(headingNode);
23
- if (removeContentTitle) {
24
- // @ts-expect-error: TODO how to fix?
25
- parent.children.splice(index, 1);
20
+ visit(root, ['heading', 'thematicBreak'], (node, index, parent) => {
21
+ if (node.type === 'heading') {
22
+ const headingNode = node;
23
+ if (headingNode.depth === 1) {
24
+ vfile.data.contentTitle = toString(headingNode);
25
+ if (removeContentTitle) {
26
+ // @ts-expect-error: TODO how to fix?
27
+ parent.children.splice(index, 1);
28
+ }
29
+ return EXIT; // We only handle the very first heading
30
+ }
31
+ // We only handle contentTitle if it's the very first heading found
32
+ if (headingNode.depth >= 1) {
33
+ return EXIT;
26
34
  }
27
- return EXIT; // We only handle the very first heading
28
35
  }
29
- // We only handle contentTitle if it's the very first heading found
30
- if (headingNode.depth >= 1) {
36
+ // We only handle contentTitle when it's above the first thematic break
37
+ if (node.type === 'thematicBreak') {
31
38
  return EXIT;
32
39
  }
33
40
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/remark/contentTitle/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAgBH;;;;GAIG;AACH,MAAM,MAAM,GAAW,SAAS,MAAM,CACpC,UAAyB,EAAE;IAE3B,mBAAmB;IACnB,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,KAAK,CAAC;IAE/D,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,EAAC,QAAQ,EAAC,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACxD,MAAM,EAAC,KAAK,EAAE,IAAI,EAAC,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAEvD,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,WAAoB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC7D,IAAI,WAAW,CAAC,KAAK,KAAK,CAAC,EAAE;gBAC3B,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAChD,IAAI,kBAAkB,EAAE;oBACtB,qCAAqC;oBACrC,MAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;iBACnC;gBACD,OAAO,IAAI,CAAC,CAAC,wCAAwC;aACtD;YACD,mEAAmE;YACnE,IAAI,WAAW,CAAC,KAAK,IAAI,CAAC,EAAE;gBAC1B,OAAO,IAAI,CAAC;aACb;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/remark/contentTitle/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAgBH;;;;GAIG;AACH,MAAM,MAAM,GAAW,SAAS,MAAM,CACpC,UAAyB,EAAE;IAE3B,mBAAmB;IACnB,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,KAAK,CAAC;IAE/D,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,EAAC,QAAQ,EAAC,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACxD,MAAM,EAAC,KAAK,EAAE,IAAI,EAAC,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAEvD,KAAK,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAChE,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;gBAC3B,MAAM,WAAW,GAAG,IAAe,CAAC;gBACpC,IAAI,WAAW,CAAC,KAAK,KAAK,CAAC,EAAE;oBAC3B,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;oBAChD,IAAI,kBAAkB,EAAE;wBACtB,qCAAqC;wBACrC,MAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;qBACnC;oBACD,OAAO,IAAI,CAAC,CAAC,wCAAwC;iBACtD;gBACD,mEAAmE;gBACnE,IAAI,WAAW,CAAC,KAAK,IAAI,CAAC,EAAE;oBAC1B,OAAO,IAAI,CAAC;iBACb;aACF;YACD,uEAAuE;YACvE,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE;gBACjC,OAAO,IAAI,CAAC;aACb;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,MAAM,CAAC"}
@@ -4,12 +4,11 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- type Plugin = any;
8
- export type TOCItem = {
9
- readonly value: string;
10
- readonly id: string;
11
- readonly level: number;
12
- };
13
- declare const plugin: Plugin;
14
- export default plugin;
7
+ import type { Root } from 'mdast';
8
+ import type { Transformer } from 'unified';
9
+ interface PluginOptions {
10
+ name?: string;
11
+ }
12
+ export default function plugin(options?: PluginOptions): Transformer<Root>;
13
+ export {};
15
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/remark/toc/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,KAAK,MAAM,GAAG,GAAG,CAAC;AAElB,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAuDF,QAAA,MAAM,MAAM,EAAE,MAiCb,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/remark/toc/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EAAU,IAAI,EAAC,MAAM,OAAO,CAAC;AAEzC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AASzC,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAiID,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,WAAW,CAAC,IAAI,CAAC,CA6B7E"}
@@ -6,106 +6,111 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- const tslib_1 = require("tslib");
10
- const parser_1 = require("@babel/parser");
11
- const traverse_1 = tslib_1.__importDefault(require("@babel/traverse"));
12
- const stringify_object_1 = tslib_1.__importDefault(require("stringify-object"));
13
- const utils_1 = require("../utils");
14
- const parseOptions = {
15
- plugins: ['jsx'],
16
- sourceType: 'module',
17
- };
18
- const isImport = (child) => child.type === 'mdxjsEsm' && child.value.startsWith('import');
19
- const hasImports = (index) => index > -1;
20
- const isExport = (child) => child.type === 'mdxjsEsm' && child.value.startsWith('export');
21
- const isTarget = (child, name) => {
22
- let found = false;
23
- const ast = (0, parser_1.parse)(child.value, parseOptions);
24
- (0, traverse_1.default)(ast, {
25
- VariableDeclarator: (path) => {
26
- if (path.node.id.name === name) {
27
- found = true;
9
+ const utils_1 = require("./utils");
10
+ function createTocSliceImportName({ tocExportName, componentName, }) {
11
+ // The name of the toc slice import alias doesn't matter much
12
+ // We just need to ensure it's valid and won't conflict with other names
13
+ return `__${tocExportName}${componentName}`;
14
+ }
15
+ async function collectImportsExports({ root, tocExportName, }) {
16
+ const { visit } = await import('unist-util-visit');
17
+ const markdownImports = new Map();
18
+ let existingTocExport = null;
19
+ visit(root, 'mdxjsEsm', (node) => {
20
+ if (!node.data?.estree) {
21
+ return;
22
+ }
23
+ if ((0, utils_1.isNamedExport)(node, tocExportName)) {
24
+ existingTocExport = node;
25
+ }
26
+ (0, utils_1.getImportDeclarations)(node.data.estree).forEach((declaration) => {
27
+ if (!(0, utils_1.isMarkdownImport)(declaration)) {
28
+ return;
28
29
  }
29
- },
30
+ const componentName = (0, utils_1.findDefaultImportName)(declaration);
31
+ if (!componentName) {
32
+ return;
33
+ }
34
+ markdownImports.set(componentName, {
35
+ declaration,
36
+ });
37
+ });
30
38
  });
31
- return found;
32
- };
33
- const getOrCreateExistingTargetIndex = async (children, name) => {
34
- let importsIndex = -1;
35
- let targetIndex = -1;
36
- children.forEach((child, index) => {
37
- if (isImport(child)) {
38
- importsIndex = index;
39
+ return { markdownImports, existingTocExport };
40
+ }
41
+ async function collectTOCItems({ root, tocExportName, markdownImports, }) {
42
+ const { toString } = await import('mdast-util-to-string');
43
+ const { visit } = await import('unist-util-visit');
44
+ const tocItems = [];
45
+ visit(root, (child) => {
46
+ if (child.type === 'heading') {
47
+ visitHeading(child);
39
48
  }
40
- else if (isExport(child) && isTarget(child, name)) {
41
- targetIndex = index;
49
+ else if (child.type === 'mdxJsxFlowElement') {
50
+ visitJSXElement(child);
42
51
  }
43
52
  });
44
- if (targetIndex === -1) {
45
- const target = await createExportNode(name, []);
46
- targetIndex = hasImports(importsIndex) ? importsIndex + 1 : 0;
47
- children.splice(targetIndex, 0, target);
53
+ return { tocItems };
54
+ // Visit Markdown headings
55
+ function visitHeading(node) {
56
+ const value = toString(node);
57
+ // depth:1 headings are titles and not included in the TOC
58
+ if (!value || node.depth < 2) {
59
+ return;
60
+ }
61
+ tocItems.push({
62
+ type: 'heading',
63
+ heading: node,
64
+ });
48
65
  }
49
- return targetIndex;
50
- };
51
- const plugin = function plugin(options = {}) {
52
- const name = options.name || 'toc';
66
+ // Visit JSX elements, such as <Partial/>
67
+ function visitJSXElement(node) {
68
+ const componentName = node.name;
69
+ if (!componentName) {
70
+ return;
71
+ }
72
+ const importDeclaration = markdownImports.get(componentName)?.declaration;
73
+ if (!importDeclaration) {
74
+ return;
75
+ }
76
+ const tocSliceImportName = createTocSliceImportName({
77
+ tocExportName,
78
+ componentName,
79
+ });
80
+ tocItems.push({
81
+ type: 'slice',
82
+ importName: tocSliceImportName,
83
+ });
84
+ (0, utils_1.addTocSliceImportIfNeeded)({
85
+ importDeclaration,
86
+ tocExportName,
87
+ tocSliceImportName,
88
+ });
89
+ }
90
+ }
91
+ function plugin(options = {}) {
92
+ const tocExportName = options.name || 'toc';
53
93
  return async (root) => {
54
- const { toString } = await import('mdast-util-to-string');
55
- const { visit } = await import('unist-util-visit');
56
- const headings = [];
57
- visit(root, 'heading', (child) => {
58
- const value = toString(child);
59
- // depth:1 headings are titles and not included in the TOC
60
- if (!value || child.depth < 2) {
61
- return;
62
- }
63
- headings.push({
64
- value: (0, utils_1.toValue)(child, toString),
65
- id: child.data.id,
66
- level: child.depth,
67
- });
94
+ const { markdownImports, existingTocExport } = await collectImportsExports({
95
+ root,
96
+ tocExportName,
68
97
  });
69
- const { children } = root;
70
- const targetIndex = await getOrCreateExistingTargetIndex(children, name);
71
- if (headings?.length) {
72
- children[targetIndex] = await createExportNode(name, headings);
98
+ // If user explicitly writes "export const toc" in his mdx file
99
+ // We keep it as is do not override their explicit toc structure
100
+ // See https://github.com/facebook/docusaurus/pull/7530#discussion_r1458087876
101
+ if (existingTocExport) {
102
+ return;
73
103
  }
74
- };
75
- };
76
- exports.default = plugin;
77
- async function createExportNode(name, object) {
78
- const { valueToEstree } = await import('estree-util-value-to-estree');
79
- return {
80
- type: 'mdxjsEsm',
81
- value: `export const ${name} = ${(0, stringify_object_1.default)(object)}`,
82
- data: {
83
- estree: {
84
- type: 'Program',
85
- body: [
86
- {
87
- type: 'ExportNamedDeclaration',
88
- declaration: {
89
- type: 'VariableDeclaration',
90
- declarations: [
91
- {
92
- type: 'VariableDeclarator',
93
- id: {
94
- type: 'Identifier',
95
- name,
96
- },
97
- init: valueToEstree(object),
98
- },
99
- ],
100
- kind: 'const',
101
- },
102
- specifiers: [],
103
- source: null,
104
- },
105
- ],
106
- sourceType: 'module',
107
- },
108
- },
104
+ const { tocItems } = await collectTOCItems({
105
+ root,
106
+ tocExportName,
107
+ markdownImports,
108
+ });
109
+ root.children.push(await (0, utils_1.createTOCExportNodeAST)({
110
+ tocExportName,
111
+ tocItems,
112
+ }));
109
113
  };
110
114
  }
115
+ exports.default = plugin;
111
116
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/remark/toc/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/remark/toc/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
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
+ import type { Heading } from 'mdast';
8
+ export type TOCItem = {
9
+ readonly value: string;
10
+ readonly id: string;
11
+ readonly level: number;
12
+ };
13
+ export type TOCHeading = {
14
+ readonly type: 'heading';
15
+ readonly heading: Heading;
16
+ };
17
+ export type TOCSlice = {
18
+ readonly type: 'slice';
19
+ readonly importName: string;
20
+ };
21
+ export type TOCItems = (TOCHeading | TOCSlice)[];
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/remark/toc/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAInC,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAGF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/remark/toc/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
@@ -0,0 +1,25 @@
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
+ import type { Node } from 'unist';
8
+ import type { MdxjsEsm } from 'mdast-util-mdx';
9
+ import type { TOCItems } from './types';
10
+ import type { Program, ImportDeclaration, ImportSpecifier } from 'estree';
11
+ export declare function getImportDeclarations(program: Program): ImportDeclaration[];
12
+ export declare function isMarkdownImport(node: Node): node is ImportDeclaration;
13
+ export declare function findDefaultImportName(importDeclaration: ImportDeclaration): string | undefined;
14
+ export declare function findNamedImportSpecifier(importDeclaration: ImportDeclaration, localName: string): ImportSpecifier | undefined;
15
+ export declare function addTocSliceImportIfNeeded({ importDeclaration, tocExportName, tocSliceImportName, }: {
16
+ importDeclaration: ImportDeclaration;
17
+ tocExportName: string;
18
+ tocSliceImportName: string;
19
+ }): void;
20
+ export declare function isNamedExport(node: Node, exportName: string): node is MdxjsEsm;
21
+ export declare function createTOCExportNodeAST({ tocExportName, tocItems, }: {
22
+ tocExportName: string;
23
+ tocItems: TOCItems;
24
+ }): Promise<MdxjsEsm>;
25
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/remark/toc/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EACV,QAAQ,EAET,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAsB,QAAQ,EAAW,MAAM,SAAS,CAAC;AACrE,OAAO,KAAK,EACV,OAAO,EAEP,iBAAiB,EACjB,eAAe,EAChB,MAAM,QAAQ,CAAC;AAEhB,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,EAAE,CAI3E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,iBAAiB,CAMtE;AAED,wBAAgB,qBAAqB,CACnC,iBAAiB,EAAE,iBAAiB,GACnC,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,wBAAwB,CACtC,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,MAAM,GAChB,eAAe,GAAG,SAAS,CAM7B;AAID,wBAAgB,yBAAyB,CAAC,EACxC,iBAAiB,EACjB,aAAa,EACb,kBAAkB,GACnB,EAAE;IACD,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GAAG,IAAI,CASP;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,GACjB,IAAI,IAAI,QAAQ,CAyBlB;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,aAAa,EACb,QAAQ,GACT,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,QAAQ,CAAC;CACpB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAiEpB"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createTOCExportNodeAST = exports.isNamedExport = exports.addTocSliceImportIfNeeded = exports.findNamedImportSpecifier = exports.findDefaultImportName = exports.isMarkdownImport = exports.getImportDeclarations = void 0;
10
+ const utils_1 = require("../utils");
11
+ function getImportDeclarations(program) {
12
+ return program.body.filter((item) => item.type === 'ImportDeclaration');
13
+ }
14
+ exports.getImportDeclarations = getImportDeclarations;
15
+ function isMarkdownImport(node) {
16
+ if (node.type !== 'ImportDeclaration') {
17
+ return false;
18
+ }
19
+ const importPath = node.source.value;
20
+ return typeof importPath === 'string' && /\.mdx?$/.test(importPath);
21
+ }
22
+ exports.isMarkdownImport = isMarkdownImport;
23
+ function findDefaultImportName(importDeclaration) {
24
+ return importDeclaration.specifiers.find((o) => o.type === 'ImportDefaultSpecifier')?.local.name;
25
+ }
26
+ exports.findDefaultImportName = findDefaultImportName;
27
+ function findNamedImportSpecifier(importDeclaration, localName) {
28
+ return importDeclaration?.specifiers.find((specifier) => specifier.type === 'ImportSpecifier' &&
29
+ specifier.local.name === localName);
30
+ }
31
+ exports.findNamedImportSpecifier = findNamedImportSpecifier;
32
+ // Before: import Partial from "partial"
33
+ // After: import Partial, {toc as __tocPartial} from "partial"
34
+ function addTocSliceImportIfNeeded({ importDeclaration, tocExportName, tocSliceImportName, }) {
35
+ // We only add the toc slice named import if it doesn't exist already
36
+ if (!findNamedImportSpecifier(importDeclaration, tocSliceImportName)) {
37
+ importDeclaration.specifiers.push({
38
+ type: 'ImportSpecifier',
39
+ imported: { type: 'Identifier', name: tocExportName },
40
+ local: { type: 'Identifier', name: tocSliceImportName },
41
+ });
42
+ }
43
+ }
44
+ exports.addTocSliceImportIfNeeded = addTocSliceImportIfNeeded;
45
+ function isNamedExport(node, exportName) {
46
+ if (node.type !== 'mdxjsEsm') {
47
+ return false;
48
+ }
49
+ const program = node.data?.estree;
50
+ if (!program) {
51
+ return false;
52
+ }
53
+ if (program.body.length !== 1) {
54
+ return false;
55
+ }
56
+ const exportDeclaration = program.body[0];
57
+ if (exportDeclaration.type !== 'ExportNamedDeclaration') {
58
+ return false;
59
+ }
60
+ const variableDeclaration = exportDeclaration.declaration;
61
+ if (variableDeclaration?.type !== 'VariableDeclaration') {
62
+ return false;
63
+ }
64
+ const { id } = variableDeclaration.declarations[0];
65
+ if (id.type !== 'Identifier') {
66
+ return false;
67
+ }
68
+ return id.name === exportName;
69
+ }
70
+ exports.isNamedExport = isNamedExport;
71
+ async function createTOCExportNodeAST({ tocExportName, tocItems, }) {
72
+ function createTOCSliceAST(tocSlice) {
73
+ return {
74
+ type: 'SpreadElement',
75
+ argument: { type: 'Identifier', name: tocSlice.importName },
76
+ };
77
+ }
78
+ async function createTOCHeadingAST({ heading }) {
79
+ const { toString } = await import('mdast-util-to-string');
80
+ const { valueToEstree } = await import('estree-util-value-to-estree');
81
+ const value = {
82
+ value: (0, utils_1.toValue)(heading, toString),
83
+ id: heading.data.id,
84
+ level: heading.depth,
85
+ };
86
+ return valueToEstree(value);
87
+ }
88
+ async function createTOCItemAST(tocItem) {
89
+ switch (tocItem.type) {
90
+ case 'slice':
91
+ return createTOCSliceAST(tocItem);
92
+ case 'heading':
93
+ return createTOCHeadingAST(tocItem);
94
+ default: {
95
+ throw new Error(`unexpected toc item type`);
96
+ }
97
+ }
98
+ }
99
+ return {
100
+ type: 'mdxjsEsm',
101
+ value: '',
102
+ data: {
103
+ estree: {
104
+ type: 'Program',
105
+ body: [
106
+ {
107
+ type: 'ExportNamedDeclaration',
108
+ declaration: {
109
+ type: 'VariableDeclaration',
110
+ declarations: [
111
+ {
112
+ type: 'VariableDeclarator',
113
+ id: {
114
+ type: 'Identifier',
115
+ name: tocExportName,
116
+ },
117
+ init: {
118
+ type: 'ArrayExpression',
119
+ elements: await Promise.all(tocItems.map(createTOCItemAST)),
120
+ },
121
+ },
122
+ ],
123
+ kind: 'const',
124
+ },
125
+ specifiers: [],
126
+ source: null,
127
+ },
128
+ ],
129
+ sourceType: 'module',
130
+ },
131
+ },
132
+ };
133
+ }
134
+ exports.createTOCExportNodeAST = createTOCExportNodeAST;
135
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/remark/toc/utils.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,oCAAiC;AAcjC,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CACxB,CAAC,IAAI,EAA6B,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,mBAAmB,CACvE,CAAC;AACJ,CAAC;AAJD,sDAIC;AAED,SAAgB,gBAAgB,CAAC,IAAU;IACzC,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE;QACrC,OAAO,KAAK,CAAC;KACd;IACD,MAAM,UAAU,GAAI,IAA0B,CAAC,MAAM,CAAC,KAAK,CAAC;IAC5D,OAAO,OAAO,UAAU,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtE,CAAC;AAND,4CAMC;AAED,SAAgB,qBAAqB,CACnC,iBAAoC;IAEpC,OAAO,iBAAiB,CAAC,UAAU,CAAC,IAAI,CACtC,CAAC,CAAO,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAwB,CACjD,EAAE,KAAK,CAAC,IAAI,CAAC;AAChB,CAAC;AAND,sDAMC;AAED,SAAgB,wBAAwB,CACtC,iBAAoC,EACpC,SAAiB;IAEjB,OAAO,iBAAiB,EAAE,UAAU,CAAC,IAAI,CACvC,CAAC,SAAS,EAAgC,EAAE,CAC1C,SAAS,CAAC,IAAI,KAAK,iBAAiB;QACpC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CACrC,CAAC;AACJ,CAAC;AATD,4DASC;AAED,wCAAwC;AACxC,8DAA8D;AAC9D,SAAgB,yBAAyB,CAAC,EACxC,iBAAiB,EACjB,aAAa,EACb,kBAAkB,GAKnB;IACC,qEAAqE;IACrE,IAAI,CAAC,wBAAwB,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,EAAE;QACpE,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC;YAChC,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,EAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAC;YACnD,KAAK,EAAE,EAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,kBAAkB,EAAC;SACtD,CAAC,CAAC;KACJ;AACH,CAAC;AAjBD,8DAiBC;AAED,SAAgB,aAAa,CAC3B,IAAU,EACV,UAAkB;IAElB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE;QAC5B,OAAO,KAAK,CAAC;KACd;IACD,MAAM,OAAO,GAAI,IAAiB,CAAC,IAAI,EAAE,MAAM,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,KAAK,CAAC;KACd;IACD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QAC7B,OAAO,KAAK,CAAC;KACd;IACD,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;IAC3C,IAAI,iBAAiB,CAAC,IAAI,KAAK,wBAAwB,EAAE;QACvD,OAAO,KAAK,CAAC;KACd;IACD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,WAAW,CAAC;IAC1D,IAAI,mBAAmB,EAAE,IAAI,KAAK,qBAAqB,EAAE;QACvD,OAAO,KAAK,CAAC;KACd;IACD,MAAM,EAAC,EAAE,EAAC,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC,CAAE,CAAC;IAClD,IAAI,EAAE,CAAC,IAAI,KAAK,YAAY,EAAE;QAC5B,OAAO,KAAK,CAAC;KACd;IAED,OAAO,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC;AAChC,CAAC;AA5BD,sCA4BC;AAEM,KAAK,UAAU,sBAAsB,CAAC,EAC3C,aAAa,EACb,QAAQ,GAIT;IACC,SAAS,iBAAiB,CAAC,QAAkB;QAC3C,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,EAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAC;SAC1D,CAAC;IACJ,CAAC;IAED,KAAK,UAAU,mBAAmB,CAAC,EAAC,OAAO,EAAa;QACtD,MAAM,EAAC,QAAQ,EAAC,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACxD,MAAM,EAAC,aAAa,EAAC,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QACpE,MAAM,KAAK,GAAY;YACrB,KAAK,EAAE,IAAA,eAAO,EAAC,OAAO,EAAE,QAAQ,CAAC;YACjC,EAAE,EAAE,OAAO,CAAC,IAAK,CAAC,EAAG;YACrB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC;QACF,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,UAAU,gBAAgB,CAAC,OAAyB;QACvD,QAAQ,OAAO,CAAC,IAAI,EAAE;YACpB,KAAK,OAAO;gBACV,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAC;YACpC,KAAK,SAAS;gBACZ,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;YACtC,OAAO,CAAC,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;aAC7C;SACF;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,EAAE;QACT,IAAI,EAAE;YACJ,MAAM,EAAE;gBACN,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE;oBACJ;wBACE,IAAI,EAAE,wBAAwB;wBAC9B,WAAW,EAAE;4BACX,IAAI,EAAE,qBAAqB;4BAC3B,YAAY,EAAE;gCACZ;oCACE,IAAI,EAAE,oBAAoB;oCAC1B,EAAE,EAAE;wCACF,IAAI,EAAE,YAAY;wCAClB,IAAI,EAAE,aAAa;qCACpB;oCACD,IAAI,EAAE;wCACJ,IAAI,EAAE,iBAAiB;wCACvB,QAAQ,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;qCAC5D;iCACF;6BACF;4BACD,IAAI,EAAE,OAAO;yBACd;wBACD,UAAU,EAAE,EAAE;wBACd,MAAM,EAAE,IAAI;qBACb;iBACF;gBACD,UAAU,EAAE,QAAQ;aACrB;SACF;KACF,CAAC;AACJ,CAAC;AAvED,wDAuEC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/mdx-loader",
3
- "version": "3.1.1",
3
+ "version": "3.2.1",
4
4
  "description": "Docusaurus Loader for MDX",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -18,11 +18,9 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
- "@babel/parser": "^7.22.7",
22
- "@babel/traverse": "^7.22.8",
23
- "@docusaurus/logger": "3.1.1",
24
- "@docusaurus/utils": "3.1.1",
25
- "@docusaurus/utils-validation": "3.1.1",
21
+ "@docusaurus/logger": "3.2.1",
22
+ "@docusaurus/utils": "3.2.1",
23
+ "@docusaurus/utils-validation": "3.2.1",
26
24
  "@mdx-js/mdx": "^3.0.0",
27
25
  "@slorber/remark-comment": "^1.0.0",
28
26
  "escape-html": "^1.0.3",
@@ -46,7 +44,7 @@
46
44
  "webpack": "^5.88.1"
47
45
  },
48
46
  "devDependencies": {
49
- "@docusaurus/types": "3.1.1",
47
+ "@docusaurus/types": "3.2.1",
50
48
  "@types/escape-html": "^1.0.2",
51
49
  "@types/mdast": "^4.0.2",
52
50
  "@types/stringify-object": "^3.3.1",
@@ -66,5 +64,5 @@
66
64
  "engines": {
67
65
  "node": ">=18.0"
68
66
  },
69
- "gitHead": "8017f6a6776ba1bd7065e630a52fe2c2654e2f1b"
67
+ "gitHead": "f268e15264e208e6faf26117258162e988b53773"
70
68
  }
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  import {mdxLoader} from './loader';
9
9
 
10
- import type {TOCItem as TOCItemImported} from './remark/toc';
10
+ import type {TOCItem as TOCItemImported} from './remark/toc/types';
11
11
 
12
12
  export default mdxLoader;
13
13
 
@@ -34,17 +34,24 @@ const plugin: Plugin = function plugin(
34
34
  const {toString} = await import('mdast-util-to-string');
35
35
  const {visit, EXIT} = await import('unist-util-visit');
36
36
 
37
- visit(root, 'heading', (headingNode: Heading, index, parent) => {
38
- if (headingNode.depth === 1) {
39
- vfile.data.contentTitle = toString(headingNode);
40
- if (removeContentTitle) {
41
- // @ts-expect-error: TODO how to fix?
42
- parent!.children.splice(index, 1);
37
+ visit(root, ['heading', 'thematicBreak'], (node, index, parent) => {
38
+ if (node.type === 'heading') {
39
+ const headingNode = node as Heading;
40
+ if (headingNode.depth === 1) {
41
+ vfile.data.contentTitle = toString(headingNode);
42
+ if (removeContentTitle) {
43
+ // @ts-expect-error: TODO how to fix?
44
+ parent!.children.splice(index, 1);
45
+ }
46
+ return EXIT; // We only handle the very first heading
47
+ }
48
+ // We only handle contentTitle if it's the very first heading found
49
+ if (headingNode.depth >= 1) {
50
+ return EXIT;
43
51
  }
44
- return EXIT; // We only handle the very first heading
45
52
  }
46
- // We only handle contentTitle if it's the very first heading found
47
- if (headingNode.depth >= 1) {
53
+ // We only handle contentTitle when it's above the first thematic break
54
+ if (node.type === 'thematicBreak') {
48
55
  return EXIT;
49
56
  }
50
57
  return undefined;
@@ -5,154 +5,183 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {parse, type ParserOptions} from '@babel/parser';
9
- import traverse from '@babel/traverse';
10
- import stringifyObject from 'stringify-object';
11
- import {toValue} from '../utils';
12
- import type {Identifier} from '@babel/types';
13
- import type {Node, Parent} from 'unist';
14
- import type {Heading, Literal} from 'mdast';
8
+ import {
9
+ addTocSliceImportIfNeeded,
10
+ createTOCExportNodeAST,
11
+ findDefaultImportName,
12
+ getImportDeclarations,
13
+ isMarkdownImport,
14
+ isNamedExport,
15
+ } from './utils';
16
+ import type {Heading, Root} from 'mdast';
15
17
  // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
16
18
  import type {Transformer} from 'unified';
17
19
  import type {
18
20
  MdxjsEsm,
21
+ MdxJsxFlowElement,
19
22
  // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
20
23
  } from 'mdast-util-mdx';
21
-
22
- // TODO as of April 2023, no way to import/re-export this ESM type easily :/
23
- // TODO upgrade to TS 5.3
24
- // See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
25
- // import type {Plugin} from 'unified';
26
- type Plugin = any; // TODO fix this asap
27
-
28
- export type TOCItem = {
29
- readonly value: string;
30
- readonly id: string;
31
- readonly level: number;
32
- };
33
-
34
- const parseOptions: ParserOptions = {
35
- plugins: ['jsx'],
36
- sourceType: 'module',
37
- };
38
-
39
- const isImport = (child: any): child is Literal =>
40
- child.type === 'mdxjsEsm' && child.value.startsWith('import');
41
- const hasImports = (index: number) => index > -1;
42
- const isExport = (child: any): child is Literal =>
43
- child.type === 'mdxjsEsm' && child.value.startsWith('export');
24
+ import type {TOCItems} from './types';
25
+ import type {ImportDeclaration} from 'estree';
44
26
 
45
27
  interface PluginOptions {
46
28
  name?: string;
47
29
  }
48
30
 
49
- const isTarget = (child: Literal, name: string) => {
50
- let found = false;
51
- const ast = parse(child.value, parseOptions);
52
- traverse(ast, {
53
- VariableDeclarator: (path) => {
54
- if ((path.node.id as Identifier).name === name) {
55
- found = true;
31
+ // ComponentName (default export) => ImportDeclaration mapping
32
+ type MarkdownImports = Map<string, {declaration: ImportDeclaration}>;
33
+
34
+ // MdxjsEsm node representing an already existing "export const toc" declaration
35
+ type ExistingTOCExport = MdxjsEsm | null;
36
+
37
+ function createTocSliceImportName({
38
+ tocExportName,
39
+ componentName,
40
+ }: {
41
+ tocExportName: string;
42
+ componentName: string;
43
+ }) {
44
+ // The name of the toc slice import alias doesn't matter much
45
+ // We just need to ensure it's valid and won't conflict with other names
46
+ return `__${tocExportName}${componentName}`;
47
+ }
48
+
49
+ async function collectImportsExports({
50
+ root,
51
+ tocExportName,
52
+ }: {
53
+ root: Root;
54
+ tocExportName: string;
55
+ }): Promise<{
56
+ markdownImports: MarkdownImports;
57
+ existingTocExport: ExistingTOCExport;
58
+ }> {
59
+ const {visit} = await import('unist-util-visit');
60
+
61
+ const markdownImports = new Map<string, {declaration: ImportDeclaration}>();
62
+ let existingTocExport: MdxjsEsm | null = null;
63
+
64
+ visit(root, 'mdxjsEsm', (node) => {
65
+ if (!node.data?.estree) {
66
+ return;
67
+ }
68
+ if (isNamedExport(node, tocExportName)) {
69
+ existingTocExport = node;
70
+ }
71
+
72
+ getImportDeclarations(node.data.estree).forEach((declaration) => {
73
+ if (!isMarkdownImport(declaration)) {
74
+ return;
75
+ }
76
+ const componentName = findDefaultImportName(declaration);
77
+ if (!componentName) {
78
+ return;
56
79
  }
57
- },
80
+ markdownImports.set(componentName, {
81
+ declaration,
82
+ });
83
+ });
58
84
  });
59
- return found;
60
- };
61
-
62
- const getOrCreateExistingTargetIndex = async (
63
- children: Node[],
64
- name: string,
65
- ) => {
66
- let importsIndex = -1;
67
- let targetIndex = -1;
68
-
69
- children.forEach((child, index) => {
70
- if (isImport(child)) {
71
- importsIndex = index;
72
- } else if (isExport(child) && isTarget(child, name)) {
73
- targetIndex = index;
85
+
86
+ return {markdownImports, existingTocExport};
87
+ }
88
+
89
+ async function collectTOCItems({
90
+ root,
91
+ tocExportName,
92
+ markdownImports,
93
+ }: {
94
+ root: Root;
95
+ tocExportName: string;
96
+ markdownImports: MarkdownImports;
97
+ }): Promise<{
98
+ // The toc items we collected in the tree
99
+ tocItems: TOCItems;
100
+ }> {
101
+ const {toString} = await import('mdast-util-to-string');
102
+ const {visit} = await import('unist-util-visit');
103
+
104
+ const tocItems: TOCItems = [];
105
+
106
+ visit(root, (child) => {
107
+ if (child.type === 'heading') {
108
+ visitHeading(child);
109
+ } else if (child.type === 'mdxJsxFlowElement') {
110
+ visitJSXElement(child);
74
111
  }
75
112
  });
76
113
 
77
- if (targetIndex === -1) {
78
- const target = await createExportNode(name, []);
114
+ return {tocItems};
79
115
 
80
- targetIndex = hasImports(importsIndex) ? importsIndex + 1 : 0;
81
- children.splice(targetIndex, 0, target);
116
+ // Visit Markdown headings
117
+ function visitHeading(node: Heading) {
118
+ const value = toString(node);
119
+ // depth:1 headings are titles and not included in the TOC
120
+ if (!value || node.depth < 2) {
121
+ return;
122
+ }
123
+ tocItems.push({
124
+ type: 'heading',
125
+ heading: node,
126
+ });
82
127
  }
83
128
 
84
- return targetIndex;
85
- };
86
-
87
- const plugin: Plugin = function plugin(
88
- options: PluginOptions = {},
89
- ): Transformer {
90
- const name = options.name || 'toc';
129
+ // Visit JSX elements, such as <Partial/>
130
+ function visitJSXElement(node: MdxJsxFlowElement) {
131
+ const componentName = node.name;
132
+ if (!componentName) {
133
+ return;
134
+ }
135
+ const importDeclaration = markdownImports.get(componentName)?.declaration;
136
+ if (!importDeclaration) {
137
+ return;
138
+ }
91
139
 
92
- return async (root) => {
93
- const {toString} = await import('mdast-util-to-string');
94
- const {visit} = await import('unist-util-visit');
140
+ const tocSliceImportName = createTocSliceImportName({
141
+ tocExportName,
142
+ componentName,
143
+ });
95
144
 
96
- const headings: TOCItem[] = [];
145
+ tocItems.push({
146
+ type: 'slice',
147
+ importName: tocSliceImportName,
148
+ });
97
149
 
98
- visit(root, 'heading', (child: Heading) => {
99
- const value = toString(child);
150
+ addTocSliceImportIfNeeded({
151
+ importDeclaration,
152
+ tocExportName,
153
+ tocSliceImportName,
154
+ });
155
+ }
156
+ }
100
157
 
101
- // depth:1 headings are titles and not included in the TOC
102
- if (!value || child.depth < 2) {
103
- return;
104
- }
158
+ export default function plugin(options: PluginOptions = {}): Transformer<Root> {
159
+ const tocExportName = options.name || 'toc';
105
160
 
106
- headings.push({
107
- value: toValue(child, toString),
108
- id: child.data!.id!,
109
- level: child.depth,
110
- });
161
+ return async (root) => {
162
+ const {markdownImports, existingTocExport} = await collectImportsExports({
163
+ root,
164
+ tocExportName,
111
165
  });
112
166
 
113
- const {children} = root as Parent;
114
- const targetIndex = await getOrCreateExistingTargetIndex(children, name);
115
-
116
- if (headings?.length) {
117
- children[targetIndex] = await createExportNode(name, headings);
167
+ // If user explicitly writes "export const toc" in his mdx file
168
+ // We keep it as is do not override their explicit toc structure
169
+ // See https://github.com/facebook/docusaurus/pull/7530#discussion_r1458087876
170
+ if (existingTocExport) {
171
+ return;
118
172
  }
119
- };
120
- };
121
-
122
- export default plugin;
123
-
124
- async function createExportNode(name: string, object: any): Promise<MdxjsEsm> {
125
- const {valueToEstree} = await import('estree-util-value-to-estree');
126
-
127
- return {
128
- type: 'mdxjsEsm',
129
- value: `export const ${name} = ${stringifyObject(object)}`,
130
- data: {
131
- estree: {
132
- type: 'Program',
133
- body: [
134
- {
135
- type: 'ExportNamedDeclaration',
136
- declaration: {
137
- type: 'VariableDeclaration',
138
- declarations: [
139
- {
140
- type: 'VariableDeclarator',
141
- id: {
142
- type: 'Identifier',
143
- name,
144
- },
145
- init: valueToEstree(object),
146
- },
147
- ],
148
- kind: 'const',
149
- },
150
- specifiers: [],
151
- source: null,
152
- },
153
- ],
154
- sourceType: 'module',
155
- },
156
- },
173
+
174
+ const {tocItems} = await collectTOCItems({
175
+ root,
176
+ tocExportName,
177
+ markdownImports,
178
+ });
179
+
180
+ root.children.push(
181
+ await createTOCExportNodeAST({
182
+ tocExportName,
183
+ tocItems,
184
+ }),
185
+ );
157
186
  };
158
187
  }
@@ -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,177 @@
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 {toValue} from '../utils';
9
+ import type {Node} from 'unist';
10
+ import type {
11
+ MdxjsEsm,
12
+ // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
13
+ } from 'mdast-util-mdx';
14
+ import type {TOCHeading, TOCItem, TOCItems, TOCSlice} from './types';
15
+ import type {
16
+ Program,
17
+ SpreadElement,
18
+ ImportDeclaration,
19
+ ImportSpecifier,
20
+ } from 'estree';
21
+
22
+ export function getImportDeclarations(program: Program): ImportDeclaration[] {
23
+ return program.body.filter(
24
+ (item): item is ImportDeclaration => item.type === 'ImportDeclaration',
25
+ );
26
+ }
27
+
28
+ export function isMarkdownImport(node: Node): node is ImportDeclaration {
29
+ if (node.type !== 'ImportDeclaration') {
30
+ return false;
31
+ }
32
+ const importPath = (node as ImportDeclaration).source.value;
33
+ return typeof importPath === 'string' && /\.mdx?$/.test(importPath);
34
+ }
35
+
36
+ export function findDefaultImportName(
37
+ importDeclaration: ImportDeclaration,
38
+ ): string | undefined {
39
+ return importDeclaration.specifiers.find(
40
+ (o: Node) => o.type === 'ImportDefaultSpecifier',
41
+ )?.local.name;
42
+ }
43
+
44
+ export function findNamedImportSpecifier(
45
+ importDeclaration: ImportDeclaration,
46
+ localName: string,
47
+ ): ImportSpecifier | undefined {
48
+ return importDeclaration?.specifiers.find(
49
+ (specifier): specifier is ImportSpecifier =>
50
+ specifier.type === 'ImportSpecifier' &&
51
+ specifier.local.name === localName,
52
+ );
53
+ }
54
+
55
+ // Before: import Partial from "partial"
56
+ // After: import Partial, {toc as __tocPartial} from "partial"
57
+ export function addTocSliceImportIfNeeded({
58
+ importDeclaration,
59
+ tocExportName,
60
+ tocSliceImportName,
61
+ }: {
62
+ importDeclaration: ImportDeclaration;
63
+ tocExportName: string;
64
+ tocSliceImportName: string;
65
+ }): void {
66
+ // We only add the toc slice named import if it doesn't exist already
67
+ if (!findNamedImportSpecifier(importDeclaration, tocSliceImportName)) {
68
+ importDeclaration.specifiers.push({
69
+ type: 'ImportSpecifier',
70
+ imported: {type: 'Identifier', name: tocExportName},
71
+ local: {type: 'Identifier', name: tocSliceImportName},
72
+ });
73
+ }
74
+ }
75
+
76
+ export function isNamedExport(
77
+ node: Node,
78
+ exportName: string,
79
+ ): node is MdxjsEsm {
80
+ if (node.type !== 'mdxjsEsm') {
81
+ return false;
82
+ }
83
+ const program = (node as MdxjsEsm).data?.estree;
84
+ if (!program) {
85
+ return false;
86
+ }
87
+ if (program.body.length !== 1) {
88
+ return false;
89
+ }
90
+ const exportDeclaration = program.body[0]!;
91
+ if (exportDeclaration.type !== 'ExportNamedDeclaration') {
92
+ return false;
93
+ }
94
+ const variableDeclaration = exportDeclaration.declaration;
95
+ if (variableDeclaration?.type !== 'VariableDeclaration') {
96
+ return false;
97
+ }
98
+ const {id} = variableDeclaration.declarations[0]!;
99
+ if (id.type !== 'Identifier') {
100
+ return false;
101
+ }
102
+
103
+ return id.name === exportName;
104
+ }
105
+
106
+ export async function createTOCExportNodeAST({
107
+ tocExportName,
108
+ tocItems,
109
+ }: {
110
+ tocExportName: string;
111
+ tocItems: TOCItems;
112
+ }): Promise<MdxjsEsm> {
113
+ function createTOCSliceAST(tocSlice: TOCSlice): SpreadElement {
114
+ return {
115
+ type: 'SpreadElement',
116
+ argument: {type: 'Identifier', name: tocSlice.importName},
117
+ };
118
+ }
119
+
120
+ async function createTOCHeadingAST({heading}: TOCHeading) {
121
+ const {toString} = await import('mdast-util-to-string');
122
+ const {valueToEstree} = await import('estree-util-value-to-estree');
123
+ const value: TOCItem = {
124
+ value: toValue(heading, toString),
125
+ id: heading.data!.id!,
126
+ level: heading.depth,
127
+ };
128
+ return valueToEstree(value);
129
+ }
130
+
131
+ async function createTOCItemAST(tocItem: TOCItems[number]) {
132
+ switch (tocItem.type) {
133
+ case 'slice':
134
+ return createTOCSliceAST(tocItem);
135
+ case 'heading':
136
+ return createTOCHeadingAST(tocItem);
137
+ default: {
138
+ throw new Error(`unexpected toc item type`);
139
+ }
140
+ }
141
+ }
142
+
143
+ return {
144
+ type: 'mdxjsEsm',
145
+ value: '', // See https://github.com/facebook/docusaurus/pull/9684#discussion_r1457595181
146
+ data: {
147
+ estree: {
148
+ type: 'Program',
149
+ body: [
150
+ {
151
+ type: 'ExportNamedDeclaration',
152
+ declaration: {
153
+ type: 'VariableDeclaration',
154
+ declarations: [
155
+ {
156
+ type: 'VariableDeclarator',
157
+ id: {
158
+ type: 'Identifier',
159
+ name: tocExportName,
160
+ },
161
+ init: {
162
+ type: 'ArrayExpression',
163
+ elements: await Promise.all(tocItems.map(createTOCItemAST)),
164
+ },
165
+ },
166
+ ],
167
+ kind: 'const',
168
+ },
169
+ specifiers: [],
170
+ source: null,
171
+ },
172
+ ],
173
+ sourceType: 'module',
174
+ },
175
+ },
176
+ };
177
+ }