Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/docusaurus-mdx-loader/src/__tests__/processor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,22 @@ Body
expect(result.content).toMatchSnapshot();
});

it('extracts explicit heading ID from HTML comment with mdx1Compat.comments', async () => {
const options = createOptions({
markdownConfig: {
format: 'md',
mdx1Compat: {comments: true},
},
});
const result = await processContent(
'## Hello World <!-- #my-explicit-id -->',
options,
);
expect(result.content).toContain('id: "my-explicit-id"');
expect(result.content).toContain('"value": "Hello World"');
expect(result.content).not.toContain('hello-world');
});

it('preserves legacy heading IDs', async () => {
const options = createOptions();
const result = await processContent('## Heading {#custom-id}', options);
Expand Down
4 changes: 3 additions & 1 deletion packages/docusaurus-mdx-loader/src/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ function createProcessorUncached({
} satisfies TransformLinksOptions,
],
gfm,
options.markdownConfig.mdx1Compat.comments ? remarkComment : null,
options.markdownConfig.mdx1Compat.comments
? [remarkComment, {ast: true}]
: null,
...(options.remarkPlugins ?? []),
[
unusedDirectives,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import {describe, expect, it} from 'vitest';
import {remark} from 'remark';
import mdx from 'remark-mdx';
import remarkComment from '@slorber/remark-comment';
import {u} from 'unist-builder';
import {visit} from 'unist-util-visit';
import {escapeMarkdownHeadingIds} from '@docusaurus/utils';
Expand Down Expand Up @@ -439,6 +440,30 @@ describe('headings remark plugin', () => {
const id = await headingIdFor('# Heading {/* #my-id */}', 'md');
expect(id).not.toEqual('my-id');
});

it('extracts id from HTML comment when remarkComment is enabled', async () => {
const result = await process(
'## Heading <!-- #my-id -->',
[[remarkComment, {ast: true}]],
{},
'md',
);
const heading = result.children[0] as Heading;
expect((heading.data as {id: string}).id).toEqual('my-id');
expect(heading).toEqual(h('Heading', 2, 'my-id'));
});

it('removes the remark-comment node when it is the only heading content', async () => {
const result = await process(
'## <!-- #id-only -->',
[[remarkComment, {ast: true}]],
{},
'md',
);
const heading = result.children[0] as Heading;
expect((heading.data as {id: string}).id).toEqual('id-only');
expect(heading).toEqual(h(null, 2, 'id-only'));
});
});

describe('works for format MDX', () => {
Expand Down
11 changes: 10 additions & 1 deletion packages/docusaurus-mdx-loader/src/remark/headings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ function getCommentHeadingId(heading: Heading): string | undefined {
}
}

// remark-comment AST node: <!-- my-id --> or <!-- #my-id -->
if (lastChild?.type === ('comment' as unknown)) {
const commentContent = (lastChild as unknown as {commentValue?: string})
.commentValue;
if (commentContent) {
return getCommentContentHeadingId(commentContent);
}
}

return undefined;
}

Expand Down Expand Up @@ -114,7 +123,7 @@ const plugin: Plugin<PluginOptions[], Root> = function plugin({
return (root) => {
function getHeadingText(heading: Heading) {
const headingTextNodes = heading.children.filter(
({type}) => !['html', 'jsx'].includes(type),
({type}) => !['html', 'jsx', 'comment'].includes(type),
);
return toString(headingTextNodes.length > 0 ? headingTextNodes : heading);
}
Expand Down