feat(mdx): support recma plugins (#10241)

This commit is contained in:
Sébastien Lorber 2024-06-21 19:25:32 +02:00 committed by GitHub
parent 4ad425a88f
commit cc506c8950
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 45 additions and 0 deletions

View file

@ -54,6 +54,7 @@ export type MDXOptions = {
admonitions: boolean | Partial<AdmonitionOptions>; admonitions: boolean | Partial<AdmonitionOptions>;
remarkPlugins: MDXPlugin[]; remarkPlugins: MDXPlugin[];
rehypePlugins: MDXPlugin[]; rehypePlugins: MDXPlugin[];
recmaPlugins: MDXPlugin[];
beforeDefaultRemarkPlugins: MDXPlugin[]; beforeDefaultRemarkPlugins: MDXPlugin[];
beforeDefaultRehypePlugins: MDXPlugin[]; beforeDefaultRehypePlugins: MDXPlugin[];
}; };
@ -150,6 +151,10 @@ async function createProcessorFactory() {
...(options.rehypePlugins ?? []), ...(options.rehypePlugins ?? []),
]; ];
// Maybe we'll want to introduce default recma plugins later?
// For example https://github.com/domdomegg/recma-mdx-displayname ?
const recmaPlugins = [...(options.recmaPlugins ?? [])];
if (format === 'md') { if (format === 'md') {
// This is what permits to embed HTML elements with format 'md' // This is what permits to embed HTML elements with format 'md'
// See https://github.com/facebook/docusaurus/pull/8960 // See https://github.com/facebook/docusaurus/pull/8960
@ -173,6 +178,7 @@ async function createProcessorFactory() {
...options, ...options,
remarkPlugins, remarkPlugins,
rehypePlugins, rehypePlugins,
recmaPlugins,
providerImportSource: '@mdx-js/react', providerImportSource: '@mdx-js/react',
}; };

View file

@ -63,6 +63,7 @@ describe('validateOptions', () => {
markdownPluginsObjectStub, markdownPluginsObjectStub,
[markdownPluginsFunctionStub, {option1: '42'}], [markdownPluginsFunctionStub, {option1: '42'}],
], ],
recmaPlugins: [markdownPluginsFunctionStub],
}; };
expect(testValidate(userOptions)).toEqual(userOptions); expect(testValidate(userOptions)).toEqual(userOptions);
}); });

View file

@ -250,6 +250,7 @@ export default async function pluginContentBlog(
admonitions, admonitions,
rehypePlugins, rehypePlugins,
remarkPlugins, remarkPlugins,
recmaPlugins,
truncateMarker, truncateMarker,
beforeDefaultRemarkPlugins, beforeDefaultRemarkPlugins,
beforeDefaultRehypePlugins, beforeDefaultRehypePlugins,
@ -262,6 +263,7 @@ export default async function pluginContentBlog(
admonitions, admonitions,
remarkPlugins, remarkPlugins,
rehypePlugins, rehypePlugins,
recmaPlugins,
beforeDefaultRemarkPlugins: [ beforeDefaultRemarkPlugins: [
footnoteIDFixer, footnoteIDFixer,
...beforeDefaultRemarkPlugins, ...beforeDefaultRemarkPlugins,

View file

@ -9,6 +9,7 @@ import {
Joi, Joi,
RemarkPluginsSchema, RemarkPluginsSchema,
RehypePluginsSchema, RehypePluginsSchema,
RecmaPluginsSchema,
AdmonitionsSchema, AdmonitionsSchema,
RouteBasePathSchema, RouteBasePathSchema,
URISchema, URISchema,
@ -29,6 +30,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
truncateMarker: /<!--\s*truncate\s*-->|\{\/\*\s*truncate\s*\*\/\}/, truncateMarker: /<!--\s*truncate\s*-->|\{\/\*\s*truncate\s*\*\/\}/,
rehypePlugins: [], rehypePlugins: [],
remarkPlugins: [], remarkPlugins: [],
recmaPlugins: [],
showReadingTime: true, showReadingTime: true,
blogTagsPostsComponent: '@theme/BlogTagsPostsPage', blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
blogTagsListComponent: '@theme/BlogTagsListPage', blogTagsListComponent: '@theme/BlogTagsListPage',
@ -93,6 +95,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
showReadingTime: Joi.bool().default(DEFAULT_OPTIONS.showReadingTime), showReadingTime: Joi.bool().default(DEFAULT_OPTIONS.showReadingTime),
remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins), remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins),
rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins), rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins),
recmaPlugins: RecmaPluginsSchema.default(DEFAULT_OPTIONS.recmaPlugins),
admonitions: AdmonitionsSchema.default(DEFAULT_OPTIONS.admonitions), admonitions: AdmonitionsSchema.default(DEFAULT_OPTIONS.admonitions),
editUrl: Joi.alternatives().try(URISchema, Joi.function()), editUrl: Joi.alternatives().try(URISchema, Joi.function()),
editLocalizedFiles: Joi.boolean().default(DEFAULT_OPTIONS.editLocalizedFiles), editLocalizedFiles: Joi.boolean().default(DEFAULT_OPTIONS.editLocalizedFiles),

View file

@ -60,6 +60,7 @@ describe('normalizeDocsPluginOptions', () => {
// @ts-expect-error: it seems to work in practice? // @ts-expect-error: it seems to work in practice?
remarkPlugins: [markdownPluginsObjectStub], remarkPlugins: [markdownPluginsObjectStub],
rehypePlugins: [markdownPluginsFunctionStub], rehypePlugins: [markdownPluginsFunctionStub],
recmaPlugins: [markdownPluginsFunctionStub],
beforeDefaultRehypePlugins: [], beforeDefaultRehypePlugins: [],
beforeDefaultRemarkPlugins: [], beforeDefaultRemarkPlugins: [],
breadcrumbs: true, breadcrumbs: true,

View file

@ -293,6 +293,7 @@ export default async function pluginContentDocs(
const { const {
rehypePlugins, rehypePlugins,
remarkPlugins, remarkPlugins,
recmaPlugins,
beforeDefaultRehypePlugins, beforeDefaultRehypePlugins,
beforeDefaultRemarkPlugins, beforeDefaultRemarkPlugins,
} = options; } = options;
@ -307,6 +308,7 @@ export default async function pluginContentDocs(
admonitions: options.admonitions, admonitions: options.admonitions,
remarkPlugins, remarkPlugins,
rehypePlugins, rehypePlugins,
recmaPlugins,
beforeDefaultRehypePlugins, beforeDefaultRehypePlugins,
beforeDefaultRemarkPlugins, beforeDefaultRemarkPlugins,
staticDirs: siteConfig.staticDirectories.map((dir) => staticDirs: siteConfig.staticDirectories.map((dir) =>

View file

@ -10,6 +10,7 @@ import {
Joi, Joi,
RemarkPluginsSchema, RemarkPluginsSchema,
RehypePluginsSchema, RehypePluginsSchema,
RecmaPluginsSchema,
AdmonitionsSchema, AdmonitionsSchema,
RouteBasePathSchema, RouteBasePathSchema,
URISchema, URISchema,
@ -40,6 +41,7 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
docCategoryGeneratedIndexComponent: '@theme/DocCategoryGeneratedIndexPage', docCategoryGeneratedIndexComponent: '@theme/DocCategoryGeneratedIndexPage',
remarkPlugins: [], remarkPlugins: [],
rehypePlugins: [], rehypePlugins: [],
recmaPlugins: [],
beforeDefaultRemarkPlugins: [], beforeDefaultRemarkPlugins: [],
beforeDefaultRehypePlugins: [], beforeDefaultRehypePlugins: [],
showLastUpdateTime: false, showLastUpdateTime: false,
@ -123,6 +125,7 @@ const OptionsSchema = Joi.object<PluginOptions>({
), ),
remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins), remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins),
rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins), rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins),
recmaPlugins: RecmaPluginsSchema.default(DEFAULT_OPTIONS.recmaPlugins),
beforeDefaultRemarkPlugins: RemarkPluginsSchema.default( beforeDefaultRemarkPlugins: RemarkPluginsSchema.default(
DEFAULT_OPTIONS.beforeDefaultRemarkPlugins, DEFAULT_OPTIONS.beforeDefaultRemarkPlugins,
), ),

View file

@ -72,6 +72,7 @@ export default function pluginContentPages(
admonitions, admonitions,
rehypePlugins, rehypePlugins,
remarkPlugins, remarkPlugins,
recmaPlugins,
beforeDefaultRehypePlugins, beforeDefaultRehypePlugins,
beforeDefaultRemarkPlugins, beforeDefaultRemarkPlugins,
} = options; } = options;
@ -82,6 +83,7 @@ export default function pluginContentPages(
admonitions, admonitions,
remarkPlugins, remarkPlugins,
rehypePlugins, rehypePlugins,
recmaPlugins,
beforeDefaultRehypePlugins, beforeDefaultRehypePlugins,
beforeDefaultRemarkPlugins, beforeDefaultRemarkPlugins,
staticDirs: siteConfig.staticDirectories.map((dir) => staticDirs: siteConfig.staticDirectories.map((dir) =>

View file

@ -9,6 +9,7 @@ import {
Joi, Joi,
RemarkPluginsSchema, RemarkPluginsSchema,
RehypePluginsSchema, RehypePluginsSchema,
RecmaPluginsSchema,
AdmonitionsSchema, AdmonitionsSchema,
RouteBasePathSchema, RouteBasePathSchema,
URISchema, URISchema,
@ -25,6 +26,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
mdxPageComponent: '@theme/MDXPage', mdxPageComponent: '@theme/MDXPage',
remarkPlugins: [], remarkPlugins: [],
rehypePlugins: [], rehypePlugins: [],
recmaPlugins: [],
beforeDefaultRehypePlugins: [], beforeDefaultRehypePlugins: [],
beforeDefaultRemarkPlugins: [], beforeDefaultRemarkPlugins: [],
admonitions: true, admonitions: true,
@ -41,6 +43,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
mdxPageComponent: Joi.string().default(DEFAULT_OPTIONS.mdxPageComponent), mdxPageComponent: Joi.string().default(DEFAULT_OPTIONS.mdxPageComponent),
remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins), remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins),
rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins), rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins),
recmaPlugins: RecmaPluginsSchema.default(DEFAULT_OPTIONS.recmaPlugins),
beforeDefaultRehypePlugins: RehypePluginsSchema.default( beforeDefaultRehypePlugins: RehypePluginsSchema.default(
DEFAULT_OPTIONS.beforeDefaultRehypePlugins, DEFAULT_OPTIONS.beforeDefaultRehypePlugins,
), ),

View file

@ -19,6 +19,7 @@ export {
PluginIdSchema, PluginIdSchema,
RemarkPluginsSchema, RemarkPluginsSchema,
RehypePluginsSchema, RehypePluginsSchema,
RecmaPluginsSchema,
AdmonitionsSchema, AdmonitionsSchema,
RouteBasePathSchema, RouteBasePathSchema,
URISchema, URISchema,

View file

@ -36,6 +36,7 @@ const MarkdownPluginsSchema = Joi.array()
export const RemarkPluginsSchema = MarkdownPluginsSchema; export const RemarkPluginsSchema = MarkdownPluginsSchema;
export const RehypePluginsSchema = MarkdownPluginsSchema; export const RehypePluginsSchema = MarkdownPluginsSchema;
export const RecmaPluginsSchema = MarkdownPluginsSchema;
export const AdmonitionsSchema = JoiFrontMatter.alternatives() export const AdmonitionsSchema = JoiFrontMatter.alternatives()
.try( .try(

View file

@ -284,6 +284,8 @@ rachelnabors
Ramón Ramón
reactjs reactjs
rearchitecture rearchitecture
recma
Recma
recrawl recrawl
redirections redirections
Redoc Redoc

View file

@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import path from 'path';
import RecmaMDXDisplayName from 'recma-mdx-displayname';
import type {PluginConfig, Plugin} from '@docusaurus/types'; import type {PluginConfig, Plugin} from '@docusaurus/types';
import type {Options as DocsOptions} from '@docusaurus/plugin-content-docs'; import type {Options as DocsOptions} from '@docusaurus/plugin-content-docs';
import type {Options as BlogOptions} from '@docusaurus/plugin-content-blog'; import type {Options as BlogOptions} from '@docusaurus/plugin-content-blog';
@ -42,6 +44,13 @@ export const dogfoodingPluginInstances: PluginConfig[] = [
}, },
onInlineTags: 'warn', onInlineTags: 'warn',
tags: 'tags.yml', tags: 'tags.yml',
recmaPlugins: [
[
RecmaMDXDisplayName,
(vfile: {path: string}) =>
`MDXContent(${path.relative(process.cwd(), vfile.path)})`,
],
],
// Using a _ prefix to test against an edge case regarding MDX partials: https://github.com/facebook/docusaurus/discussions/5181#discussioncomment-1018079 // Using a _ prefix to test against an edge case regarding MDX partials: https://github.com/facebook/docusaurus/discussions/5181#discussioncomment-1018079
path: '_dogfooding/_docs tests', path: '_dogfooding/_docs tests',

View file

@ -60,6 +60,7 @@ Accepted fields:
| `blogArchiveComponent` | `string` | `'@theme/BlogArchivePage'` | Root component of the blog archive page. | | `blogArchiveComponent` | `string` | `'@theme/BlogArchivePage'` | Root component of the blog archive page. |
| `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. | | `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. |
| `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. | | `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. |
| `rehypePlugins` | `any[]` | `[]` | Recma plugins passed to MDX. |
| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | | `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. |
| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | | `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. |
| `truncateMarker` | `RegExp` | `/<!--\s*truncate\s*-->/` \| `\{\/\*\s*truncate\s*\*\/\}/` | Truncate marker marking where the summary ends. | | `truncateMarker` | `RegExp` | `/<!--\s*truncate\s*-->/` \| `\{\/\*\s*truncate\s*\*\/\}/` | Truncate marker marking where the summary ends. |

View file

@ -55,6 +55,7 @@ Accepted fields:
| `docCategoryGeneratedIndexComponent` | `string` | `'@theme/DocCategoryGeneratedIndexPage'` | Root component of the generated category index page. | | `docCategoryGeneratedIndexComponent` | `string` | `'@theme/DocCategoryGeneratedIndexPage'` | Root component of the generated category index page. |
| `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. | | `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. |
| `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. | | `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. |
| `rehypePlugins` | `any[]` | `[]` | Recma plugins passed to MDX. |
| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | | `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. |
| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | | `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. |
| `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the doc. | | `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the doc. |

View file

@ -42,6 +42,7 @@ Accepted fields:
| `mdxPageComponent` | `string` | `'@theme/MDXPage'` | Component used by each MDX page. | | `mdxPageComponent` | `string` | `'@theme/MDXPage'` | Component used by each MDX page. |
| `remarkPlugins` | `[]` | `any[]` | Remark plugins passed to MDX. | | `remarkPlugins` | `[]` | `any[]` | Remark plugins passed to MDX. |
| `rehypePlugins` | `[]` | `any[]` | Rehype plugins passed to MDX. | | `rehypePlugins` | `[]` | `any[]` | Rehype plugins passed to MDX. |
| `rehypePlugins` | `any[]` | `[]` | Recma plugins passed to MDX. |
| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | | `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. |
| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | | `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. |
| `showLastUpdateAuthor` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the author who last updated the page. | | `showLastUpdateAuthor` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the author who last updated the page. |

View file

@ -60,6 +60,7 @@
"react-dom": "^18.0.0", "react-dom": "^18.0.0",
"react-lite-youtube-embed": "^2.3.52", "react-lite-youtube-embed": "^2.3.52",
"react-medium-image-zoom": "^5.1.6", "react-medium-image-zoom": "^5.1.6",
"recma-mdx-displayname": "^0.4.1",
"rehype-katex": "^7.0.0", "rehype-katex": "^7.0.0",
"remark-math": "^6.0.0", "remark-math": "^6.0.0",
"swc-loader": "^0.2.3", "swc-loader": "^0.2.3",

View file

@ -14055,6 +14055,11 @@ rechoir@^0.6.2:
dependencies: dependencies:
resolve "^1.1.6" resolve "^1.1.6"
recma-mdx-displayname@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/recma-mdx-displayname/-/recma-mdx-displayname-0.4.1.tgz#45ba59d2ac573795233d20a0bda1c2f03e85e301"
integrity sha512-2apUFDEAiqkz4QmQboOVrLdvWyyR5dC6Is4S4gwxCFxznNfDk+W4bNBWK+9oWUO91olFZg7Edd7Lw5XkRTOuRQ==
recursive-readdir@^2.2.2: recursive-readdir@^2.2.2:
version "2.2.3" version "2.2.3"
resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372"