diff --git a/.cspell.json b/.cspell.json index c7bea3bd6aa7..3e9dd8c3257a 100644 --- a/.cspell.json +++ b/.cspell.json @@ -53,6 +53,6 @@ "*.min.*", "jest/vendor" ], - "ignoreRegExpList": ["Email", "Urls", "#[\\w-]*"], + "ignoreRegExpList": ["Email", "Urls", "#[\\w-]*", "\\u\\{[0-9A-F]{4}\\}"], "enableFiletypes": ["mdx"] } diff --git a/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts b/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts index a81e8cfff103..e81622499d8b 100644 --- a/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts +++ b/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts @@ -197,6 +197,26 @@ describe('createExcerpt', () => { `), ).toBe('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); }); + + it('creates excerpt with XML tag inside inline code', () => { + expect( + createExcerpt(dedent` + # Markdown Regular Title + + This paragraph includes a link to the \`\` documentation. + `), + ).toBe('This paragraph includes a link to the documentation.'); + }); + + it('creates excerpt with XML tag inside inline code with hyperlink', () => { + expect( + createExcerpt(dedent` + # Markdown Regular Title + + This paragraph includes a link to the [\`\`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/metadata) documentation. + `), + ).toBe('This paragraph includes a link to the documentation.'); + }); }); describe('parseMarkdownContentTitle', () => { diff --git a/packages/docusaurus-utils/src/markdownUtils.ts b/packages/docusaurus-utils/src/markdownUtils.ts index 216d0122e7ad..9626e14ec4d1 100644 --- a/packages/docusaurus-utils/src/markdownUtils.ts +++ b/packages/docusaurus-utils/src/markdownUtils.ts @@ -16,6 +16,12 @@ import type { // server-side when we infer metadata like `title` and `description` from the // content. Most parsing is still done in MDX through the mdx-loader. +/** + * Characters that have markup behavior for the Markdown/MDX renderer to + * interpret. + */ +const MARKUP_CHARS = ['_', ':', '*', '<', '>', '~', '!', '[', ']']; + /** * Hacky temporary escape hatch for Crowdin bad MDX support * See https://docusaurus.io/docs/i18n/crowdin#mdx @@ -143,6 +149,12 @@ export function createExcerpt(fileString: string): string | undefined { } const cleanedLine = fileLine + // Unwrap inline code. + .replace(/`(?.+?)`/g, (_, text) => { + return MARKUP_CHARS.reduce((acc, val) => { + return acc.replaceAll(val, `\u{FFFE}${val.codePointAt(0)}\u{FFFF}`); + }, text); + }) // Remove HTML tags. .replace(/<[^>]*>/g, '') // Remove Title headers @@ -159,8 +171,6 @@ export function createExcerpt(fileString: string): string | undefined { .replace(/\[\^.+?\](?:: .*$)?/g, '') // Remove inline links. .replace(/\[(?.*?)\][[(].*?[\])]/g, '$1') - // Remove inline code. - .replace(/`(?.+?)`/g, '$1') // Remove blockquotes. .replace(/^\s{0,3}>\s?/g, '') // Remove admonition definition. @@ -172,7 +182,9 @@ export function createExcerpt(fileString: string): string | undefined { .trim(); if (cleanedLine) { - return cleanedLine; + return MARKUP_CHARS.reduce((acc, val) => { + return acc.replaceAll(`\u{FFFE}${val.codePointAt(0)}\u{FFFF}`, val); + }, cleanedLine); } } diff --git a/website/_dogfooding/_docs tests/doc-with-complex-description.mdx b/website/_dogfooding/_docs tests/doc-with-complex-description.mdx new file mode 100644 index 000000000000..ebb5e46e85c6 --- /dev/null +++ b/website/_dogfooding/_docs tests/doc-with-complex-description.mdx @@ -0,0 +1,3 @@ +# Doc with Complex Description + +One Two _Three_ `` `:Five:` Six ![Seven](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII) diff --git a/website/_dogfooding/docs-tests-sidebars.js b/website/_dogfooding/docs-tests-sidebars.js index d8dac0c10e50..da20f4e6a9b7 100644 --- a/website/_dogfooding/docs-tests-sidebars.js +++ b/website/_dogfooding/docs-tests-sidebars.js @@ -22,6 +22,7 @@ const sidebars = { }, 'doc-without-sidebar', 'doc-with-another-sidebar', + 'doc-with-complex-description', 'doc-with-last-update', { type: 'category',