mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Core: Support MDX preset
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
Support MDX preset in Fumadocs Core
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import type * as Plugins from '@/mdx-plugins';
|
||||
import { resolvePlugins, type ResolvePlugins } from '@/content/mdx/util';
|
||||
|
||||
export type MDXBundlerPresetOptions = Omit<
|
||||
NonNullable<ProcessorOptions>,
|
||||
'rehypePlugins' | 'remarkPlugins'
|
||||
> & {
|
||||
rehypePlugins?: ResolvePlugins;
|
||||
remarkPlugins?: ResolvePlugins;
|
||||
|
||||
remarkStructureOptions?: Plugins.StructureOptions | false;
|
||||
remarkHeadingOptions?: Plugins.RemarkHeadingOptions;
|
||||
remarkImageOptions?: Plugins.RemarkImageOptions | false;
|
||||
remarkCodeTabOptions?: Plugins.RemarkCodeTabOptions | false;
|
||||
remarkNpmOptions?: Plugins.RemarkNpmOptions | false;
|
||||
rehypeCodeOptions?: Plugins.RehypeCodeOptions | false;
|
||||
};
|
||||
|
||||
/**
|
||||
* apply MDX processor presets
|
||||
*/
|
||||
export async function mdxPreset(
|
||||
options: MDXBundlerPresetOptions = {},
|
||||
): Promise<ProcessorOptions> {
|
||||
const {
|
||||
rehypeCodeOptions,
|
||||
remarkImageOptions,
|
||||
remarkHeadingOptions,
|
||||
remarkStructureOptions,
|
||||
remarkCodeTabOptions,
|
||||
remarkNpmOptions,
|
||||
...mdxOptions
|
||||
} = options;
|
||||
|
||||
const remarkPlugins = await resolvePlugins(
|
||||
(v) => [
|
||||
import('remark-gfm').then((mod) => mod.default),
|
||||
import('@/mdx-plugins/remark-heading').then((mod) => [
|
||||
mod.remarkHeading,
|
||||
{
|
||||
generateToc: false,
|
||||
...remarkHeadingOptions,
|
||||
},
|
||||
]),
|
||||
remarkImageOptions !== false &&
|
||||
import('@/mdx-plugins/remark-image').then((mod) => [
|
||||
mod.remarkImage,
|
||||
{
|
||||
...remarkImageOptions,
|
||||
useImport: remarkImageOptions?.useImport ?? true,
|
||||
},
|
||||
]),
|
||||
remarkCodeTabOptions !== false &&
|
||||
import('@/mdx-plugins/remark-code-tab').then((mod) => [
|
||||
mod.remarkCodeTab,
|
||||
remarkCodeTabOptions,
|
||||
]),
|
||||
remarkNpmOptions !== false &&
|
||||
import('@/mdx-plugins/remark-npm').then((mod) => [
|
||||
mod.remarkNpm,
|
||||
remarkNpmOptions,
|
||||
]),
|
||||
...v,
|
||||
remarkStructureOptions !== false &&
|
||||
import('@/mdx-plugins/remark-structure').then((mod) => [
|
||||
mod.remarkStructure,
|
||||
{
|
||||
exportAs: 'structuredData',
|
||||
...remarkStructureOptions,
|
||||
} satisfies Plugins.StructureOptions,
|
||||
]),
|
||||
],
|
||||
mdxOptions.remarkPlugins,
|
||||
);
|
||||
|
||||
const rehypePlugins = await resolvePlugins(
|
||||
(v) => [
|
||||
rehypeCodeOptions !== false &&
|
||||
import('@/mdx-plugins/rehype-code').then((mod) => [
|
||||
mod.rehypeCode,
|
||||
rehypeCodeOptions,
|
||||
]),
|
||||
...v,
|
||||
import('@/mdx-plugins/rehype-toc').then((mod) => mod.rehypeToc),
|
||||
],
|
||||
mdxOptions.rehypePlugins,
|
||||
);
|
||||
|
||||
return {
|
||||
...mdxOptions,
|
||||
remarkPlugins,
|
||||
rehypePlugins,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import type { ProcessorOptions } from '@mdx-js/mdx';
|
||||
import type * as Plugins from '@/mdx-plugins';
|
||||
import { resolvePlugins, type ResolvePlugins } from '@/content/mdx/util';
|
||||
|
||||
export type MDXRuntimePresetOptions = Omit<
|
||||
NonNullable<ProcessorOptions>,
|
||||
'rehypePlugins' | 'remarkPlugins'
|
||||
> & {
|
||||
rehypePlugins?: ResolvePlugins;
|
||||
remarkPlugins?: ResolvePlugins;
|
||||
|
||||
remarkStructureOptions?: Plugins.StructureOptions | false;
|
||||
remarkHeadingOptions?: Plugins.RemarkHeadingOptions;
|
||||
remarkImageOptions?: Plugins.RemarkImageOptions | false;
|
||||
remarkCodeTabOptions?: Plugins.RemarkCodeTabOptions | false;
|
||||
remarkNpmOptions?: Plugins.RemarkNpmOptions | false;
|
||||
rehypeCodeOptions?: Plugins.RehypeCodeOptions | false;
|
||||
};
|
||||
|
||||
/**
|
||||
* apply MDX processor presets
|
||||
*/
|
||||
export async function mdxPreset(
|
||||
options: MDXRuntimePresetOptions = {},
|
||||
): Promise<ProcessorOptions> {
|
||||
const {
|
||||
rehypeCodeOptions,
|
||||
remarkImageOptions,
|
||||
remarkHeadingOptions,
|
||||
remarkStructureOptions,
|
||||
remarkCodeTabOptions,
|
||||
remarkNpmOptions,
|
||||
outputFormat = 'function-body',
|
||||
...mdxOptions
|
||||
} = options;
|
||||
|
||||
const remarkPlugins = await resolvePlugins(
|
||||
(v) => [
|
||||
import('remark-gfm').then((mod) => mod.default),
|
||||
import('@/mdx-plugins/remark-heading').then((mod) => [
|
||||
mod.remarkHeading,
|
||||
{
|
||||
generateToc: false,
|
||||
...remarkHeadingOptions,
|
||||
},
|
||||
]),
|
||||
remarkImageOptions !== false &&
|
||||
import('@/mdx-plugins/remark-image').then((mod) => [
|
||||
mod.remarkImage,
|
||||
remarkImageOptions,
|
||||
]),
|
||||
remarkCodeTabOptions !== false &&
|
||||
import('@/mdx-plugins/remark-code-tab').then((mod) => [
|
||||
mod.remarkCodeTab,
|
||||
remarkCodeTabOptions,
|
||||
]),
|
||||
remarkNpmOptions !== false &&
|
||||
import('@/mdx-plugins/remark-npm').then((mod) => [
|
||||
mod.remarkNpm,
|
||||
remarkNpmOptions,
|
||||
]),
|
||||
...v,
|
||||
remarkStructureOptions !== false &&
|
||||
import('@/mdx-plugins/remark-structure').then((mod) => [
|
||||
mod.remarkStructure,
|
||||
{
|
||||
exportAs: 'structuredData',
|
||||
...remarkStructureOptions,
|
||||
} satisfies Plugins.StructureOptions,
|
||||
]),
|
||||
],
|
||||
mdxOptions.remarkPlugins,
|
||||
);
|
||||
|
||||
const rehypePlugins = await resolvePlugins(
|
||||
(v) => [
|
||||
rehypeCodeOptions !== false &&
|
||||
import('@/mdx-plugins/rehype-code').then((mod) => [
|
||||
mod.rehypeCode,
|
||||
rehypeCodeOptions,
|
||||
]),
|
||||
...v,
|
||||
import('@/mdx-plugins/rehype-toc').then((mod) => mod.rehypeToc),
|
||||
],
|
||||
mdxOptions.rehypePlugins,
|
||||
);
|
||||
|
||||
return {
|
||||
...mdxOptions,
|
||||
outputFormat,
|
||||
remarkPlugins,
|
||||
rehypePlugins,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { Pluggable } from 'unified';
|
||||
|
||||
type Thenable<T> = T | PromiseLike<T>;
|
||||
|
||||
export type ResolvePlugins =
|
||||
| Thenable<Pluggable>[]
|
||||
| ((v: Pluggable[]) => Thenable<Pluggable>[]);
|
||||
|
||||
export async function resolvePlugins(
|
||||
def: (v: Thenable<Pluggable>[]) => Thenable<Pluggable | false>[],
|
||||
options: ResolvePlugins = [],
|
||||
): Promise<Pluggable[]> {
|
||||
const list = (
|
||||
await Promise.all(def(Array.isArray(options) ? options : []))
|
||||
).filter((v) => v !== false);
|
||||
|
||||
if (typeof options === 'function') {
|
||||
return Promise.all(options(list));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ export default defineConfig({
|
||||
'src/{toc,link,breadcrumb,dynamic-link}.tsx',
|
||||
'src/page-tree/index.ts',
|
||||
'src/{negotiation,content}/*',
|
||||
'src/content/mdx/preset-*.ts',
|
||||
'src/source/{index,schema}.ts',
|
||||
'src/source/client/*.{ts,tsx}',
|
||||
'src/source/plugins/lucide-icons.ts',
|
||||
|
||||
Reference in New Issue
Block a user