summaryrefslogtreecommitdiff
path: root/packages/integrations/mdx/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/mdx/src')
-rw-r--r--packages/integrations/mdx/src/index.ts68
-rw-r--r--packages/integrations/mdx/src/plugins.ts57
2 files changed, 56 insertions, 69 deletions
diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts
index e9d81ca1f..2fcc89731 100644
--- a/packages/integrations/mdx/src/index.ts
+++ b/packages/integrations/mdx/src/index.ts
@@ -1,4 +1,5 @@
import { toRemarkInitializeAstroData } from '@astrojs/markdown-remark/dist/internal.js';
+import { markdownConfigDefaults } from '@astrojs/markdown-remark';
import { compile as mdxCompile } from '@mdx-js/mdx';
import { PluggableList } from '@mdx-js/mdx/lib/core.js';
import mdxPlugin, { Options as MdxRollupPluginOptions } from '@mdx-js/rollup';
@@ -17,44 +18,41 @@ const RAW_CONTENT_ERROR =
const COMPILED_CONTENT_ERROR =
'MDX does not support compiledContent()! If you need to read the HTML contents to calculate values (ex. reading time), we suggest injecting frontmatter via rehype plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins';
-export type MdxOptions = {
- remarkPlugins?: PluggableList;
- rehypePlugins?: PluggableList;
- recmaPlugins?: PluggableList;
- /**
- * Choose which remark and rehype plugins to inherit, if any.
- *
- * - "markdown" (default) - inherit your project’s markdown plugin config ([see Markdown docs](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown))
- * - "astroDefaults" - inherit Astro’s default plugins only ([see defaults](https://docs.astro.build/en/reference/configuration-reference/#markdownextenddefaultplugins))
- * - false - do not inherit any plugins
- */
- extendPlugins?: 'markdown' | 'astroDefaults' | false;
- remarkRehype?: RemarkRehypeOptions;
+export type MdxOptions = Omit<typeof markdownConfigDefaults, 'remarkPlugins' | 'rehypePlugins'> & {
+ extendMarkdownConfig: boolean;
+ recmaPlugins: PluggableList;
+ // Markdown allows strings as remark and rehype plugins.
+ // This is not supported by the MDX compiler, so override types here.
+ remarkPlugins: PluggableList;
+ rehypePlugins: PluggableList;
+ remarkRehype: RemarkRehypeOptions;
};
-export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
+export default function mdx(partialMdxOptions: Partial<MdxOptions> = {}): AstroIntegration {
return {
name: '@astrojs/mdx',
hooks: {
'astro:config:setup': async ({ updateConfig, config, addPageExtension, command }: any) => {
addPageExtension('.mdx');
- mdxOptions.extendPlugins ??= 'markdown';
- const remarkRehypeOptions = {
- ...(mdxOptions.extendPlugins === 'markdown' ? config.markdown.remarkRehype : {}),
- ...mdxOptions.remarkRehype,
- };
+ const extendMarkdownConfig =
+ partialMdxOptions.extendMarkdownConfig ?? defaultOptions.extendMarkdownConfig;
+
+ const mdxOptions = applyDefaultOptions({
+ options: partialMdxOptions,
+ defaults: extendMarkdownConfig ? config.markdown : defaultOptions,
+ });
const mdxPluginOpts: MdxRollupPluginOptions = {
remarkPlugins: await getRemarkPlugins(mdxOptions, config),
- rehypePlugins: getRehypePlugins(mdxOptions, config),
+ rehypePlugins: getRehypePlugins(mdxOptions),
recmaPlugins: mdxOptions.recmaPlugins,
+ remarkRehypeOptions: mdxOptions.remarkRehype,
jsx: true,
jsxImportSource: 'astro',
// Note: disable `.md` (and other alternative extensions for markdown files like `.markdown`) support
format: 'mdx',
mdExtensions: [],
- remarkRehypeOptions,
};
let importMetaEnv: Record<string, any> = {
@@ -166,6 +164,34 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
};
}
+const defaultOptions: MdxOptions = {
+ ...markdownConfigDefaults,
+ extendMarkdownConfig: true,
+ recmaPlugins: [],
+ remarkPlugins: [],
+ rehypePlugins: [],
+ remarkRehype: {},
+};
+
+function applyDefaultOptions({
+ options,
+ defaults,
+}: {
+ options: Partial<MdxOptions>;
+ defaults: MdxOptions;
+}): MdxOptions {
+ return {
+ syntaxHighlight: options.syntaxHighlight ?? defaults.syntaxHighlight,
+ extendMarkdownConfig: options.extendMarkdownConfig ?? defaults.extendMarkdownConfig,
+ recmaPlugins: options.recmaPlugins ?? defaults.recmaPlugins,
+ remarkRehype: options.remarkRehype ?? defaults.remarkRehype,
+ gfm: options.gfm ?? defaults.gfm,
+ remarkPlugins: options.remarkPlugins ?? defaults.remarkPlugins,
+ rehypePlugins: options.rehypePlugins ?? defaults.rehypePlugins,
+ shikiConfig: options.shikiConfig ?? defaults.shikiConfig,
+ };
+}
+
// Converts the first dot in `import.meta.env` to its Unicode escape sequence,
// which prevents Vite from replacing strings like `import.meta.env.SITE`
// in our JS representation of loaded Markdown files
diff --git a/packages/integrations/mdx/src/plugins.ts b/packages/integrations/mdx/src/plugins.ts
index 675a8a645..f5557b8a3 100644
--- a/packages/integrations/mdx/src/plugins.ts
+++ b/packages/integrations/mdx/src/plugins.ts
@@ -14,7 +14,6 @@ import type { Image } from 'mdast';
import { pathToFileURL } from 'node:url';
import rehypeRaw from 'rehype-raw';
import remarkGfm from 'remark-gfm';
-import remarkSmartypants from 'remark-smartypants';
import { visit } from 'unist-util-visit';
import type { VFile } from 'vfile';
import { MdxOptions } from './index.js';
@@ -140,36 +139,22 @@ function toRemarkContentRelImageError({ srcDir }: { srcDir: URL }) {
};
}
-const DEFAULT_REMARK_PLUGINS: PluggableList = [remarkGfm, remarkSmartypants];
-const DEFAULT_REHYPE_PLUGINS: PluggableList = [];
-
export async function getRemarkPlugins(
mdxOptions: MdxOptions,
config: AstroConfig
): Promise<MdxRollupPluginOptions['remarkPlugins']> {
let remarkPlugins: PluggableList = [];
- switch (mdxOptions.extendPlugins) {
- case false:
- break;
- case 'astroDefaults':
- remarkPlugins = [...remarkPlugins, ...DEFAULT_REMARK_PLUGINS];
- break;
- default:
- remarkPlugins = [
- ...remarkPlugins,
- ...(markdownShouldExtendDefaultPlugins(config) ? DEFAULT_REMARK_PLUGINS : []),
- ...ignoreStringPlugins(config.markdown.remarkPlugins ?? []),
- ];
- break;
- }
- if (config.markdown.syntaxHighlight === 'shiki') {
- remarkPlugins.push([await remarkShiki(config.markdown.shikiConfig)]);
+ if (mdxOptions.syntaxHighlight === 'shiki') {
+ remarkPlugins.push([await remarkShiki(mdxOptions.shikiConfig)]);
}
- if (config.markdown.syntaxHighlight === 'prism') {
+ if (mdxOptions.syntaxHighlight === 'prism') {
remarkPlugins.push(remarkPrism);
}
+ if (mdxOptions.gfm) {
+ remarkPlugins.push(remarkGfm);
+ }
- remarkPlugins = [...remarkPlugins, ...(mdxOptions.remarkPlugins ?? [])];
+ remarkPlugins = [...remarkPlugins, ...ignoreStringPlugins(mdxOptions.remarkPlugins)];
// Apply last in case user plugins resolve relative image paths
if (config.experimental.contentCollections) {
@@ -178,34 +163,17 @@ export async function getRemarkPlugins(
return remarkPlugins;
}
-export function getRehypePlugins(
- mdxOptions: MdxOptions,
- config: AstroConfig
-): MdxRollupPluginOptions['rehypePlugins'] {
+export function getRehypePlugins(mdxOptions: MdxOptions): MdxRollupPluginOptions['rehypePlugins'] {
let rehypePlugins: PluggableList = [
// ensure `data.meta` is preserved in `properties.metastring` for rehype syntax highlighters
rehypeMetaString,
// rehypeRaw allows custom syntax highlighters to work without added config
[rehypeRaw, { passThrough: nodeTypes }] as any,
];
- switch (mdxOptions.extendPlugins) {
- case false:
- break;
- case 'astroDefaults':
- rehypePlugins = [...rehypePlugins, ...DEFAULT_REHYPE_PLUGINS];
- break;
- default:
- rehypePlugins = [
- ...rehypePlugins,
- ...(markdownShouldExtendDefaultPlugins(config) ? DEFAULT_REHYPE_PLUGINS : []),
- ...ignoreStringPlugins(config.markdown.rehypePlugins ?? []),
- ];
- break;
- }
rehypePlugins = [
...rehypePlugins,
- ...(mdxOptions.rehypePlugins ?? []),
+ ...ignoreStringPlugins(mdxOptions.rehypePlugins),
// getHeadings() is guaranteed by TS, so this must be included.
// We run `rehypeHeadingIds` _last_ to respect any custom IDs set by user plugins.
rehypeHeadingIds,
@@ -216,13 +184,6 @@ export function getRehypePlugins(
return rehypePlugins;
}
-function markdownShouldExtendDefaultPlugins(config: AstroConfig): boolean {
- return (
- config.markdown.extendDefaultPlugins ||
- (config.markdown.remarkPlugins.length === 0 && config.markdown.rehypePlugins.length === 0)
- );
-}
-
function ignoreStringPlugins(plugins: any[]) {
let validPlugins: PluggableList = [];
let hasInvalidPlugin = false;