Skip to content

Commit 9868bab

Browse files
authored
fix(mdx-loader): improve mdxJsxTextElementToHtml (#9262)
1 parent b3c8f5c commit 9868bab

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/non-text-content.md

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ exports[`toc remark plugin works on non text phrasing content 1`] = `
171171
value: '<code>inline.code()</code>',
172172
id: 'inlinecode',
173173
level: 2
174+
},
175+
{
176+
value: 'some <span class="some-class">styled</span> <strong>heading</strong> <span class="myClassName &lt;&gt; weird char"></span> test',
177+
id: 'some-styled-heading--test',
178+
level: 2
174179
}
175180
]
176181
@@ -183,6 +188,8 @@ exports[`toc remark plugin works on non text phrasing content 1`] = `
183188
## <i>HTML</i>
184189
185190
## \`inline.code()\`
191+
192+
## some <span className="some-class" style={{border: "solid"}}>styled</span> <strong>heading</strong> <span class="myClass" className="myClassName <> weird char" data-random-attr="456" /> test
186193
"
187194
`;
188195

packages/docusaurus-mdx-loader/src/remark/utils/index.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,57 @@
88
import escapeHtml from 'escape-html';
99
import type {Parent} from 'unist';
1010
import type {PhrasingContent, Heading} from 'mdast';
11-
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
12-
import type {MdxJsxAttributeValueExpression} from 'mdast-util-mdx';
11+
import type {
12+
MdxJsxAttribute,
13+
MdxJsxAttributeValueExpression,
14+
MdxJsxTextElement,
15+
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
16+
} from 'mdast-util-mdx';
1317

1418
export function stringifyContent(
1519
node: Parent,
16-
toString: (param: unknown) => string, // TODO weird but works): string {
20+
toString: (param: unknown) => string, // TODO weird but works
1721
): string {
1822
return (node.children as PhrasingContent[])
1923
.map((item) => toValue(item, toString))
2024
.join('');
2125
}
2226

27+
// TODO This is really a workaround, and not super reliable
28+
// For now we only support serializing tagName, className and content
29+
// Can we implement the TOC with real JSX nodes instead of html strings later?
30+
function mdxJsxTextElementToHtml(
31+
element: MdxJsxTextElement,
32+
toString: (param: unknown) => string, // TODO weird but works
33+
): string {
34+
const tag = element.name;
35+
36+
const attributes = element.attributes.filter(
37+
(child): child is MdxJsxAttribute => child.type === 'mdxJsxAttribute',
38+
);
39+
40+
const classAttribute =
41+
attributes.find((attr) => attr.name === 'className') ??
42+
attributes.find((attr) => attr.name === 'class');
43+
44+
const classAttributeString = classAttribute
45+
? `class="${escapeHtml(String(classAttribute.value))}"`
46+
: ``;
47+
48+
const allAttributes = classAttributeString ? ` ${classAttributeString}` : '';
49+
50+
const content = stringifyContent(element, toString);
51+
52+
return `<${tag}${allAttributes}>${content}</${tag}>`;
53+
}
54+
2355
export function toValue(
2456
node: PhrasingContent | Heading,
2557
toString: (param: unknown) => string, // TODO weird but works
2658
): string {
2759
switch (node.type) {
2860
case 'mdxJsxTextElement': {
29-
const tag = node.name;
30-
return `<${tag}>${stringifyContent(node, toString)}</${tag}>`;
61+
return mdxJsxTextElementToHtml(node as MdxJsxTextElement, toString);
3162
}
3263
case 'text':
3364
return escapeHtml(node.value);

0 commit comments

Comments
 (0)