From 16034f0dd5b3683e9e022dbd413e85bd18d2b031 Mon Sep 17 00:00:00 2001 From: hippotastic <6137925+hippotastic@users.noreply.github.com> Date: Fri, 5 Aug 2022 16:23:16 +0200 Subject: [PATCH] Fix double-escaping of non-highlighted code blocks in Astro-flavored markdown (#4169) --- .changeset/strong-hotels-cross.md | 5 +++++ packages/markdown/remark/src/rehype-escape.ts | 5 +++-- .../markdown/remark/test/entities.test.js | 22 +++++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 .changeset/strong-hotels-cross.md diff --git a/.changeset/strong-hotels-cross.md b/.changeset/strong-hotels-cross.md new file mode 100644 index 000000000..56f5789c6 --- /dev/null +++ b/.changeset/strong-hotels-cross.md @@ -0,0 +1,5 @@ +--- +'@astrojs/markdown-remark': patch +--- + +Fix double-escaping of non-highlighted code blocks in Astro-flavored markdown diff --git a/packages/markdown/remark/src/rehype-escape.ts b/packages/markdown/remark/src/rehype-escape.ts index e99e37e41..b0a4cb923 100644 --- a/packages/markdown/remark/src/rehype-escape.ts +++ b/packages/markdown/remark/src/rehype-escape.ts @@ -1,4 +1,4 @@ -import { visit } from 'unist-util-visit'; +import { visit, SKIP } from 'unist-util-visit'; export function escapeEntities(value: string): string { return value.replace(/&/g, '&').replace(//g, '>'); @@ -14,8 +14,9 @@ export default function rehypeEscape(): any { visit(el, 'raw', (raw) => { raw.value = escapeEntities(raw.value); }); + // Do not visit children to prevent double escaping + return SKIP; } - return el; }); }; } diff --git a/packages/markdown/remark/test/entities.test.js b/packages/markdown/remark/test/entities.test.js index a6b5918a5..dff844329 100644 --- a/packages/markdown/remark/test/entities.test.js +++ b/packages/markdown/remark/test/entities.test.js @@ -2,11 +2,25 @@ import { renderMarkdown } from '../dist/index.js'; import { expect } from 'chai'; describe('entities', () => { - const renderAstroMd = (text) => renderMarkdown(text, { isAstroFlavoredMd: false }); - - it('should not unescape entities', async () => { - const { code } = await renderAstroMd(`<i>This should NOT be italic</i>`); + it('should not unescape entities in regular Markdown', async () => { + const { code } = await renderMarkdown(`<i>This should NOT be italic</i>`, { + isAstroFlavoredMd: false, + }); expect(code).to.equal(`

<i>This should NOT be italic</i>

`); }); + + it('should not escape entities in code blocks twice in Astro-flavored markdown', async () => { + const { code } = await renderMarkdown( + `\`\`\`astro\n

{x && x.name || ''}!

\n\`\`\``, + { + isAstroFlavoredMd: true, + syntaxHighlight: false, + } + ); + + expect(code).to.equal( + `
<h1>{x && x.name || ''}!</h1>\n
` + ); + }); });