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

Markdown and MDX configuration rework #5684

Merged
merged 29 commits into from Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d1523d6
feat: change extendDefaults -> gfm
bholmesdev Dec 27, 2022
7b97880
deps: remove smartypants from md/remark
bholmesdev Dec 27, 2022
b97055c
tests: update markdown plugin tests
bholmesdev Dec 27, 2022
10c84bd
fix: borked lockfile
bholmesdev Dec 27, 2022
150aa45
feat: allow all Markdown options in MDX config, with extend
bholmesdev Dec 27, 2022
ef71843
deps: remove smartypants from MDX
bholmesdev Dec 27, 2022
f8217c9
chore: remove unused `mode` property
bholmesdev Dec 27, 2022
bb168a8
chore: remark rehype types
bholmesdev Dec 27, 2022
3fed4cb
chore: dead code
bholmesdev Dec 27, 2022
6ac8f41
fix: order of default config properties
bholmesdev Dec 27, 2022
ef91b0a
refactor: move md defaults to remark
bholmesdev Dec 27, 2022
351d86c
fix: RemarkRehype type
bholmesdev Dec 27, 2022
a8dfaf8
fix: apply defaults based on MD defaults
bholmesdev Dec 27, 2022
661980d
chore: update plugin tests
bholmesdev Dec 27, 2022
11b9970
chore: add syntaxHighlight test
bholmesdev Dec 27, 2022
b9b4e1a
refactor: remove drafts from config defaults
bholmesdev Dec 27, 2022
4bc9f11
docs: new MDX config options
bholmesdev Dec 27, 2022
2c8dca0
chore: add changeset
bholmesdev Dec 27, 2022
641dbca
edit: test both extends for syntax highlight
bholmesdev Dec 27, 2022
35393ad
refactor: remove MDX config deep merge
bholmesdev Dec 28, 2022
1ae5b72
docs: update README and changeset
bholmesdev Dec 28, 2022
3a93e7d
edit: avoid -> disable
bholmesdev Dec 28, 2022
063060a
edit: `drafts` clarification
bholmesdev Dec 28, 2022
20f0dfc
edit: remove "scare quotes"
bholmesdev Dec 28, 2022
d7858a2
docs: MDX config options redraft
bholmesdev Dec 28, 2022
28fece6
docs: add migration
bholmesdev Dec 28, 2022
91edc65
chore: changeset heading levels
bholmesdev Jan 2, 2023
4a2c2e7
refactor: githubFlavoredMarkdown -> gfm
bholmesdev Jan 3, 2023
aae0f82
chore: remove unused imports
bholmesdev Jan 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
63 changes: 63 additions & 0 deletions .changeset/shaggy-keys-turn.md
@@ -0,0 +1,63 @@
---
'astro': major
'@astrojs/markdown-remark': major
'@astrojs/mdx': minor
---

Refine Markdown and MDX configuration options for ease-of-use.

#### Markdown

- **Remove `remark-smartypants`** from Astro's default Markdown plugins.
- **Replace the `extendDefaultPlugins` option** with a simplified `gfm` boolean. This is enabled by default, and can be disabled to remove GitHub-Flavored Markdown.
- Ensure GitHub-Flavored Markdown is applied whether or not custom `remarkPlugins` or `rehypePlugins` are configured. If you want to apply custom plugins _and_ remove GFM, manually set `gfm: false` in your config.

#### MDX

- Support _all_ Markdown configuration options (except `drafts`) from your MDX integration config. This includes `syntaxHighlighting` and `shikiConfig` options to further customize the MDX renderer.
- Simplify `extendDefaults` to an `extendMarkdownConfig` option. MDX options will default to their equivalent in your Markdown config. By setting `extendMarkdownConfig` to false, you can "eject" to set your own syntax highlighting, plugins, and more.

#### Migration

To preserve your existing Markdown and MDX setup, you may need some configuration changes:

##### Smartypants manual installation

[Smartypants](https://github.com/silvenon/remark-smartypants) has been removed from Astro's default setup. If you rely on this plugin, [install `remark-smartypants`](https://github.com/silvenon/remark-smartypants#installing) and apply to your `astro.config.*`:

```diff
// astro.config.mjs
import { defineConfig } from 'astro/config';
+ import smartypants from 'remark-smartypants';

export default defineConfig({
markdown: {
+ remarkPlugins: [smartypants],
}
});
```

##### Migrate `extendDefaultPlugins` to `gfm`

You may have disabled Astro's built-in plugins (GitHub-Flavored Markdown and Smartypants) with the `extendDefaultPlugins` option. Since Smartypants has been removed, this has been renamed to `gfm`.

```diff
// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
markdown: {
- extendDefaultPlugins: false,
+ gfm: false,
}
});
```


Additionally, applying remark and rehype plugins **no longer disables** `gfm`. You will need to opt-out manually by setting `gfm` to `false`.

##### Migrate MDX's `extendPlugins` to `extendMarkdownConfig`

You may have used the `extendPlugins` option to manage plugin defaults in MDX. This has been replaced by 2 flags:
- `extendMarkdownConfig` (`true` by default) to toggle Markdown config inheritance. This replaces the `extendPlugins: 'markdown'` option.
- `gfm` (`true` by default) to toggle GitHub-Flavored Markdown in MDX. This replaces the `extendPlugins: 'defaults'` option.
20 changes: 5 additions & 15 deletions packages/astro/src/@types/astro.ts
Expand Up @@ -734,10 +734,6 @@ export interface AstroUserConfig {
* @description
* 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.
*
* :::caution
* Providing a list of plugins will **remove** our default plugins. To preserve these defaults, see the [`extendDefaultPlugins`](#markdownextenddefaultplugins) flag.
* :::
*
* ```js
* import remarkToc from 'remark-toc';
* {
Expand All @@ -755,10 +751,6 @@ export interface AstroUserConfig {
* @description
* 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.
*
* :::caution
* Providing a list of plugins will **remove** our default plugins. To preserve these defaults, see the [`extendDefaultPlugins`](#markdownextenddefaultplugins) flag.
* :::
*
* ```js
* import rehypeMinifyHtml from 'rehype-minify';
* {
Expand All @@ -771,23 +763,21 @@ export interface AstroUserConfig {
rehypePlugins?: RehypePlugins;
/**
* @docs
* @name markdown.extendDefaultPlugins
* @name markdown.gfm
* @type {boolean}
* @default `false`
* @default `true`
* @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`:
* Astro uses [GitHub-flavored Markdown](https://github.com/remarkjs/remark-gfm) by default. To disable this, set the `gfm` flag to `false`:
*
* ```js
* {
* markdown: {
* extendDefaultPlugins: true,
* remarkPlugins: [exampleRemarkPlugin],
* rehypePlugins: [exampleRehypePlugin],
* gfm: false,
* }
* }
* ```
*/
extendDefaultPlugins?: boolean;
gfm?: boolean;
/**
* @docs
* @name markdown.remarkRehype
Expand Down
13 changes: 3 additions & 10 deletions packages/astro/src/core/config/schema.ts
@@ -1,4 +1,5 @@
import type { RehypePlugin, RemarkPlugin, RemarkRehype } from '@astrojs/markdown-remark';
import { markdownConfigDefaults } from '@astrojs/markdown-remark';
import type * as Postcss from 'postcss';
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
import type { AstroUserConfig, ViteUserConfig } from '../../@types/astro';
Expand Down Expand Up @@ -33,15 +34,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
integrations: [],
markdown: {
drafts: false,
syntaxHighlight: 'shiki',
shikiConfig: {
langs: [],
theme: 'github-dark',
wrap: false,
},
remarkPlugins: [],
rehypePlugins: [],
remarkRehype: {},
...markdownConfigDefaults,
},
vite: {},
legacy: {
Expand Down Expand Up @@ -184,7 +177,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),
gfm: z.boolean().default(ASTRO_CONFIG_DEFAULTS.markdown.gfm),
})
.default({}),
vite: z
Expand Down
34 changes: 28 additions & 6 deletions packages/astro/test/astro-markdown-plugins.test.js
Expand Up @@ -46,29 +46,51 @@ describe('Astro Markdown plugins', () => {
expect($('#hello-world').hasClass('title')).to.equal(true);
});

for (const extendDefaultPlugins of [true, false]) {
it(`Handles default plugins when extendDefaultPlugins = ${extendDefaultPlugins}`, async () => {
// Asserts Astro 1.0 behavior is removed. Test can be removed in Astro 3.0.
it('Still applies GFM when user plugins are provided', async () => {
const fixture = await buildFixture({
markdown: {
remarkPlugins: [remarkExamplePlugin],
rehypePlugins: [[addClasses, { 'h1,h2,h3': 'title' }]],
},
});
const html = await fixture.readFile('/with-gfm/index.html');
const $ = cheerio.load(html);

// test 1: GFM autolink applied correctly
expect($('a[href="https://example.com"]')).to.have.lengthOf(1);

// test 2: remark plugins still applied
expect(html).to.include('Remark plugin applied!');

// test 3: rehype plugins still applied
expect($('#github-flavored-markdown-test')).to.have.lengthOf(1);
expect($('#github-flavored-markdown-test').hasClass('title')).to.equal(true);
});

for (const gfm of [true, false]) {
it(`Handles GFM when gfm = ${gfm}`, async () => {
const fixture = await buildFixture({
markdown: {
remarkPlugins: [remarkExamplePlugin],
rehypePlugins: [[addClasses, { 'h1,h2,h3': 'title' }]],
extendDefaultPlugins,
gfm,
},
});
const html = await fixture.readFile('/with-gfm/index.html');
const $ = cheerio.load(html);

// test 1: GFM autolink applied correctly
if (extendDefaultPlugins === true) {
if (gfm === 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
// test 2: remark plugins still applied
expect(html).to.include('Remark plugin applied!');

// test 3: (sanity check) rehype plugins still applied
// test 3: rehype plugins still applied
expect($('#github-flavored-markdown-test')).to.have.lengthOf(1);
expect($('#github-flavored-markdown-test').hasClass('title')).to.equal(true);
});
Expand Down
156 changes: 70 additions & 86 deletions packages/integrations/mdx/README.md
Expand Up @@ -78,116 +78,100 @@ Visit the [MDX docs](https://mdxjs.com/docs/what-is-mdx/) to learn about using s

Once the MDX integration is installed, no configuration is necessary to use `.mdx` files in your Astro project.

You can extend how your MDX is rendered by adding remark, rehype and recma plugins.
You can configure how your MDX is rendered with the following options:

- [`extendPlugins`](#extendplugins)
- [`remarkRehype`](#remarkrehype)
- [`remarkPlugins`](#remarkplugins)
- [`rehypePlugins`](#rehypeplugins)
- [Options inherited from Markdown config](#options-inherited-from-markdown-config)
- [`extendMarkdownConfig`](#extendmarkdownconfig)
- [`recmaPlugins`](#recmaplugins)

### `extendPlugins`
### Options inherited from Markdown config

You can customize how MDX files inherit your project’s existing Markdown configuration using the `extendPlugins` option.
All [`markdown` configuration options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) except `drafts` can be configured separately in the MDX integration. This includes remark and rehype plugins, syntax highlighting, and more. Options will default to those in your Markdown config ([see the `extendMarkdownConfig` option](#extendmarkdownconfig) to modify this).

#### `markdown` (default)
:::note
There is no separate MDX configuration for [including pages marked as draft in the build](https://docs.astro.build/en/reference/configuration-reference/#markdowndrafts). This Markdown setting will be respected by both Markdown and MDX files and cannot be overriden for MDX files specifically.
:::

Astro's MDX files will inherit all [`markdown` options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) in your Astro configuration file, which includes the [GitHub-Flavored Markdown](https://github.com/remarkjs/remark-gfm) and [Smartypants](https://github.com/silvenon/remark-smartypants) plugins by default.

Any additional plugins you apply in your MDX config will be applied *after* your configured Markdown plugins.

#### `astroDefaults`

Astro's MDX files will apply only [Astro's default plugins](/en/reference/configuration-reference/#markdownextenddefaultplugins), without inheriting the rest of your Markdown config.

This example will apply the default [GitHub-Flavored Markdown](https://github.com/remarkjs/remark-gfm) and [Smartypants](https://github.com/silvenon/remark-smartypants) plugins alongside [`remark-toc`](https://github.com/remarkjs/remark-toc) to your MDX files, while ignoring any `markdown.remarkPlugins` configuration:

```js "extendPlugins: 'astroDefaults'"
```ts
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';
import rehypeMinifyHtml from 'rehype-minify-html';

export default {
markdown: {
remarkPlugins: [/** ignored */]
},
integrations: [mdx({
remarkPlugins: [remarkToc],
// Astro defaults applied
extendPlugins: 'astroDefaults',
})],
}
export default defineConfig({
integrations: [
mdx({
syntaxHighlight: 'shiki',
shikiConfig: { theme: 'dracula' },
remarkPlugins: [remarkToc],
rehypePlugins: [rehypeMinifyHtml],
remarkRehype: { footnoteLabel: 'Footnotes' },
gfm: false,
})
]
})
```

#### `false`
:::caution
MDX does not support passing remark and rehype plugins as a string. You should install, import, and apply the plugin function instead.
:::

Astro's MDX files will not inherit any [`markdown` options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options), nor will any Astro Markdown defaults be applied:
📚 See the [Markdown Options reference](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) for a complete list of options.

```js "extendPlugins: false"
// astro.config.mjs
import remarkToc from 'remark-toc';

export default {
integrations: [mdx({
remarkPlugins: [remarkToc],
// Astro defaults not applied
extendPlugins: false,
})],
}
```
### `extendMarkdownConfig`

### `remarkRehype`
- **Type:** `boolean`
- **Default:** `true`

Markdown content is transformed into HTML through remark-rehype which has [a number of options](https://github.com/remarkjs/remark-rehype#options).
MDX will extend [your project's existing Markdown configuration](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) by default. To override individual options, you can specify their equivalent in your MDX configuration.

You can set remark-rehype options in your config file:
For example, say you need to disable GitHub-Flavored Markdown and apply a different set of remark plugins for MDX files. You can apply these options like so, with `extendMarkdownConfig` enabled by default:

```js
```ts
// astro.config.mjs
export default {
integrations: [mdx({
remarkRehype: {
footnoteLabel: 'Catatan kaki',
footnoteBackLabel: 'Kembali ke konten',
},
})],
};
```
This inherits the configuration of [`markdown.remarkRehype`](https://docs.astro.build/en/reference/configuration-reference/#markdownremarkrehype). This behavior can be changed by configuring `extendPlugins`.

### `remarkPlugins`

Browse [awesome-remark](https://github.com/remarkjs/awesome-remark) for a full curated list of [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md) to extend your Markdown's capabilities.

This example applies the [`remark-toc`](https://github.com/remarkjs/remark-toc) plugin to `.mdx` files. To customize plugin inheritance from your Markdown config or Astro's defaults, [see the `extendPlugins` option](#extendplugins).

```js
// astro.config.mjs
import remarkToc from 'remark-toc';
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

export default {
integrations: [mdx({
remarkPlugins: [remarkToc],
})],
}
export default defineConfig({
markdown: {
syntaxHighlight: 'prism',
remarkPlugins: [remarkPlugin1],
gfm: true,
},
integrations: [
mdx({
// `syntaxHighlight` inherited from Markdown

// Markdown `remarkPlugins` ignored,
// only `remarkPlugin2` applied.
remarkPlugins: [remarkPlugin2],
// `gfm` overridden to `false`
gfm: false,
})
]
});
```

### `rehypePlugins`

Browse [awesome-rehype](https://github.com/rehypejs/awesome-rehype) for a full curated list of [Rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md) to transform the HTML that your Markdown generates.
You may also need to disable `markdown` config extension in MDX. For this, set `extendMarkdownConfig` to `false`:

We apply our own (non-removable) [`collect-headings`](https://github.com/withastro/astro/blob/main/packages/integrations/mdx/src/rehype-collect-headings.ts) plugin. This applies IDs to all headings (i.e. `h1 -> h6`) in your MDX files to [link to headings via anchor tags](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#linking_to_an_element_on_the_same_page).

This example applies the [`rehype-accessible-emojis`](https://www.npmjs.com/package/rehype-accessible-emojis) plugin to `.mdx` files. To customize plugin inheritance from your Markdown config or Astro's defaults, [see the `extendPlugins` option](#extendplugins).

```js
```ts
// astro.config.mjs
import rehypeAccessibleEmojis from 'rehype-accessible-emojis';
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

export default {
integrations: [mdx({
rehypePlugins: [rehypeAccessibleEmojis],
})],
}
export default defineConfig({
markdown: {
remarkPlugins: [remarkPlugin1],
},
integrations: [
mdx({
// Markdown config now ignored
extendMarkdownConfig: false,
// No `remarkPlugins` applied
})
]
});
```

### `recmaPlugins`
Expand Down
1 change: 0 additions & 1 deletion packages/integrations/mdx/package.json
Expand Up @@ -43,7 +43,6 @@
"rehype-raw": "^6.1.1",
"remark-frontmatter": "^4.0.1",
"remark-gfm": "^3.0.1",
"remark-smartypants": "^2.0.0",
"shiki": "^0.11.1",
"unist-util-visit": "^4.1.0",
"vfile": "^5.3.2"
Expand Down