Skip to content

Commit

Permalink
Add ability to escape heading anchor link syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
slorber committed Nov 4, 2022
1 parent 1bf2e82 commit 83064b2
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 29 deletions.
12 changes: 9 additions & 3 deletions packages/docusaurus-mdx-loader/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
parseMarkdownContentTitle,
escapePath,
getFileLoaderUtils,
escapeMarkdownHeadingIds,
} from '@docusaurus/utils';
import emoji from 'remark-emoji';

Expand Down Expand Up @@ -171,9 +172,14 @@ export async function mdxLoader(

const {frontMatter, content: contentWithTitle} = parseFrontMatter(fileString);

const {content, contentTitle} = parseMarkdownContentTitle(contentWithTitle, {
removeContentTitle: reqOptions.removeContentTitle,
});
const {content: contentUnescaped, contentTitle} = parseMarkdownContentTitle(
contentWithTitle,
{
removeContentTitle: reqOptions.removeContentTitle,
},
);

const content = escapeMarkdownHeadingIds(contentUnescaped);

const hasFrontMatter = Object.keys(frontMatter).length > 0;

Expand Down
135 changes: 135 additions & 0 deletions packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
parseMarkdownString,
parseMarkdownHeadingId,
writeMarkdownHeadingId,
escapeMarkdownHeadingIds,
} from '../markdownUtils';

describe('createExcerpt', () => {
Expand Down Expand Up @@ -882,6 +883,140 @@ describe('parseMarkdownHeadingId', () => {
});
});

describe('escapeMarkdownHeadingIds', () => {
it('can escape simple heading id', () => {
expect(escapeMarkdownHeadingIds('# title 1 {#id-1}')).toBe(
'# title 1 \\{#id-1}',
);
expect(escapeMarkdownHeadingIds('# title 1 {#id-1}')).toBe(
'# title 1 \\{#id-1}',
);
expect(escapeMarkdownHeadingIds('# title 1{#id-1}')).toBe(
'# title 1\\{#id-1}',
);
expect(escapeMarkdownHeadingIds('# title 1 \\{#id-1}')).toBe(
'# title 1 \\{#id-1}',
);
expect(escapeMarkdownHeadingIds('# title 1\\{#id-1}')).toBe(
'# title 1\\{#id-1}',
);
});

it('can escape level 1-6 heading ids', () => {
expect(
escapeMarkdownHeadingIds(dedent`
# title 1 {#id-1}
## title 2 {#id-2}
### title 3 {#id-3}
#### title 4 {#id-4}
##### title 5 {#id-5}
###### title 6 {#id-6}
`),
).toEqual(dedent`
# title 1 \{#id-1}
## title 2 \{#id-2}
### title 3 \{#id-3}
#### title 4 \{#id-4}
##### title 5 \{#id-5}
###### title 6 \{#id-6}
`);
});

it('does not escape level 7 heading id', () => {
expect(
escapeMarkdownHeadingIds(dedent`
####### title 7 {#id-7}
`),
).toEqual(dedent`
####### title 7 {#id-7}
`);
});

it('does not escape non-heading', () => {
expect(
escapeMarkdownHeadingIds(dedent`
some text {#non-id}
`),
).toEqual(dedent`
some text {#non-id}
`);
});

it('real world', () => {
expect(
escapeMarkdownHeadingIds(dedent`
# Support
Docusaurus has a community of thousands of developers.
On this page we've listed some Docusaurus-related communities that you can be a part of; see the other pages in this section for additional online and in-person learning materials.
Before participating in Docusaurus' communities, [please read our Code of Conduct](https://engineering.fb.com/codeofconduct/). We have adopted the [Contributor Covenant](https://www.contributor-covenant.org/) and we expect that all community members adhere to the guidelines within.
## Stack Overflow {#stack-overflow}
Stack Overflow is a popular forum to ask code-level questions or if you're stuck with a specific error. Read through the [existing questions](https://stackoverflow.com/questions/tagged/docusaurus) tagged with **docusaurus** or [ask your own](https://stackoverflow.com/questions/ask?tags=docusaurus)!
## Discussion forums \{#discussion-forums}
There are many online forums for discussion about best practices and application architecture as well as the future of Docusaurus. If you have an answerable code-level question, Stack Overflow is usually a better fit.
- [Docusaurus online chat](https://discord.gg/docusaurus)
- [#help-and-questions](https://discord.gg/fwbcrQ3dHR) for user help
- [#contributors](https://discord.gg/6g6ASPA) for contributing help
- [Reddit's Docusaurus community](https://www.reddit.com/r/docusaurus/)
## Feature requests {#feature-requests}
For new feature requests, you can create a post on our [feature requests board (Canny)](/feature-requests), which is a handy tool for road-mapping and allows for sorting by upvotes, which gives the core team a better indicator of what features are in high demand, as compared to GitHub issues which are harder to triage. Refrain from making a Pull Request for new features (especially large ones) as someone might already be working on it or will be part of our roadmap. Talk to us first!
## News {#news}
For the latest news about Docusaurus, [follow **@docusaurus** on Twitter](https://twitter.com/docusaurus) and the [official Docusaurus blog](/blog) on this website.
`),
).toEqual(dedent`
# Support
Docusaurus has a community of thousands of developers.
On this page we've listed some Docusaurus-related communities that you can be a part of; see the other pages in this section for additional online and in-person learning materials.
Before participating in Docusaurus' communities, [please read our Code of Conduct](https://engineering.fb.com/codeofconduct/). We have adopted the [Contributor Covenant](https://www.contributor-covenant.org/) and we expect that all community members adhere to the guidelines within.
## Stack Overflow \{#stack-overflow}
Stack Overflow is a popular forum to ask code-level questions or if you're stuck with a specific error. Read through the [existing questions](https://stackoverflow.com/questions/tagged/docusaurus) tagged with **docusaurus** or [ask your own](https://stackoverflow.com/questions/ask?tags=docusaurus)!
## Discussion forums \{#discussion-forums}
There are many online forums for discussion about best practices and application architecture as well as the future of Docusaurus. If you have an answerable code-level question, Stack Overflow is usually a better fit.
- [Docusaurus online chat](https://discord.gg/docusaurus)
- [#help-and-questions](https://discord.gg/fwbcrQ3dHR) for user help
- [#contributors](https://discord.gg/6g6ASPA) for contributing help
- [Reddit's Docusaurus community](https://www.reddit.com/r/docusaurus/)
## Feature requests \{#feature-requests}
For new feature requests, you can create a post on our [feature requests board (Canny)](/feature-requests), which is a handy tool for road-mapping and allows for sorting by upvotes, which gives the core team a better indicator of what features are in high demand, as compared to GitHub issues which are harder to triage. Refrain from making a Pull Request for new features (especially large ones) as someone might already be working on it or will be part of our roadmap. Talk to us first!
## News \{#news}
For the latest news about Docusaurus, [follow **@docusaurus** on Twitter](https://twitter.com/docusaurus) and the [official Docusaurus blog](/blog) on this website.
`);
});
});

describe('writeMarkdownHeadingId', () => {
it('works for simple level-2 heading', () => {
expect(writeMarkdownHeadingId('## ABC')).toBe('## ABC {#abc}');
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export {
} from './tags';
export {
parseMarkdownHeadingId,
escapeMarkdownHeadingIds,
createExcerpt,
parseFrontMatter,
parseMarkdownContentTitle,
Expand Down
17 changes: 17 additions & 0 deletions packages/docusaurus-utils/src/markdownUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ export function parseMarkdownHeadingId(heading: string): {
return {text: heading, id: undefined};
}

/**
* MDX 2 requires escaping { with a \ so our anchor syntax need that now.
* See https://mdxjs.com/docs/troubleshooting-mdx/#could-not-parse-expression-with-acorn-error
*/
export function escapeMarkdownHeadingIds(content: string): string {
const markdownHeadingRegexp = /(?:^|\n)#{1,6}(?!#).*/g;
return content.replaceAll(markdownHeadingRegexp, (substring, ...args) =>
// TODO probably not the most efficient impl...
(
substring
.replace('{#', '\\{#')
// prevent duplicate escaping
.replace('\\\\{#', '\\{#')
)
);
}

// TODO: Find a better way to do so, possibly by compiling the Markdown content,
// stripping out HTML tags and obtaining the first line.
/**
Expand Down
8 changes: 4 additions & 4 deletions website/community/0-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ On this page we've listed some Docusaurus-related communities that you can be a

Before participating in Docusaurus' communities, [please read our Code of Conduct](https://engineering.fb.com/codeofconduct/). We have adopted the [Contributor Covenant](https://www.contributor-covenant.org/) and we expect that all community members adhere to the guidelines within.

## Stack Overflow \{#stack-overflow}
## Stack Overflow {#stack-overflow}

Stack Overflow is a popular forum to ask code-level questions or if you're stuck with a specific error. Read through the [existing questions](https://stackoverflow.com/questions/tagged/docusaurus) tagged with **docusaurus** or [ask your own](https://stackoverflow.com/questions/ask?tags=docusaurus)!

## Discussion forums \{#discussion-forums}
## Discussion forums {#discussion-forums}

There are many online forums for discussion about best practices and application architecture as well as the future of Docusaurus. If you have an answerable code-level question, Stack Overflow is usually a better fit.

Expand All @@ -19,10 +19,10 @@ There are many online forums for discussion about best practices and application
- [#contributors](https://discord.gg/6g6ASPA) for contributing help
- [Reddit's Docusaurus community](https://www.reddit.com/r/docusaurus/)

## Feature requests \{#feature-requests}
## Feature requests {#feature-requests}

For new feature requests, you can create a post on our [feature requests board (Canny)](/feature-requests), which is a handy tool for road-mapping and allows for sorting by upvotes, which gives the core team a better indicator of what features are in high demand, as compared to GitHub issues which are harder to triage. Refrain from making a Pull Request for new features (especially large ones) as someone might already be working on it or will be part of our roadmap. Talk to us first!

## News \{#news}
## News {#news}

For the latest news about Docusaurus, [follow **@docusaurus** on Twitter](https://twitter.com/docusaurus) and the [official Docusaurus blog](/blog) on this website.
8 changes: 4 additions & 4 deletions website/community/1-team.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@ import {
StudentFellowsTeamRow,
} from '@site/src/components/TeamProfileCards';

## Active Team \{#active-team}
## Active Team {#active-team}

The Docusaurus team works on the core functionality, plugins for the classic theme, as well as the Docusaurus documentation website.

Current members of the Docusaurus team are listed in alphabetical order below.

<ActiveTeamRow />

## Honorary Alumni \{#honorary-alumni}
## Honorary Alumni {#honorary-alumni}

Docusaurus would never be what it is today without the huge contributions from these folks who have moved on to bigger and greater things.

<HonoraryAlumniTeamRow />

## Student Fellows \{#student-fellows}
## Student Fellows {#student-fellows}

A handful of students have also worked on Docusaurus as part of their school term/internship and the [Major League Hacking Fellowship program](https://fellowship.mlh.io/), contributing amazing features such as plugin options validation, migration tooling, and a Bootstrap theme.

<StudentFellowsTeamRow />

## Acknowledgements \{#acknowledgements}
## Acknowledgements {#acknowledgements}

Docusaurus was originally created by Joel Marcey. Today, Docusaurus has a few hundred open source contributors. We’d like to recognize a few people who have made significant contributions to Docusaurus and its documentation in the past and have helped maintain them over the years:

Expand Down
16 changes: 8 additions & 8 deletions website/community/2-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,37 @@

A curated list of interesting Docusaurus community projects.

## Videos \{#videos}
## Videos {#videos}

- [F8 2019: Using Docusaurus to Create Open Source Websites](https://www.youtube.com/watch?v=QcGJsf6mgZE)

## Articles \{#articles}
## Articles {#articles}

- [Awesome Docusaurus](https://github.com/webbertakken/awesome-docusaurus#readme) - Community curated list of Docusaurus resources.
- [Live code editing in Docusaurus](https://dev.to/mrmuhammadali/live-code-editing-in-docusaurus-ux-at-its-best-2hj1)

## Showcase \{#showcase}
## Showcase {#showcase}

See the <a href={require('@docusaurus/useBaseUrl').default('showcase')}>showcase</a>.

## Community plugins \{#community-plugins}
## Community plugins {#community-plugins}

### Search \{#search}
### Search {#search}

- [docusaurus-plugin-lunr](https://github.com/daldridge/docusaurus-plugin-lunr) - Docusaurus v2 plugin to create a local search index for use with Lunr.js
- [docusaurus-lunr-search](https://github.com/lelouch77/docusaurus-lunr-search) - Offline Search for Docusaurus v2
- [docusaurus-search-local](https://github.com/cmfcmf/docusaurus-search-local) - Offline/local search for Docusaurus v2
- [@easyops-cn/docusaurus-search-local](https://github.com/easyops-cn/docusaurus-search-local) - Offline/local search for Docusaurus v2 (language of zh supported)
- [docusaurus-theme-search-typesense](https://github.com/typesense/docusaurus-theme-search-typesense) - Docusaurus v2 plugin for [Typesense DocSearch](https://typesense.org/docs/latest/guide/docsearch.html).

### Integrations \{#integrations}
### Integrations {#integrations}

- [docusaurus2-dotenv](https://github.com/jonnynabors/docusaurus2-dotenv) - A Docusaurus 2 plugin that supports dotenv and other environment variables
- [posthog-docusaurus](https://github.com/PostHog/posthog-docusaurus) - Integrate [PostHog](https://posthog.com/) product analytics with Docusaurus v2
- [docusaurus-plugin-moesif](https://github.com/Moesif/docusaurus-plugin-moesif) - Adds [Moesif API Analytics](https://www.moesif.com/) to track user behavior and pinpoint where developers drop off in your activation funnel.
- [docusaurus-plugin-yandex-metrica](https://github.com/sgromkov/docusaurus-plugin-yandex-metrica) - Adds [Yandex Metrika](https://metrika.yandex.ru/) counter for evaluating site traffic and analyzing user behavior.

### Features \{#features}
### Features {#features}

- [docusaurus-theme-github-codeblock](https://github.com/saucelabs/docusaurus-theme-github-codeblock). A Docusaurus v2 plugin that supports referencing code examples from public GitHub repositories
- [mr-pdf](https://github.com/kohheepeace/mr-pdf) - Generate documentation into PDF format, suitable for Docusaurus v1 and v2 (including beta versions)
Expand All @@ -50,7 +50,7 @@ See the <a href={require('@docusaurus/useBaseUrl').default('showcase')}>showcase
- [docusaurus-openapi-docs](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs) - A Docusaurus v2 plugin and theme for generating interactive OpenAPI docs
- [docusaurus-post-generator](https://github.com/moojing/docusaurus-post-generator) - A command line tool for user to add a blog/doc file quickly by command like `yarn gen-post new [template] [post_name]`.

## Enterprise usage \{#enterprise-usage}
## Enterprise usage {#enterprise-usage}

- Facebook
- Google
Expand Down

0 comments on commit 83064b2

Please sign in to comment.