mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-06 12:52:31 +02:00
feat(core): add new site config option siteConfig.markdown.anchors.maintainCase
(#10064)
Co-authored-by: Joshua Chen <sidachen2003@gmail.com> Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com> Co-authored-by: sebastien <lorber.sebastien@gmail.com>
This commit is contained in:
parent
9418786b26
commit
daba917e7c
10 changed files with 122 additions and 13 deletions
|
@ -47,11 +47,6 @@ type SimpleProcessor = {
|
|||
}) => Promise<SimpleProcessorResult>;
|
||||
};
|
||||
|
||||
async function getDefaultRemarkPlugins(): Promise<MDXPlugin[]> {
|
||||
const {default: emoji} = await import('remark-emoji');
|
||||
return [headings, emoji, toc];
|
||||
}
|
||||
|
||||
export type MDXPlugin = Pluggable;
|
||||
|
||||
export type MDXOptions = {
|
||||
|
@ -86,8 +81,18 @@ async function createProcessorFactory() {
|
|||
const {default: comment} = await import('@slorber/remark-comment');
|
||||
const {default: directive} = await import('remark-directive');
|
||||
const {VFile} = await import('vfile');
|
||||
const {default: emoji} = await import('remark-emoji');
|
||||
|
||||
const defaultRemarkPlugins = await getDefaultRemarkPlugins();
|
||||
function getDefaultRemarkPlugins({options}: {options: Options}): MDXPlugin[] {
|
||||
return [
|
||||
[
|
||||
headings,
|
||||
{anchorsMaintainCase: options.markdownConfig.anchors.maintainCase},
|
||||
],
|
||||
emoji,
|
||||
toc,
|
||||
];
|
||||
}
|
||||
|
||||
// /!\ this method is synchronous on purpose
|
||||
// Using async code here can create cache entry race conditions!
|
||||
|
@ -104,7 +109,7 @@ async function createProcessorFactory() {
|
|||
directive,
|
||||
[contentTitle, {removeContentTitle: options.removeContentTitle}],
|
||||
...getAdmonitionsPlugins(options.admonitions ?? false),
|
||||
...defaultRemarkPlugins,
|
||||
...getDefaultRemarkPlugins({options}),
|
||||
details,
|
||||
head,
|
||||
...(options.markdownConfig.mermaid ? [mermaid] : []),
|
||||
|
|
|
@ -11,13 +11,20 @@ import u from 'unist-builder';
|
|||
import {removePosition} from 'unist-util-remove-position';
|
||||
import {toString} from 'mdast-util-to-string';
|
||||
import {visit} from 'unist-util-visit';
|
||||
import slug from '../index';
|
||||
import plugin from '../index';
|
||||
import type {PluginOptions} from '../index';
|
||||
import type {Plugin} from 'unified';
|
||||
import type {Parent} from 'unist';
|
||||
|
||||
async function process(doc: string, plugins: Plugin[] = []) {
|
||||
async function process(
|
||||
doc: string,
|
||||
plugins: Plugin[] = [],
|
||||
options: PluginOptions = {anchorsMaintainCase: false},
|
||||
) {
|
||||
const {remark} = await import('remark');
|
||||
const processor = await remark().use({plugins: [...plugins, slug]});
|
||||
const processor = await remark().use({
|
||||
plugins: [...plugins, [plugin, options]],
|
||||
});
|
||||
const result = await processor.run(processor.parse(doc));
|
||||
removePosition(result, {force: true});
|
||||
return result;
|
||||
|
@ -312,4 +319,25 @@ describe('headings remark plugin', () => {
|
|||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('preserve anchors case then "anchorsMaintainCase" option is set', async () => {
|
||||
const result = await process('# Case Sensitive Heading', [], {
|
||||
anchorsMaintainCase: true,
|
||||
});
|
||||
const expected = u('root', [
|
||||
u(
|
||||
'heading',
|
||||
{
|
||||
depth: 1,
|
||||
data: {
|
||||
hProperties: {id: 'Case-Sensitive-Heading'},
|
||||
id: 'Case-Sensitive-Heading',
|
||||
},
|
||||
},
|
||||
[u('text', 'Case Sensitive Heading')],
|
||||
),
|
||||
]);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,7 +12,13 @@ import {parseMarkdownHeadingId, createSlugger} from '@docusaurus/utils';
|
|||
import type {Transformer} from 'unified';
|
||||
import type {Heading, Text} from 'mdast';
|
||||
|
||||
export default function plugin(): Transformer {
|
||||
export interface PluginOptions {
|
||||
anchorsMaintainCase: boolean;
|
||||
}
|
||||
|
||||
export default function plugin({
|
||||
anchorsMaintainCase,
|
||||
}: PluginOptions): Transformer {
|
||||
return async (root) => {
|
||||
const {toString} = await import('mdast-util-to-string');
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
@ -38,7 +44,9 @@ export default function plugin(): Transformer {
|
|||
// Support explicit heading IDs
|
||||
const parsedHeading = parseMarkdownHeadingId(heading);
|
||||
|
||||
id = parsedHeading.id ?? slugs.slug(heading);
|
||||
id =
|
||||
parsedHeading.id ??
|
||||
slugs.slug(heading, {maintainCase: anchorsMaintainCase});
|
||||
|
||||
if (parsedHeading.id) {
|
||||
// When there's an id, it is always in the last child node
|
||||
|
|
|
@ -25,7 +25,7 @@ const processFixture = async (name: string) => {
|
|||
|
||||
const result = await compile(file, {
|
||||
format: 'mdx',
|
||||
remarkPlugins: [headings, gfm, plugin],
|
||||
remarkPlugins: [[headings, {anchorsMaintainCase: false}], gfm, plugin],
|
||||
rehypePlugins: [],
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue