in packages/docusaurus-mdx-loader/src/remark/headings/index.ts [16:70]
export default function plugin(): Transformer {
return (root) => {
const slugs = createSlugger();
visit(root, 'heading', (headingNode: Heading) => {
const data = headingNode.data || (headingNode.data = {});
const properties = (data.hProperties || (data.hProperties = {})) as {
id: string;
};
let {id} = properties;
if (id) {
id = slugs.slug(id, {maintainCase: true});
} else {
const headingTextNodes = headingNode.children.filter(
({type}) => !['html', 'jsx'].includes(type),
);
const heading = mdastToString(
headingTextNodes.length > 0 ? headingTextNodes : headingNode,
);
// Support explicit heading IDs
const parsedHeading = parseMarkdownHeadingId(heading);
id = parsedHeading.id || slugs.slug(heading);
if (parsedHeading.id) {
// When there's an id, it is always in the last child node
// Sometimes heading is in multiple "parts" (** syntax creates a child
// node):
// ## part1 *part2* part3 {#id}
const lastNode = headingNode.children[
headingNode.children.length - 1
] as Text;
if (headingNode.children.length > 1) {
const lastNodeText = parseMarkdownHeadingId(lastNode.value).text;
// When last part contains test+id, remove the id
if (lastNodeText) {
lastNode.value = lastNodeText;
}
// When last part contains only the id: completely remove that node
else {
headingNode.children.pop();
}
} else {
lastNode.value = parsedHeading.text;
}
}
}
data.id = id;
properties.id = id;
});
};
}