fix(utils): allow any non-boundary characters in Markdown heading ID (#7604)

This commit is contained in:
Joshua Chen 2022-06-16 18:32:42 +08:00 committed by GitHub
parent 0114f00069
commit 89e146f596
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 4 deletions

View file

@ -833,6 +833,53 @@ describe('parseMarkdownHeadingId', () => {
id: 'id',
});
});
it('does not parse empty id', () => {
expect(parseMarkdownHeadingId('## a {#}')).toEqual({
text: '## a {#}',
id: undefined,
});
});
it('can parse id with more characters', () => {
expect(parseMarkdownHeadingId('## a {#你好}')).toEqual({
text: '## a',
id: '你好',
});
expect(parseMarkdownHeadingId('## a {#2022.1.1}')).toEqual({
text: '## a',
id: '2022.1.1',
});
expect(parseMarkdownHeadingId('## a {#a#b}')).toEqual({
text: '## a',
id: 'a#b',
});
});
// The actual behavior is unspecified, just need to ensure it stays consistent
it('handles unmatched boundaries', () => {
expect(parseMarkdownHeadingId('## a {# a {#bcd}')).toEqual({
text: '## a {# a',
id: 'bcd',
});
expect(parseMarkdownHeadingId('## a {#bcd}}')).toEqual({
text: '## a {#bcd}}',
id: undefined,
});
expect(parseMarkdownHeadingId('## a {#b{cd}')).toEqual({
text: '## a',
id: 'b{cd',
});
expect(parseMarkdownHeadingId('## a {#b{#b}')).toEqual({
text: '## a {#b',
id: 'b',
});
});
});
describe('writeMarkdownHeadingId', () => {

View file

@ -14,8 +14,8 @@ import {createSlugger, type Slugger, type SluggerOptions} from './slugger';
// content. Most parsing is still done in MDX through the mdx-loader.
/**
* Parses custom ID from a heading. The ID must be composed of letters,
* underscores, and dashes only.
* Parses custom ID from a heading. The ID can contain any characters except
* `{#` and `}`.
*
* @param heading e.g. `## Some heading {#some-heading}` where the last
* character must be `}` for the ID to be recognized
@ -26,9 +26,9 @@ export function parseMarkdownHeadingId(heading: string): {
*/
text: string;
/** The heading ID. e.g. `some-heading` */
id?: string;
id: string | undefined;
} {
const customHeadingIdRegex = /\s*\{#(?<id>[\w-]+)\}$/;
const customHeadingIdRegex = /\s*\{#(?<id>(?:.(?!\{#|\}))*.)\}$/;
const matches = customHeadingIdRegex.exec(heading);
if (matches) {
return {

View file

@ -162,6 +162,16 @@ function Clock(props) {
## Custom heading ID {#custom}
### Weird heading {#你好}
### Weird heading {#2022.1.1}
### Weird heading {#a#b}
### Weird heading {#a b}
### Weird heading {#a{b}
## Pipe
Code tag + double pipe: <code>&#124;&#124;</code>