Skip to content

Commit

Permalink
fix: generate slug for id including values in backtick blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
nokazn committed Jun 2, 2022
1 parent d1b7a36 commit fb69531
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
12 changes: 8 additions & 4 deletions packages/markdown/remark/src/rehype-collect-headers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function createCollectHeaders() {
let text = '';
let isJSX = false;
visit(node, (child, _, parent) => {
if (child.type === 'element' || ['code', 'pre'].some((tag) => parent?.tagName === tag)) {
if (child.type === 'element' || parent == null) {
return;
}
if (child.type === 'raw') {
Expand All @@ -30,8 +30,12 @@ export default function createCollectHeaders() {
}
}
if (child.type === 'text' || child.type === 'raw') {
text += child.value;
isJSX = isJSX || child.value.includes('{');
if (new Set(['code', 'pre']).has(parent.tagName)) {
text += child.value;
} else {
text += child.value.replace(/\{/g, '${');
isJSX = isJSX || child.value.includes('{');
}
}
});

Expand All @@ -43,7 +47,7 @@ export default function createCollectHeaders() {
.replace(/\n(<)/g, '<')
.replace(/(>)\n/g, '>');
// HACK: for ids that have JSX content, use $$slug helper to generate slug at runtime
node.properties.id = `$$slug(\`${text.replace(/\{/g, '${')}\`)`;
node.properties.id = `$$slug(\`${text}\`)`;
(node as any).type = 'raw';
(
node as any
Expand Down
12 changes: 10 additions & 2 deletions packages/markdown/remark/test/expressions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,21 @@ describe('expressions', () => {
);
});

it('should be able to avoid evaluating JSX-like expressions in an inline code & generate a slug for id', async () => {
const { code } = await renderMarkdown(`# \`{frontmatter.title}\``, {});

chai
.expect(code)
.to.equal('<h1 id="frontmattertitle"><code is:raw>{frontmatter.title}</code></h1>');
});

it('should be able to avoid evaluating JSX-like expressions in inline codes', async () => {
const { code } = await renderMarkdown(`# \`{ foo }\` is a shorthand for \`{ foo: foo }\``, {});

chai
.expect(code)
.to.equal(
'<h1 id="-is-a-shorthand-for-"><code is:raw>{ foo }</code> is a shorthand for <code is:raw>{ foo: foo }</code></h1>'
'<h1 id="-foo--is-a-shorthand-for--foo-foo-"><code is:raw>{ foo }</code> is a shorthand for <code is:raw>{ foo: foo }</code></h1>'
);
});

Expand All @@ -59,7 +67,7 @@ describe('expressions', () => {
chai
.expect(code)
.to.equal(
`<h6 id={$$slug(\` is equivalent to (at TypeScript v\${frontmatter.version})\`)}><code is:raw>{}</code> is equivalent to <code is:raw>Record&lt;never, never&gt;</code> <small>(at TypeScript v{frontmatter.version})</small></h6>`
`<h6 id={$$slug(\`{} is equivalent to Record&lt;never, never&gt; (at TypeScript v\${frontmatter.version})\`)}><code is:raw>{}</code> is equivalent to <code is:raw>Record&lt;never, never&gt;</code> <small>(at TypeScript v{frontmatter.version})</small></h6>`
);
});

Expand Down

0 comments on commit fb69531

Please sign in to comment.