From 23dbf9c0ae14c5d012a8c9bbc8570885d69b1558 Mon Sep 17 00:00:00 2001 From: ozaki <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:14:31 +0200 Subject: [PATCH] feat(mdx-loader): wrap mdx content title (`# Title`) in `
` for concistency (#10335) Co-authored-by: sebastien --- argos/tests/screenshot.spec.ts | 2 + .../contentTitle/__tests__/index.test.ts | 39 +++++++++++++++---- .../src/remark/contentTitle/index.ts | 27 ++++++++++++- .../src/remark/head/index.ts | 2 +- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/argos/tests/screenshot.spec.ts b/argos/tests/screenshot.spec.ts index b1f6824288f8..3fbb4b0d6308 100644 --- a/argos/tests/screenshot.spec.ts +++ b/argos/tests/screenshot.spec.ts @@ -41,6 +41,8 @@ function isBlacklisted(pathname: string) { '/feature-requests', // Flaky because of dynamic canary version fetched from npm '/community/canary', + // Flaky because of screenshots being taken dynamically + '/showcase', // Long blog post with many image carousels, often timeouts '/blog/2022/08/01/announcing-docusaurus-2.0', ]; diff --git a/packages/docusaurus-mdx-loader/src/remark/contentTitle/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/contentTitle/__tests__/index.test.ts index 54d111754833..995bd394088e 100644 --- a/packages/docusaurus-mdx-loader/src/remark/contentTitle/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/contentTitle/__tests__/index.test.ts @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import {escapeMarkdownHeadingIds} from '@docusaurus/utils'; import plugin from '../index'; async function process( @@ -12,8 +13,14 @@ async function process( options: {removeContentTitle?: boolean} = {}, ) { const {remark} = await import('remark'); - const processor = await remark().use({plugins: [[plugin, options]]}); - return processor.process(content); + const {default: mdx} = await import('remark-mdx'); + + const result = await remark() + .use(mdx) + .use(plugin, options) + .process(escapeMarkdownHeadingIds(content)); + + return result; } describe('contentTitle remark plugin', () => { @@ -33,7 +40,8 @@ some **markdown** *content* }); it('extracts h1 heading alt syntax', async () => { - const result = await process(` + const result = await process( + ` contentTitle alt === @@ -44,7 +52,8 @@ contentTitle alt # contentTitle 2 some **markdown** *content* - `); + `, + ); expect(result.data.contentTitle).toBe('contentTitle alt'); }); @@ -98,7 +107,9 @@ some **markdown** *content* }); describe('returns appropriate content', () => { - it('returns content unmodified', async () => { + it('returns heading wrapped in
', async () => { + // Test case for https://github.com/facebook/docusaurus/issues/8476 + const content = ` # contentTitle 1 @@ -111,7 +122,19 @@ some **markdown** *content* const result = await process(content); - expect(result.toString().trim()).toEqual(content); + expect(result.toString().trim()).toEqual( + ` +
+ # contentTitle 1 +
+ +## Heading Two \\{#custom-heading-two} + +# contentTitle 2 + +some **markdown** *content* +`.trim(), + ); }); it('can strip contentTitle', async () => { @@ -129,7 +152,7 @@ some **markdown** *content* expect(result.toString().trim()).toEqual( ` -## Heading Two {#custom-heading-two} +## Heading Two \\{#custom-heading-two} # contentTitle 2 @@ -154,7 +177,7 @@ some **markdown** *content* expect(result.toString().trim()).toEqual( ` -## Heading Two {#custom-heading-two} +## Heading Two \\{#custom-heading-two} # contentTitle 2 diff --git a/packages/docusaurus-mdx-loader/src/remark/contentTitle/index.ts b/packages/docusaurus-mdx-loader/src/remark/contentTitle/index.ts index 65ad91f82528..12aa5cdc7ba9 100644 --- a/packages/docusaurus-mdx-loader/src/remark/contentTitle/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/contentTitle/index.ts @@ -7,7 +7,10 @@ // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 import type {Transformer} from 'unified'; -import type {Heading} from 'mdast'; +import type {Heading, Parent} from 'mdast'; + +// @ts-expect-error: ES support... +import type {MdxJsxFlowElement} from 'mdast-util-mdx'; // TODO as of April 2023, no way to import/re-export this ESM type easily :/ // TODO upgrade to TS 5.3 @@ -19,6 +22,20 @@ interface PluginOptions { removeContentTitle?: boolean; } +function wrapHeadingInJsxHeader( + headingNode: Heading, + parent: Parent, + index: number, +) { + const header: MdxJsxFlowElement = { + type: 'mdxJsxFlowElement', + name: 'header', + attributes: [], + children: [headingNode], + }; + parent.children[index] = header; +} + /** * A remark plugin to extract the h1 heading found in Markdown files * This is exposed as "data.contentTitle" to the processed vfile @@ -33,15 +50,21 @@ const plugin: Plugin = function plugin( return async (root, vfile) => { const {toString} = await import('mdast-util-to-string'); const {visit, EXIT} = await import('unist-util-visit'); - visit(root, ['heading', 'thematicBreak'], (node, index, parent) => { if (node.type === 'heading') { const headingNode = node as Heading; + // console.log('headingNode:', headingNode); + if (headingNode.depth === 1) { vfile.data.contentTitle = toString(headingNode); if (removeContentTitle) { // @ts-expect-error: TODO how to fix? parent!.children.splice(index, 1); + } else { + // TODO in the future it might be better to export contentTitle as + // as JSX node to keep this logic a theme concern? + // See https://github.com/facebook/docusaurus/pull/10335#issuecomment-2250187371 + wrapHeadingInJsxHeader(headingNode, parent, index!); } return EXIT; // We only handle the very first heading } diff --git a/packages/docusaurus-mdx-loader/src/remark/head/index.ts b/packages/docusaurus-mdx-loader/src/remark/head/index.ts index 3063c93a8285..0bab7a76692d 100644 --- a/packages/docusaurus-mdx-loader/src/remark/head/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/head/index.ts @@ -8,7 +8,7 @@ // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 import type {Transformer} from 'unified'; -// @ts-expect-error: ES support... +// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 import type {MdxJsxFlowElement} from 'mdast-util-mdx'; // Transform to