mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-22 19:17:46 +02:00
feat(mdx): add siteConfig.markdown.format to configure the default content parser (MDX / CommonMark) (#9097)
This commit is contained in:
parent
be4e67caa9
commit
cc6d9696f0
21 changed files with 304 additions and 83 deletions
|
@ -9,44 +9,126 @@ import {getFormat} from '../format';
|
|||
|
||||
describe('getFormat', () => {
|
||||
it('uses frontMatter format over anything else', () => {
|
||||
expect(getFormat({frontMatterFormat: 'md', filePath: 'xyz.md'})).toBe('md');
|
||||
expect(getFormat({frontMatterFormat: 'md', filePath: 'xyz.mdx'})).toBe(
|
||||
'md',
|
||||
);
|
||||
expect(getFormat({frontMatterFormat: 'mdx', filePath: 'xyz.md'})).toBe(
|
||||
'mdx',
|
||||
);
|
||||
expect(getFormat({frontMatterFormat: 'mdx', filePath: 'xyz.mdx'})).toBe(
|
||||
'mdx',
|
||||
);
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: 'md',
|
||||
filePath: 'xyz.md',
|
||||
markdownConfigFormat: 'mdx',
|
||||
}),
|
||||
).toBe('md');
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: 'md',
|
||||
filePath: 'xyz.mdx',
|
||||
markdownConfigFormat: 'mdx',
|
||||
}),
|
||||
).toBe('md');
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: 'mdx',
|
||||
filePath: 'xyz.md',
|
||||
markdownConfigFormat: 'md',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: 'mdx',
|
||||
filePath: 'xyz.mdx',
|
||||
markdownConfigFormat: 'md',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
});
|
||||
|
||||
it('detects appropriate format from file extension', () => {
|
||||
expect(getFormat({frontMatterFormat: 'detect', filePath: 'xyz.md'})).toBe(
|
||||
'md',
|
||||
);
|
||||
it('supports "detects" for front matter', () => {
|
||||
expect(
|
||||
getFormat({frontMatterFormat: 'detect', filePath: 'xyz.markdown'}),
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'xyz.md',
|
||||
markdownConfigFormat: 'mdx',
|
||||
}),
|
||||
).toBe('md');
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'xyz.markdown',
|
||||
markdownConfigFormat: 'mdx',
|
||||
}),
|
||||
).toBe('md');
|
||||
|
||||
expect(
|
||||
getFormat({frontMatterFormat: 'detect', filePath: 'folder/xyz.md'}),
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'folder/xyz.md',
|
||||
markdownConfigFormat: 'mdx',
|
||||
}),
|
||||
).toBe('md');
|
||||
expect(
|
||||
getFormat({frontMatterFormat: 'detect', filePath: 'folder/xyz.markdown'}),
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'folder/xyz.markdown',
|
||||
markdownConfigFormat: 'mdx',
|
||||
}),
|
||||
).toBe('md');
|
||||
expect(getFormat({frontMatterFormat: 'detect', filePath: 'xyz.mdx'})).toBe(
|
||||
'mdx',
|
||||
);
|
||||
expect(
|
||||
getFormat({frontMatterFormat: 'detect', filePath: 'folder/xyz.mdx'}),
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'xyz.mdx',
|
||||
markdownConfigFormat: 'md',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'folder/xyz.mdx',
|
||||
markdownConfigFormat: 'md',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
|
||||
expect(
|
||||
getFormat({frontMatterFormat: 'detect', filePath: 'xyz.unknown'}),
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'xyz.unknown',
|
||||
markdownConfigFormat: 'md',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
expect(
|
||||
getFormat({frontMatterFormat: 'detect', filePath: 'folder/xyz.unknown'}),
|
||||
getFormat({
|
||||
frontMatterFormat: 'detect',
|
||||
filePath: 'folder/xyz.unknown',
|
||||
markdownConfigFormat: 'md',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
});
|
||||
|
||||
it('fallbacks to markdown config format when front matter undefined', () => {
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: undefined,
|
||||
filePath: 'xyz.md',
|
||||
markdownConfigFormat: 'mdx',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: undefined,
|
||||
filePath: 'xyz.mdx',
|
||||
markdownConfigFormat: 'md',
|
||||
}),
|
||||
).toBe('md');
|
||||
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: undefined,
|
||||
filePath: 'xyz.md',
|
||||
markdownConfigFormat: 'detect',
|
||||
}),
|
||||
).toBe('md');
|
||||
expect(
|
||||
getFormat({
|
||||
frontMatterFormat: undefined,
|
||||
filePath: 'xyz.mdx',
|
||||
markdownConfigFormat: 'detect',
|
||||
}),
|
||||
).toBe('mdx');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -85,9 +85,18 @@ describe('MDX front matter schema', () => {
|
|||
describe('validateDocFrontMatter format', () => {
|
||||
testField({
|
||||
prefix: 'format',
|
||||
validFrontMatters: [{format: 'md'}, {format: 'mdx'}],
|
||||
validFrontMatters: [
|
||||
{},
|
||||
{format: undefined},
|
||||
{format: 'detect'},
|
||||
{format: 'md'},
|
||||
{format: 'mdx'},
|
||||
],
|
||||
invalidFrontMatters: [
|
||||
[{format: 'xdm'}, '"format" must be one of [md, mdx, detect]'],
|
||||
[{format: ''}, '"format" must be one of [md, mdx, detect]'],
|
||||
[{format: null}, '"format" must be one of [md, mdx, detect]'],
|
||||
[{unknownAttribute: 'mdx'}, '"unknownAttribute" is not allowed'],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import path from 'path';
|
||||
import type {MDXFrontMatter} from './frontMatter';
|
||||
import type {Format, FormatInput} from './index';
|
||||
|
||||
// Copied from https://mdxjs.com/packages/mdx/#optionsmdextensions
|
||||
// Although we are likely to only use .md / .mdx anyway...
|
||||
|
@ -21,20 +22,29 @@ const mdFormatExtensions = [
|
|||
'.ron',
|
||||
];
|
||||
|
||||
function isMDFormat(filepath: string) {
|
||||
return mdFormatExtensions.includes(path.extname(filepath));
|
||||
function getExtensionFormat(filepath: string): Format {
|
||||
const isMDFormat = mdFormatExtensions.includes(path.extname(filepath));
|
||||
// Bias toward mdx if unknown extension
|
||||
return isMDFormat ? 'md' : 'mdx';
|
||||
}
|
||||
|
||||
export function getFormat({
|
||||
filePath,
|
||||
frontMatterFormat,
|
||||
markdownConfigFormat,
|
||||
}: {
|
||||
filePath: string;
|
||||
frontMatterFormat: MDXFrontMatter['format'];
|
||||
}): 'md' | 'mdx' {
|
||||
if (frontMatterFormat !== 'detect') {
|
||||
return frontMatterFormat;
|
||||
markdownConfigFormat: FormatInput;
|
||||
}): Format {
|
||||
if (frontMatterFormat) {
|
||||
if (frontMatterFormat !== 'detect') {
|
||||
return frontMatterFormat;
|
||||
}
|
||||
return getExtensionFormat(filePath);
|
||||
}
|
||||
// Bias toward mdx if unknown extension
|
||||
return isMDFormat(filePath) ? 'md' : 'mdx';
|
||||
if (markdownConfigFormat !== 'detect') {
|
||||
return markdownConfigFormat;
|
||||
}
|
||||
return getExtensionFormat(filePath);
|
||||
}
|
||||
|
|
|
@ -10,18 +10,18 @@ import {
|
|||
validateFrontMatter,
|
||||
} from '@docusaurus/utils-validation';
|
||||
|
||||
import type {FormatInput} from './index';
|
||||
|
||||
export type MDXFrontMatter = {
|
||||
format: 'md' | 'mdx' | 'detect';
|
||||
format?: FormatInput;
|
||||
};
|
||||
|
||||
export const DefaultMDXFrontMatter: MDXFrontMatter = {
|
||||
format: 'detect',
|
||||
format: undefined,
|
||||
};
|
||||
|
||||
const MDXFrontMatterSchema = Joi.object<MDXFrontMatter>({
|
||||
format: Joi.string()
|
||||
.equal('md', 'mdx', 'detect')
|
||||
.default(DefaultMDXFrontMatter.format),
|
||||
format: Joi.string().equal('md', 'mdx', 'detect').optional(),
|
||||
}).default(DefaultMDXFrontMatter);
|
||||
|
||||
export function validateMDXFrontMatter(frontMatter: unknown): MDXFrontMatter {
|
||||
|
|
|
@ -13,6 +13,10 @@ export default mdxLoader;
|
|||
|
||||
export type TOCItem = TOCItemImported;
|
||||
|
||||
export type Format = 'md' | 'mdx';
|
||||
|
||||
export type FormatInput = Format | 'detect';
|
||||
|
||||
export type LoadedMDXContent<FrontMatter, Metadata, Assets = undefined> = {
|
||||
/** As verbatim declared in the MDX document. */
|
||||
readonly frontMatter: FrontMatter;
|
||||
|
|
|
@ -235,6 +235,7 @@ export async function createProcessorCached({
|
|||
const format = getFormat({
|
||||
filePath,
|
||||
frontMatterFormat: mdxFrontMatter.format,
|
||||
markdownConfigFormat: reqOptions.markdownConfig.format,
|
||||
});
|
||||
|
||||
return format === 'md' ? compilers.mdProcessor : compilers.mdxProcessor;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue