Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow html syntax in MDX v2 with format md #8960

Merged
merged 11 commits into from
May 12, 2023
Prev Previous commit
Next Next commit
try to refactor processor
  • Loading branch information
slorber committed May 11, 2023
commit 1471118b7578baadff6bca716e73afdbfd0da2d2
137 changes: 65 additions & 72 deletions packages/docusaurus-mdx-loader/src/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ function getAdmonitionsPlugins(
return [];
}

// Esm + Node is a pain...
const modulePromise = (async () => {
// Need to be async due to ESM dynamic imports...
async function createProcessorFactory() {
const {createProcessor: createMdxProcessor} = await import('@mdx-js/mdx');
const {default: rehypeRaw} = await import('rehype-raw');
const {default: gfm} = await import('remark-gfm');
Expand Down Expand Up @@ -154,7 +154,8 @@ const modulePromise = (async () => {
});

return {
process: async ({content, filePath}) => mdxProcessor
process: async ({content, filePath}) =>
mdxProcessor
.process({
value: content,
path: filePath,
Expand All @@ -163,83 +164,75 @@ const modulePromise = (async () => {
};
}

// We use different compilers depending on the file type (md vs mdx)
type ProcessorsCacheEntry = {
mdProcessor: SimpleProcessor;
mdxProcessor: SimpleProcessor;
};

// Compilers are cached so that Remark/Rehype plugins can run
// expensive code during initialization
const ProcessorsCache = new Map<string | Options, ProcessorsCacheEntry>();

async function createProcessorsCacheEntry({
query,
reqOptions,
}: {
query: string | Options;
reqOptions: Options;
}): Promise<ProcessorsCacheEntry> {
const compilers = ProcessorsCache.get(query);
if (compilers) {
return compilers;
}

const compilerCacheEntry: ProcessorsCacheEntry = {
mdProcessor: createProcessorSync({
options: reqOptions,
format: 'md',
}),
mdxProcessor: createProcessorSync({
options: reqOptions,
format: 'mdx',
}),
};

ProcessorsCache.set(query, compilerCacheEntry);
return {createProcessorSync};
}

return compilerCacheEntry;
}
// Will be useful for tests
export async function createProcessorUncached(parameters: {
options: Options;
format: 'md' | 'mdx';
}): Promise<SimpleProcessor> {
const {createProcessorSync} = await createProcessorFactory();
return createProcessorSync(parameters);
}

async function createProcessorCachedInternal({
filePath,
mdxFrontMatter,
query,
reqOptions,
}: {
filePath: string;
mdxFrontMatter: MDXFrontMatter;
query: string | Options;
reqOptions: Options;
}): Promise<SimpleProcessor> {
const compilers = await createProcessorsCacheEntry({query, reqOptions});

const format = getFormat({
filePath,
frontMatterFormat: mdxFrontMatter.format,
});
// We use different compilers depending on the file type (md vs mdx)
type ProcessorsCacheEntry = {
mdProcessor: SimpleProcessor;
mdxProcessor: SimpleProcessor;
};

return format === 'md' ? compilers.mdProcessor : compilers.mdxProcessor;
// Compilers are cached so that Remark/Rehype plugins can run
// expensive code during initialization
const ProcessorsCache = new Map<string | Options, ProcessorsCacheEntry>();

async function createProcessorsCacheEntry({
query,
reqOptions,
}: {
query: string | Options;
reqOptions: Options;
}): Promise<ProcessorsCacheEntry> {
const {createProcessorSync} = await createProcessorFactory();

const compilers = ProcessorsCache.get(query);
if (compilers) {
return compilers;
}

return {
createProcessorSync,
createProcessorCached: createProcessorCachedInternal,
const compilerCacheEntry: ProcessorsCacheEntry = {
mdProcessor: createProcessorSync({
options: reqOptions,
format: 'md',
}),
mdxProcessor: createProcessorSync({
options: reqOptions,
format: 'mdx',
}),
};
})();

type ModuleType = Awaited<typeof modulePromise>;
type CreateProcessorSync = ModuleType['createProcessorSync'];
type CreateProcessorCached = ModuleType['createProcessorCached'];
ProcessorsCache.set(query, compilerCacheEntry);

export async function createProcessor(
...args: Parameters<CreateProcessorSync>
): Promise<ReturnType<CreateProcessorSync>> {
return (await modulePromise).createProcessorSync(...args);
return compilerCacheEntry;
}

export async function createProcessorCached(
...args: Parameters<CreateProcessorCached>
): Promise<ReturnType<CreateProcessorCached>> {
return (await modulePromise).createProcessorCached(...args);
export async function createProcessorCached({
filePath,
mdxFrontMatter,
query,
reqOptions,
}: {
filePath: string;
mdxFrontMatter: MDXFrontMatter;
query: string | Options;
reqOptions: Options;
}): Promise<SimpleProcessor> {
const compilers = await createProcessorsCacheEntry({query, reqOptions});

const format = getFormat({
filePath,
frontMatterFormat: mdxFrontMatter.format,
});

return format === 'md' ? compilers.mdProcessor : compilers.mdxProcessor;
}