mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-15 07:45:50 +02:00
fix(mdx-loader): refactor and fix heading to toc html value serialization (#11004)
* refactor with iso behavior * Add unit tests * change behavior for <img> tags
This commit is contained in:
parent
1d4d17da18
commit
e88f1aaf96
3 changed files with 207 additions and 76 deletions
|
@ -5,14 +5,8 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import escapeHtml from 'escape-html';
|
||||
import type {Parent, Node} from 'unist';
|
||||
import type {PhrasingContent, Heading} from 'mdast';
|
||||
import type {
|
||||
MdxJsxAttribute,
|
||||
MdxJsxAttributeValueExpression,
|
||||
MdxJsxTextElement,
|
||||
} from 'mdast-util-mdx';
|
||||
import type {Node} from 'unist';
|
||||
import type {MdxJsxAttributeValueExpression} from 'mdast-util-mdx';
|
||||
|
||||
/**
|
||||
* Util to transform one node type to another node type
|
||||
|
@ -35,70 +29,6 @@ export function transformNode<NewNode extends Node>(
|
|||
return node as NewNode;
|
||||
}
|
||||
|
||||
export function stringifyContent(
|
||||
node: Parent,
|
||||
toString: (param: unknown) => string, // TODO weird but works
|
||||
): string {
|
||||
return (node.children as PhrasingContent[])
|
||||
.map((item) => toValue(item, toString))
|
||||
.join('');
|
||||
}
|
||||
|
||||
// TODO This is really a workaround, and not super reliable
|
||||
// For now we only support serializing tagName, className and content
|
||||
// Can we implement the TOC with real JSX nodes instead of html strings later?
|
||||
function mdxJsxTextElementToHtml(
|
||||
element: MdxJsxTextElement,
|
||||
toString: (param: unknown) => string, // TODO weird but works
|
||||
): string {
|
||||
const tag = element.name;
|
||||
|
||||
const attributes = element.attributes.filter(
|
||||
(child): child is MdxJsxAttribute => child.type === 'mdxJsxAttribute',
|
||||
);
|
||||
|
||||
const classAttribute =
|
||||
attributes.find((attr) => attr.name === 'className') ??
|
||||
attributes.find((attr) => attr.name === 'class');
|
||||
|
||||
const classAttributeString = classAttribute
|
||||
? `class="${escapeHtml(String(classAttribute.value))}"`
|
||||
: ``;
|
||||
|
||||
const allAttributes = classAttributeString ? ` ${classAttributeString}` : '';
|
||||
|
||||
const content = stringifyContent(element, toString);
|
||||
|
||||
return `<${tag}${allAttributes}>${content}</${tag}>`;
|
||||
}
|
||||
|
||||
export function toValue(
|
||||
node: PhrasingContent | Heading | MdxJsxTextElement,
|
||||
toString: (param: unknown) => string, // TODO weird but works
|
||||
): string {
|
||||
switch (node.type) {
|
||||
case 'mdxJsxTextElement': {
|
||||
return mdxJsxTextElementToHtml(node as MdxJsxTextElement, toString);
|
||||
}
|
||||
case 'text':
|
||||
return escapeHtml(node.value);
|
||||
case 'heading':
|
||||
return stringifyContent(node, toString);
|
||||
case 'inlineCode':
|
||||
return `<code>${escapeHtml(node.value)}</code>`;
|
||||
case 'emphasis':
|
||||
return `<em>${stringifyContent(node, toString)}</em>`;
|
||||
case 'strong':
|
||||
return `<strong>${stringifyContent(node, toString)}</strong>`;
|
||||
case 'delete':
|
||||
return `<del>${stringifyContent(node, toString)}</del>`;
|
||||
case 'link':
|
||||
return stringifyContent(node, toString);
|
||||
default:
|
||||
return toString(node);
|
||||
}
|
||||
}
|
||||
|
||||
export function assetRequireAttributeValue(
|
||||
requireString: string,
|
||||
hash: string,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue