Skip to content

Commit

Permalink
Fixes rendering of HTML comments inside markdown code blocks (#3638)
Browse files Browse the repository at this point in the history
* JS comment wrappers should be removed from HTML comments in code blocks

* chore: add changeset
  • Loading branch information
Tony Sullivan authored Jun 20, 2022
1 parent 6523591 commit 80c71c7
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/empty-bats-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/markdown-remark': patch
---

Fix: HTML comments in markdown code blocks should not be wrapped in JS comments
1 change: 1 addition & 0 deletions packages/astro/src/vite-plugin-markdown/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {

// Turn HTML comments into JS comments while preventing nested `*/` sequences
// from ending the JS comment by injecting a zero-width space
// Inside code blocks, this is removed during renderMarkdown by the remark-escape plugin.
markdownContent = markdownContent.replace(
/<\s*!--([^-->]*)(.*?)-->/gs,
(whole) => `{/*${whole.replace(/\*\//g, '*\u200b/')}*/}`
Expand Down
14 changes: 14 additions & 0 deletions packages/astro/test/astro-markdown.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ describe('Astro Markdown', () => {
expect($('h1').text()).to.equal('It still works!');
});

it.only('Can handle HTML comments in inline code', async () => {
const html = await fixture.readFile('/comment-with-js/index.html');
const $ = cheerio.load(html);

expect($('p code').text()).to.equal('<!-- HTML comments in code -->');
});

it('Can handle HTML comments in code fences', async () => {
const html = await fixture.readFile('/comment-with-js/index.html');
const $ = cheerio.load(html);

expect($('body > code').text()).to.equal('<!-- HTML comments in code fence -->')
});

// https://github.com/withastro/astro/issues/3254
it('Can handle scripts in markdown pages', async () => {
const html = await fixture.readFile('/script/index.html');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@ function test() {
```
-->

```
<!-- HTML comments in code fence -->
```

`<!-- HTML comments in code -->`

# It still works!
3 changes: 2 additions & 1 deletion packages/markdown/remark/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import rehypeEscape from './rehype-escape.js';
import rehypeExpressions from './rehype-expressions.js';
import rehypeIslands from './rehype-islands.js';
import rehypeJsx from './rehype-jsx.js';
import remarkEscape from './remark-escape.js';
import remarkMarkAndUnravel from './remark-mark-and-unravel.js';
import remarkMdxish from './remark-mdxish.js';
import remarkPrism from './remark-prism.js';
Expand Down Expand Up @@ -46,7 +47,7 @@ export async function renderMarkdown(
let parser = unified()
.use(markdown)
.use(isMDX ? [remarkMdxish, remarkMarkAndUnravel] : [])
.use([remarkUnwrap]);
.use([remarkUnwrap, remarkEscape]);

if (remarkPlugins.length === 0 && rehypePlugins.length === 0) {
remarkPlugins = [...DEFAULT_REMARK_PLUGINS];
Expand Down
17 changes: 17 additions & 0 deletions packages/markdown/remark/src/remark-escape.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { visit } from 'unist-util-visit';
import type { Literal } from 'unist';

// In code blocks, this removes the JS comment wrapper added to
// HTML comments by vite-plugin-markdown.
export default function remarkEscape() {
return (tree: any) => {
visit(tree, 'code', removeCommentWrapper);
visit(tree, 'inlineCode', removeCommentWrapper);
};

function removeCommentWrapper(node: Literal<string>) {
node.value = node.value
.replace(/{\/\*<!--/gs, '<!--')
.replace(/-->\*\/}/gs, '-->');
}
}
20 changes: 20 additions & 0 deletions packages/markdown/remark/test/expressions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,24 @@ describe('expressions', () => {

chai.expect(code).to.equal(`{frontmatter.list.map(item => <p id={item}>{item}</p>)}`);
});

it('should unwrap HTML comments in inline code blocks', async () => {
const { code } = await renderMarkdown(
`\`{/*<!-- HTML comment -->*/}\``
);

chai.expect(code).to.equal('<p><code is:raw>&lt;!-- HTML comment --&gt;</code></p>');
});

it('should unwrap HTML comments in code fences', async () => {
const { code } = await renderMarkdown(
`
\`\`\`
<!-- HTML comment -->
\`\`\`
`
);

chai.expect(code).to.match(/(?<!{\/\*)&lt;!-- HTML comment --&gt;(?!\*\/})/);
});
});

0 comments on commit 80c71c7

Please sign in to comment.