feat(mdx-loader): add support for siteConfig.markdown.remarkRehypeOptions (#9674)

This commit is contained in:
Sébastien Lorber 2023-12-27 23:19:25 +01:00 committed by GitHub
parent bd7d64f455
commit bfb882c2f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 47 additions and 1 deletions

View file

@ -165,6 +165,7 @@ async function createProcessorFactory() {
const mdxProcessor = createMdxProcessor({ const mdxProcessor = createMdxProcessor({
...processorOptions, ...processorOptions,
remarkRehypeOptions: options.markdownConfig.remarkRehypeOptions,
format, format,
}); });

View file

@ -13,6 +13,7 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11", "@types/history": "^4.7.11",
"@types/react": "*", "@types/react": "*",
"commander": "^5.1.0", "commander": "^5.1.0",

View file

@ -10,6 +10,10 @@ import type {Required as RequireKeys, DeepPartial} from 'utility-types';
import type {I18nConfig} from './i18n'; import type {I18nConfig} from './i18n';
import type {PluginConfig, PresetConfig, HtmlTagObject} from './plugin'; import type {PluginConfig, PresetConfig, HtmlTagObject} from './plugin';
import type {ProcessorOptions} from '@mdx-js/mdx';
export type RemarkRehypeOptions = ProcessorOptions['remarkRehypeOptions'];
export type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'throw'; export type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'throw';
export type ThemeConfig = { export type ThemeConfig = {
@ -91,6 +95,12 @@ export type MarkdownConfig = {
* See also https://github.com/facebook/docusaurus/issues/4029 * See also https://github.com/facebook/docusaurus/issues/4029
*/ */
mdx1Compat: MDX1CompatOptions; mdx1Compat: MDX1CompatOptions;
/**
* Ability to provide custom remark-rehype options
* See also https://github.com/remarkjs/remark-rehype#options
*/
remarkRehypeOptions: RemarkRehypeOptions;
}; };
/** /**

View file

@ -26,6 +26,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -75,6 +76,7 @@ exports[`loadSiteConfig website with ts + js config 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -124,6 +126,7 @@ exports[`loadSiteConfig website with valid JS CJS config 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -173,6 +176,7 @@ exports[`loadSiteConfig website with valid JS ESM config 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -222,6 +226,7 @@ exports[`loadSiteConfig website with valid TypeScript CJS config 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -271,6 +276,7 @@ exports[`loadSiteConfig website with valid TypeScript ESM config 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -320,6 +326,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -371,6 +378,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -422,6 +430,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",
@ -476,6 +485,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",

View file

@ -100,6 +100,7 @@ exports[`load loads props for site with custom i18n path 1`] = `
"mermaid": false, "mermaid": false,
"parseFrontMatter": [Function], "parseFrontMatter": [Function],
"preprocessor": undefined, "preprocessor": undefined,
"remarkRehypeOptions": undefined,
}, },
"noIndex": false, "noIndex": false,
"onBrokenLinks": "throw", "onBrokenLinks": "throw",

View file

@ -69,6 +69,9 @@ describe('normalizeConfig', () => {
admonitions: false, admonitions: false,
headingIds: true, headingIds: true,
}, },
remarkRehypeOptions: {
footnoteLabel: 'Pied de page',
},
}, },
}; };
const normalizedConfig = normalizeConfig(userConfig); const normalizedConfig = normalizeConfig(userConfig);
@ -514,6 +517,11 @@ describe('markdown', () => {
admonitions: true, admonitions: true,
headingIds: false, headingIds: false,
}, },
remarkRehypeOptions: {
footnoteLabel: 'Notes de bas de page',
// @ts-expect-error: we don't validate it on purpose
anyKey: 'heck we accept it on purpose',
},
}; };
expect( expect(
normalizeConfig({ normalizeConfig({

View file

@ -39,6 +39,7 @@ export const DEFAULT_MARKDOWN_CONFIG: MarkdownConfig = {
admonitions: true, admonitions: true,
headingIds: true, headingIds: true,
}, },
remarkRehypeOptions: undefined,
}; };
export const DEFAULT_CONFIG: Pick< export const DEFAULT_CONFIG: Pick<
@ -307,6 +308,11 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
DEFAULT_CONFIG.markdown.mdx1Compat.headingIds, DEFAULT_CONFIG.markdown.mdx1Compat.headingIds,
), ),
}).default(DEFAULT_CONFIG.markdown.mdx1Compat), }).default(DEFAULT_CONFIG.markdown.mdx1Compat),
remarkRehypeOptions:
// add proper external options validation?
// Not sure if it's a good idea, validation is likely to become stale
// See https://github.com/remarkjs/remark-rehype#options
Joi.object().unknown(),
}).default(DEFAULT_CONFIG.markdown), }).default(DEFAULT_CONFIG.markdown),
}).messages({ }).messages({
'docusaurus.configValidationWarning': 'docusaurus.configValidationWarning':

View file

@ -436,6 +436,7 @@ type MarkdownConfig = {
preprocessor?: MarkdownPreprocessor; preprocessor?: MarkdownPreprocessor;
parseFrontMatter?: ParseFrontMatter; parseFrontMatter?: ParseFrontMatter;
mdx1Compat: MDX1CompatOptions; mdx1Compat: MDX1CompatOptions;
remarkRehypeOptions: object; // see https://github.com/remarkjs/remark-rehype#options
}; };
``` ```
@ -475,6 +476,7 @@ export default {
| `preprocessor` | `MarkdownPreprocessor` | `undefined` | Gives you the ability to alter the Markdown content string before parsing. Use it as a last-resort escape hatch or workaround: it is almost always better to implement a Remark/Rehype plugin. | | `preprocessor` | `MarkdownPreprocessor` | `undefined` | Gives you the ability to alter the Markdown content string before parsing. Use it as a last-resort escape hatch or workaround: it is almost always better to implement a Remark/Rehype plugin. |
| `parseFrontMatter` | `ParseFrontMatter` | `undefined` | Gives you the ability to provide your own front matter parser, or to enhance the default parser. Read our [front matter guide](../guides/markdown-features/markdown-features-intro.mdx#front-matter) for details. | | `parseFrontMatter` | `ParseFrontMatter` | `undefined` | Gives you the ability to provide your own front matter parser, or to enhance the default parser. Read our [front matter guide](../guides/markdown-features/markdown-features-intro.mdx#front-matter) for details. |
| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. | | `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. |
| `remarkRehypeOptions` | `object` | `undefined` | Makes it possible to pass custom [`remark-rehype` options](https://github.com/remarkjs/remark-rehype#options). |
```mdx-code-block ```mdx-code-block
</APITable> </APITable>

View file

@ -2,5 +2,9 @@
"tagline": { "tagline": {
"en": "Build optimized websites quickly, focus on your content", "en": "Build optimized websites quickly, focus on your content",
"fr": "Construisez rapidement des sites web optimisés, concentrez-vous sur votre contenu" "fr": "Construisez rapidement des sites web optimisés, concentrez-vous sur votre contenu"
},
"remarkRehypeOptions_footnotes": {
"en": "Footnotes",
"fr": "Notes de bas de page"
} }
} }

View file

@ -102,7 +102,7 @@ const TwitterSvg =
const defaultLocale = 'en'; const defaultLocale = 'en';
function getLocalizedConfigValue(key: string) { function getLocalizedConfigValue(key: keyof typeof ConfigLocalized) {
const currentLocale = process.env.DOCUSAURUS_CURRENT_LOCALE ?? defaultLocale; const currentLocale = process.env.DOCUSAURUS_CURRENT_LOCALE ?? defaultLocale;
const values = ConfigLocalized[key]; const values = ConfigLocalized[key];
if (!values) { if (!values) {
@ -177,6 +177,9 @@ export default async function createConfigAsync() {
mdx1Compat: { mdx1Compat: {
// comments: false, // comments: false,
}, },
remarkRehypeOptions: {
footnoteLabel: getLocalizedConfigValue('remarkRehypeOptions_footnotes'),
},
parseFrontMatter: async (params) => { parseFrontMatter: async (params) => {
const result = await params.defaultParseFrontMatter(params); const result = await params.defaultParseFrontMatter(params);
return { return {