[MD] extendDefaultPlugins
to preserve default remark plugins (#4474)
* feat: add { extends } to markdown config * test: remark plugins with extends * deps: pnpm lock * chore: changeset * fix: remarkPlugins -> rehypePlugins * docs: update markdown config reference * Revert "feat: add { extends } to markdown config" This reverts commit 5d050bbcf9a2c0d470cae79c4d0a954d489f4e8c. * feat: new "extendDefaultPlugins" flag * docs: update config * nit: We -> Astro applies * fix: backticks on `false` * nit: Note -> REAL note Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * docs: note -> caution Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
d4cd7a59fd
commit
ac03218247
10 changed files with 100 additions and 31 deletions
6
.changeset/cool-turtles-lay.md
Normal file
6
.changeset/cool-turtles-lay.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'astro': minor
|
||||
'@astrojs/markdown-remark': minor
|
||||
---
|
||||
|
||||
Add "extends" to markdown plugin config to preserve Astro defaults
|
|
@ -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
|
||||
* {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/astro-markdown-plugins/',
|
||||
function remarkExamplePlugin() {
|
||||
return (tree) => {
|
||||
tree.children.push({ type: 'paragraph', children: [{ type: 'text', value: 'Remark plugin applied!' }] })
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [preact()],
|
||||
integrations: [],
|
||||
});
|
||||
|
|
|
@ -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"
|
||||
|
|
3
packages/astro/test/fixtures/astro-markdown-plugins/src/pages/with-gfm.md
vendored
Normal file
3
packages/astro/test/fixtures/astro-markdown-plugins/src/pages/with-gfm.md
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# GitHub-flavored Markdown test
|
||||
|
||||
This should auto-gen a link: https://example.com
|
|
@ -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));
|
||||
|
|
|
@ -43,6 +43,7 @@ export interface AstroMarkdownOptions {
|
|||
remarkPlugins?: RemarkPlugins;
|
||||
rehypePlugins?: RehypePlugins;
|
||||
remarkRehype?: RemarkRehype;
|
||||
extendDefaultPlugins?: boolean;
|
||||
}
|
||||
|
||||
export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue