diff options
-rw-r--r-- | .changeset/strong-hotels-cross.md | 5 | ||||
-rw-r--r-- | packages/markdown/remark/src/rehype-escape.ts | 5 | ||||
-rw-r--r-- | packages/markdown/remark/test/entities.test.js | 22 |
3 files changed, 26 insertions, 6 deletions
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, '<').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(`<p><i>This should NOT be italic</i></p>`); }); + + it('should not escape entities in code blocks twice in Astro-flavored markdown', async () => { + const { code } = await renderMarkdown( + `\`\`\`astro\n<h1>{x && x.name || ''}!</h1>\n\`\`\``, + { + isAstroFlavoredMd: true, + syntaxHighlight: false, + } + ); + + expect(code).to.equal( + `<pre is:raw><code class="language-astro"><h1>{x && x.name || ''}!</h1>\n</code></pre>` + ); + }); }); |