summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/cool-turtles-lay.md6
-rw-r--r--packages/astro/src/@types/astro.ts49
-rw-r--r--packages/astro/src/core/config.ts1
-rw-r--r--packages/astro/test/astro-markdown-plugins.test.js58
-rw-r--r--packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs3
-rw-r--r--packages/astro/test/fixtures/astro-markdown-plugins/package.json1
-rw-r--r--packages/astro/test/fixtures/astro-markdown-plugins/src/pages/with-gfm.md3
-rw-r--r--packages/markdown/remark/src/index.ts7
-rw-r--r--packages/markdown/remark/src/types.ts1
-rw-r--r--pnpm-lock.yaml2
10 files changed, 100 insertions, 31 deletions
diff --git a/.changeset/cool-turtles-lay.md b/.changeset/cool-turtles-lay.md
new file mode 100644
index 000000000..e58bc57c7
--- /dev/null
+++ b/.changeset/cool-turtles-lay.md
@@ -0,0 +1,6 @@
+---
+'astro': minor
+'@astrojs/markdown-remark': minor
+---
+
+Add "extends" to markdown plugin config to preserve Astro defaults
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 64b246238..4b4948671 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -648,17 +648,19 @@ export interface AstroUserConfig {
* @name markdown.remarkPlugins
* @type {RemarkPlugins}
* @description
- * Pass a custom [Remark](https://github.com/remarkjs/remark) plugin to customize how your Markdown is built.
+ * Pass [remark plugins](https://github.com/remarkjs/remark) to customize how your Markdown is built. You can import and apply the plugin function (recommended), or pass the plugin name as a string.
*
- * **Note:** Enabling custom `remarkPlugins` or `rehypePlugins` removes Astro's built-in support for [GitHub-flavored Markdown](https://github.github.com/gfm/) support and [Smartypants](https://github.com/silvenon/remark-smartypants). You must explicitly add these plugins to your `astro.config.mjs` file, if desired.
+ * :::caution
+ * Providing a list of plugins will **remove** our default plugins. To preserve these defaults, see the `extendDefaultPlugins` flag.
+ * :::
*
* ```js
+ * import remarkToc from 'remark-toc';
* {
* markdown: {
- * // Example: The default set of remark plugins used by Astro
- * remarkPlugins: ['remark-gfm', 'remark-smartypants'],
- * },
- * };
+ * remarkPlugins: [remarkToc]
+ * }
+ * }
* ```
*/
remarkPlugins?: RemarkPlugins;
@@ -667,26 +669,47 @@ export interface AstroUserConfig {
* @name markdown.rehypePlugins
* @type {RehypePlugins}
* @description
- * Pass a custom [Rehype](https://github.com/remarkjs/remark-rehype) plugin to customize how your Markdown is built.
+ * Pass [rehype plugins](https://github.com/remarkjs/remark-rehype) to customize how your Markdown's output HTML is processed. You can import and apply the plugin function (recommended), or pass the plugin name as a string.
*
- * **Note:** Enabling custom `remarkPlugins` or `rehypePlugins` removes Astro's built-in support for [GitHub-flavored Markdown](https://github.github.com/gfm/) support and [Smartypants](https://github.com/silvenon/remark-smartypants). You must explicitly add these plugins to your `astro.config.mjs` file, if desired.
+ * :::caution
+ * Providing a list of plugins will **remove** our default plugins. To preserve these defaults, see the `extendDefaultPlugins` flag.
+ * :::
*
* ```js
+ * import rehypeMinifyHtml from 'rehype-minify';
* {
* markdown: {
- * // Example: The default set of rehype plugins used by Astro
- * rehypePlugins: [],
- * },
- * };
+ * rehypePlugins: [rehypeMinifyHtml]
+ * }
+ * }
* ```
*/
rehypePlugins?: RehypePlugins;
/**
* @docs
+ * @name markdown.extendDefaultPlugins
+ * @type {boolean}
+ * @default `false`
+ * @description
+ * Astro applies the [GitHub-flavored Markdown](https://github.com/remarkjs/remark-gfm) and [Smartypants](https://github.com/silvenon/remark-smartypants) plugins by default. When adding your own remark or rehype plugins, you can preserve these defaults by setting the `extendDefaultPlugins` flag to `true`:
+ *
+ * ```js
+ * {
+ * markdown: {
+ * extendDefaultPlugins: true,
+ * remarkPlugins: [exampleRemarkPlugin],
+ * rehypePlugins: [exampleRehypePlugin],
+ * }
+ * }
+ * ```
+ */
+ extendDefaultPlugins?: boolean;
+ /**
+ * @docs
* @name markdown.remarkRehype
* @type {RemarkRehype}
* @description
- * Pass options to [remark-rehype](https://github.com/remarkjs/remark-rehype#api) .
+ * Pass options to [remark-rehype](https://github.com/remarkjs/remark-rehype#api).
*
* ```js
* {
diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts
index 6b9f83e13..aa8d701e7 100644
--- a/packages/astro/src/core/config.ts
+++ b/packages/astro/src/core/config.ts
@@ -219,6 +219,7 @@ export const AstroConfigSchema = z.object({
.custom<RemarkRehype>((data) => data instanceof Object && !Array.isArray(data))
.optional()
.default(ASTRO_CONFIG_DEFAULTS.markdown.remarkRehype),
+ extendDefaultPlugins: z.boolean().default(false),
})
.default({}),
vite: z
diff --git a/packages/astro/test/astro-markdown-plugins.test.js b/packages/astro/test/astro-markdown-plugins.test.js
index 9a925bdf0..c65284177 100644
--- a/packages/astro/test/astro-markdown-plugins.test.js
+++ b/packages/astro/test/astro-markdown-plugins.test.js
@@ -3,12 +3,24 @@ import * as cheerio from 'cheerio';
import { loadFixture } from './test-utils.js';
import addClasses from './fixtures/astro-markdown-plugins/add-classes.mjs';
-describe('Astro Markdown plugins', () => {
- let fixture;
+async function buildFixture(config) {
+ const fixture = await loadFixture({
+ root: './fixtures/astro-markdown-plugins/',
+ ...config,
+ });
+ await fixture.build();
+ return fixture;
+}
+
+function remarkExamplePlugin() {
+ return (tree) => {
+ tree.children.push({ type: 'paragraph', children: [{ type: 'text', value: 'Remark plugin applied!' }] })
+ }
+}
- before(async () => {
- fixture = await loadFixture({
- root: './fixtures/astro-markdown-plugins/',
+describe('Astro Markdown plugins', () => {
+ it('Can render markdown with plugins', async () => {
+ const fixture = await buildFixture({
markdown: {
remarkPlugins: [
'remark-code-titles',
@@ -21,17 +33,43 @@ describe('Astro Markdown plugins', () => {
],
},
});
- await fixture.build();
- });
-
- it('Can render markdown with plugins', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
// test 1: Added a TOC
expect($('.toc')).to.have.lengthOf(1);
- // teste 2: Added .title to h1
+ // test 2: Added .title to h1
expect($('#hello-world').hasClass('title')).to.equal(true);
});
+
+ for (const extendDefaultPlugins of [true, false]) {
+ it(`Handles default plugins when extendDefaultPlugins = ${extendDefaultPlugins}`, async () => {
+ const fixture = await buildFixture({
+ markdown: {
+ remarkPlugins: [remarkExamplePlugin],
+ rehypePlugins: [
+ [addClasses, { 'h1,h2,h3': 'title' }],
+ ],
+ extendDefaultPlugins,
+ },
+ });
+ const html = await fixture.readFile('/with-gfm/index.html');
+ const $ = cheerio.load(html);
+
+ // test 1: GFM autolink applied correctly
+ if (extendDefaultPlugins === true) {
+ expect($('a[href="https://example.com"]')).to.have.lengthOf(1);
+ } else {
+ expect($('a[href="https://example.com"]')).to.have.lengthOf(0);
+ }
+
+ // test 2: (sanity check) remark plugins still applied
+ expect(html).to.include('Remark plugin applied!');
+
+ // test 3: (sanity check) rehype plugins still applied
+ expect($('#github-flavored-markdown-test')).to.have.lengthOf(1);
+ expect($('#github-flavored-markdown-test').hasClass('title')).to.equal(true);
+ })
+ }
});
diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs b/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs
index 08916b1fe..db9a6db87 100644
--- a/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs
+++ b/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs
@@ -1,7 +1,6 @@
import { defineConfig } from 'astro/config';
-import preact from '@astrojs/preact';
// https://astro.build/config
export default defineConfig({
- integrations: [preact()],
+ integrations: [],
});
diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/package.json b/packages/astro/test/fixtures/astro-markdown-plugins/package.json
index bdad17d55..e3970aa45 100644
--- a/packages/astro/test/fixtures/astro-markdown-plugins/package.json
+++ b/packages/astro/test/fixtures/astro-markdown-plugins/package.json
@@ -3,7 +3,6 @@
"version": "0.0.0",
"private": true,
"dependencies": {
- "@astrojs/preact": "workspace:*",
"astro": "workspace:*",
"hast-util-select": "^5.0.2",
"rehype-slug": "^5.0.1"
diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/with-gfm.md b/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/with-gfm.md
new file mode 100644
index 000000000..bbb0e7399
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/with-gfm.md
@@ -0,0 +1,3 @@
+# GitHub-flavored Markdown test
+
+This should auto-gen a link: https://example.com
diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts
index da64a5459..c64bdac0e 100644
--- a/packages/markdown/remark/src/index.ts
+++ b/packages/markdown/remark/src/index.ts
@@ -39,6 +39,7 @@ export async function renderMarkdown(
remarkPlugins = [],
rehypePlugins = [],
remarkRehype = {},
+ extendDefaultPlugins = false,
isAstroFlavoredMd = false,
} = opts;
const input = new VFile({ value: content, path: fileURL });
@@ -50,9 +51,9 @@ export async function renderMarkdown(
.use(remarkInitializeAstroData)
.use(isAstroFlavoredMd ? [remarkMdxish, remarkMarkAndUnravel, remarkUnwrap, remarkEscape] : []);
- if (remarkPlugins.length === 0 && rehypePlugins.length === 0) {
- remarkPlugins = [...DEFAULT_REMARK_PLUGINS];
- rehypePlugins = [...DEFAULT_REHYPE_PLUGINS];
+ if (extendDefaultPlugins || (remarkPlugins.length === 0 && rehypePlugins.length === 0)) {
+ remarkPlugins = [...DEFAULT_REMARK_PLUGINS, ...remarkPlugins];
+ rehypePlugins = [...DEFAULT_REHYPE_PLUGINS, ...rehypePlugins];
}
const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
diff --git a/packages/markdown/remark/src/types.ts b/packages/markdown/remark/src/types.ts
index 9df11d414..5b40c9f9d 100644
--- a/packages/markdown/remark/src/types.ts
+++ b/packages/markdown/remark/src/types.ts
@@ -43,6 +43,7 @@ export interface AstroMarkdownOptions {
remarkPlugins?: RemarkPlugins;
rehypePlugins?: RehypePlugins;
remarkRehype?: RemarkRehype;
+ extendDefaultPlugins?: boolean;
}
export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3a51eacbd..a6fa6af7f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1286,12 +1286,10 @@ importers:
packages/astro/test/fixtures/astro-markdown-plugins:
specifiers:
- '@astrojs/preact': workspace:*
astro: workspace:*
hast-util-select: ^5.0.2
rehype-slug: ^5.0.1
dependencies:
- '@astrojs/preact': link:../../../../integrations/preact
astro: link:../../..
hast-util-select: 5.0.2
rehype-slug: 5.0.1