diff options
author | 2021-07-01 19:55:22 +0300 | |
---|---|---|
committer | 2021-07-01 11:55:22 -0500 | |
commit | d3969436dcbe40a3d41a036ff7c2761aed176109 (patch) | |
tree | 5b79d1ce306566bc53a71e2fe2e5b494adf20904 | |
parent | e773771b917d1d11e8a5647ccdc2d44c903f1f4c (diff) | |
download | astro-d3969436dcbe40a3d41a036ff7c2761aed176109.tar.gz astro-d3969436dcbe40a3d41a036ff7c2761aed176109.tar.zst astro-d3969436dcbe40a3d41a036ff7c2761aed176109.zip |
Remark and rehype plugins (#562)
* remark plugins
* remove unused dependency
* enable codeblocks
* backward compatibility with remark-code-titles
* add support for rehype plugins
* add proper types for plugins
* fixes after review
- connect plugins by name
- make plugins configurable
- connect gfm and footnotes if no plugins provided from config
- add more plugins to example
* update and rename example
* add documentation for markdown plugins
* chore: rename with-markdown-plugins example
* chore: restructure dependencies
* feat: add back smartypants, fix mdx expressions
* chore: remove log
* test: add markdown plugin tests
* chore: add changeset
* docs: update markdown doc
Co-authored-by: Nate Moore <nate@skypack.dev>
29 files changed, 742 insertions, 145 deletions
diff --git a/.changeset/clever-cheetahs-jump.md b/.changeset/clever-cheetahs-jump.md new file mode 100644 index 000000000..282307801 --- /dev/null +++ b/.changeset/clever-cheetahs-jump.md @@ -0,0 +1,25 @@ +--- +'astro': minor +'@astrojs/markdown-support': minor +--- + +Add support for [`remark`](https://github.com/remarkjs/remark#readme) and [`rehype`](https://github.com/rehypejs/rehype#readme) plugins for both `.md` pages and `.astro` pages using the [`<Markdown>`](/docs/guides/markdown-content.md) component. + +For example, the `astro.config.mjs` could be updated to include the following. [Read the Markdown documentation](/docs/guides/markdown-content.md) for more information. + +> **Note** Enabling custom `remarkPlugins` or `rehypePlugins` removes Astro's built-in support for [GitHub-flavored Markdown](https://github.github.com/gfm/) support, [Footnotes](https://github.com/remarkjs/remark-footnotes) syntax, [Smartypants](https://github.com/silvenon/remark-smartypants). You must explicitly add these plugins to your `astro.config.mjs` file, if desired. + +```js +export default { + markdownOptions: { + remarkPlugins: [ + 'remark-slug', + ['remark-autolink-headings', { behavior: 'prepend'}], + ], + rehypePlugins: [ + 'rehype-slug', + ['rehype-autolink-headings', { behavior: 'prepend'}], + ] + }, +} +``` diff --git a/docs/guides/markdown-content.md b/docs/guides/markdown-content.md index b00312034..00dbd7f87 100644 --- a/docs/guides/markdown-content.md +++ b/docs/guides/markdown-content.md @@ -4,12 +4,51 @@ title: Markdown Content --- Astro comes with out-of-the-box Markdown support powered by the expansive [remark](https://remark.js.org/) ecosystem. +## Remark and Rehype Plugins + +In addition to [custom components inside the `<Markdown>` component](#markdown-component), Astro comes with [GitHub-flavored Markdown](https://github.github.com/gfm/) support, [Footnotes](https://github.com/remarkjs/remark-footnotes) syntax, [Smartypants](https://github.com/silvenon/remark-smartypants), and syntax highlighting via [Prism](https://prismjs.com/) pre-enabled. + +Also, Astro supports third-party plugins for Markdown. You can provide your plugins in `astro.config.mjs`. + +> **Note** Enabling custom `remarkPlugins` or `rehypePlugins` removes Astro's built-in support for [GitHub-flavored Markdown](https://github.github.com/gfm/) support, [Footnotes](https://github.com/remarkjs/remark-footnotes) syntax, [Smartypants](https://github.com/silvenon/remark-smartypants). You must explicitly add these plugins to your `astro.config.mjs` file, if desired. + +## Add a markdown plugin in Astro + +If you want to add a plugin, you need to install the npm package dependency in your project and then update the `markdownOptions.remarkPlugins` or `markdownOptions.rehypePlugins` depends on what plugin you want to have: + +```js +// astro.config.js +export default { + markdownOptions: { + remarkPlugins: [ + // Add a Remark plugin that you want to enable for your project. + // If you need to provide options for the plugin, you can use an array and put the options as the second item. + // 'remark-slug', + // ['remark-autolink-headings', { behavior: 'prepend'}], + ] + rehypePlugins: [ + // Add a Rehype plugin that you want to enable for your project. + // If you need to provide options for the plugin, you can use an array and put the options as the second item. + // 'rehype-slug', + // ['rehype-autolink-headings', { behavior: 'prepend'}], + ] + }, +}; +``` -### Remark Plugins - -**This is the first draft of Markdown support!** While we plan to support user-provided `remark` plugins soon, our hope is that you won't need `remark` plugins at all! +You can provide names of the plugins as well as import them: -In addition to [custom components inside the `<Markdown>` component](https://github.com/snowpackjs/astro/blob/main/docs/markdown.md#markdown-component), Astro comes with [Github-flavored Markdown](https://github.github.com/gfm/) support, [Footnotes](https://github.com/remarkjs/remark-footnotes) syntax, [Smartypants](https://github.com/silvenon/remark-smartypants), and syntax highlighting via [Prism](https://prismjs.com/) pre-enabled. These features are likely to be configurable in the future. +```js +// astro.config.js +export default { + markdownOptions: { + remarkPlugins: [ + import('remark-slug'), + [import('remark-autolink-headings'), { behavior: 'prepend' }], + ], + }, +}; +``` ### Markdown Pages diff --git a/examples/with-markdown-plugins/.gitignore b/examples/with-markdown-plugins/.gitignore new file mode 100644 index 000000000..d436c6dad --- /dev/null +++ b/examples/with-markdown-plugins/.gitignore @@ -0,0 +1,18 @@ +# build output +dist + +# dependencies +node_modules/ +.snowpack/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store diff --git a/examples/with-markdown-plugins/.npmrc b/examples/with-markdown-plugins/.npmrc new file mode 100644 index 000000000..0cc653b2c --- /dev/null +++ b/examples/with-markdown-plugins/.npmrc @@ -0,0 +1,2 @@ +## force pnpm to hoist +shamefully-hoist = true
\ No newline at end of file diff --git a/examples/with-markdown-plugins/astro.config.mjs b/examples/with-markdown-plugins/astro.config.mjs new file mode 100644 index 000000000..9057b5c2f --- /dev/null +++ b/examples/with-markdown-plugins/astro.config.mjs @@ -0,0 +1,25 @@ +export default { + // projectRoot: '.', // Where to resolve all URLs relative to. Useful if you have a monorepo project. + // pages: './src/pages', // Path to Astro components, pages, and data + // dist: './dist', // When running `astro build`, path to final static output + // public: './public', // A folder of static files Astro will copy to the root. Useful for favicons, images, and other files that don’t need processing. + buildOptions: { + site: 'http://example.com', // Your public domain, e.g.: https://my-site.dev/. Used to generate sitemaps and canonical URLs. + // sitemap: true, // Generate sitemap (set to "false" to disable) + }, + markdownOptions: { + remarkPlugins: [ + 'remark-code-titles', + 'remark-slug', + ['remark-autolink-headings', { behavior: 'prepend' }], + ], + rehypePlugins: [ + ['rehype-toc', { headings: ["h2", "h3"] }], + ['rehype-add-classes', { 'h1,h2,h3': 'title', }], + ] + }, + devOptions: { + // port: 3000, // The port to run the dev server on. + // tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js' + }, +}; diff --git a/examples/with-markdown-plugins/package.json b/examples/with-markdown-plugins/package.json new file mode 100644 index 000000000..f37b72225 --- /dev/null +++ b/examples/with-markdown-plugins/package.json @@ -0,0 +1,20 @@ +{ + "name": "@example/with-markdown-plugins", + "version": "0.0.2", + "private": true, + "scripts": { + "start": "astro dev", + "build": "astro build" + }, + "devDependencies": { + "astro": "^0.15.0", + "rehype-add-classes": "^1.0.0", + "rehype-toc": "^3.0.2", + "remark-autolink-headings": "^6.0.1", + "remark-code-titles": "^0.1.2", + "remark-slug": "^6.0.0" + }, + "snowpack": { + "workspaceRoot": "../.." + } +} diff --git a/examples/with-markdown-plugins/public/favicon.svg b/examples/with-markdown-plugins/public/favicon.svg new file mode 100644 index 000000000..542f90aec --- /dev/null +++ b/examples/with-markdown-plugins/public/favicon.svg @@ -0,0 +1,11 @@ +<svg width="256" height="256" fill="none" xmlns="http://www.w3.org/2000/svg"> + <style> + #flame { fill: #FF5D01; } + #a { fill: #000014; } + @media (prefers-color-scheme: dark) { + #a { fill: #fff; } + } + </style> + <path id="a" fill-rule="evenodd" clip-rule="evenodd" d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z" /> + <path id="flame" fill-rule="evenodd" clip-rule="evenodd" d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z" /> +</svg> diff --git a/examples/with-markdown-plugins/public/global.css b/examples/with-markdown-plugins/public/global.css new file mode 100644 index 000000000..f1e536546 --- /dev/null +++ b/examples/with-markdown-plugins/public/global.css @@ -0,0 +1,53 @@ +body { + font-family: system-ui; +} + +.content { + max-width: 640px; + margin: 40px auto; + padding: 0 20px; +} + +.title { + position: relative; +} +.title a { + position: absolute; + display: block; + height: 100%; + width: 100%; + color: inherit; +} + +.title a:before { + position: absolute; + right: 100%; + display: block; + content: '#'; + margin-right: 0.2em; + visibility: hidden; + opacity: 0.5; +} + +.title:hover a:before { + visibility: visible; +} + +.remark-code-title, +pre[class^="language-"] { + padding: 10px; + margin: 0; +} + +.remark-code-title { + border-bottom: 1px solid rgba(0,0,0,.05); + border-radius: 4px 4px 0 0; + background: rgba(0,0,0,.08); + font-family: monospace; + font-weight: bold; +} + +pre[class^="language-"] { + background: rgba(0,0,0,.05); + border-radius: 0 0 4px 4px; +} diff --git a/examples/with-markdown-plugins/src/layouts/main.astro b/examples/with-markdown-plugins/src/layouts/main.astro new file mode 100644 index 000000000..d324d2017 --- /dev/null +++ b/examples/with-markdown-plugins/src/layouts/main.astro @@ -0,0 +1,32 @@ +--- +const { content } = Astro.props; +--- + +<html> + <head> + <meta charset="utf-8" /> + <title>{content.title}</title> + <link rel="stylesheet" href="/global.css" /> + <style> + .nav { + border-bottom: 1px solid #ccc; + margin-bottom: 40px; + padding-bottom: 20px; + } + .nav > * + * { + margin-left: 10px; + } + </style> + </head> + <body> + <main class="content"> + <header> + <nav class="nav"> + <a href="/">Home</a> + <a href="/about">About</a> + </nav> + </header> + <slot /> + </main> + </body> +</html> diff --git a/examples/with-markdown-plugins/src/pages/about.astro b/examples/with-markdown-plugins/src/pages/about.astro new file mode 100644 index 000000000..c313f98a9 --- /dev/null +++ b/examples/with-markdown-plugins/src/pages/about.astro @@ -0,0 +1,20 @@ +--- +import { Markdown } from 'astro/components'; +import MainLayout from '../layouts/main.astro' +--- + +<MainLayout content={{ title: "About" }}> + <Markdown> + # About + + Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + + Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + + ## My story + + Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + + Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + </Markdown> +</MainLayout> diff --git a/examples/with-markdown-plugins/src/pages/index.md b/examples/with-markdown-plugins/src/pages/index.md new file mode 100644 index 000000000..a6f8879a8 --- /dev/null +++ b/examples/with-markdown-plugins/src/pages/index.md @@ -0,0 +1,34 @@ +--- +layout: ../layouts/main.astro +title: Asto with Remark Plugins +--- + +# Heading 1 + +Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + +## Heading 2 + +Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + +### Heading 3 + +Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + +### Heading 3 + +Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut. + +```jsx:file.jsx +import Router from 'next/router' + +function MyComponent() { + const [show, setShow] = useState(false) + + useEffect(() => { + console.log(2) + }, []) + + return <>...</> +} +``` diff --git a/packages/astro/package.json b/packages/astro/package.json index 28b3b3f56..ebec27310 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -52,7 +52,6 @@ "@babel/generator": "^7.13.9", "@babel/parser": "^7.13.15", "@babel/traverse": "^7.13.15", - "@silvenon/remark-smartypants": "^1.0.0", "@snowpack/plugin-postcss": "^1.4.3", "@snowpack/plugin-sass": "^1.4.0", "acorn": "^7.4.0", @@ -67,14 +66,12 @@ "fast-xml-parser": "^3.19.0", "fdir": "^5.0.0", "find-up": "^5.0.0", - "gray-matter": "^4.0.2", + "unified": "^9.2.1", "gzip-size": "^6.0.0", "hast-to-hyperscript": "~9.0.0", "kleur": "^4.1.4", "locate-character": "^2.0.5", "magic-string": "^0.25.3", - "mdast-util-mdx": "^0.1.1", - "micromark-extension-mdxjs": "^0.3.0", "mime": "^2.5.2", "moize": "^6.0.1", "node-fetch": "^2.6.1", @@ -82,10 +79,6 @@ "postcss": "^8.2.15", "postcss-icss-keyframes": "^0.2.1", "prismjs": "^1.23.0", - "remark-footnotes": "^3.0.0", - "remark-gfm": "^1.0.0", - "remark-parse": "^9.0.0", - "remark-rehype": "^8.1.0", "resolve": "^1.20.0", "rollup": "^2.43.1", "rollup-plugin-terser": "^7.0.2", diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 1fbdd6282..bfb338cdc 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -1,4 +1,5 @@ import type { ImportSpecifier, ImportDefaultSpecifier, ImportNamespaceSpecifier } from '@babel/types'; +import type { AstroMarkdownOptions } from '@astrojs/markdown-support' export interface AstroConfigRaw { dist: string; @@ -9,12 +10,7 @@ export interface AstroConfigRaw { jsx?: string; } -export interface AstroMarkdownOptions { - /** Enable or disable footnotes syntax extension */ - footnotes: boolean; - /** Enable or disable GitHub-flavored Markdown syntax extension */ - gfm: boolean; -} +export { AstroMarkdownOptions } export interface AstroConfig { dist: string; projectRoot: URL; diff --git a/packages/astro/src/compiler/codegen/index.ts b/packages/astro/src/compiler/codegen/index.ts index 0b9780e16..b34077269 100644 --- a/packages/astro/src/compiler/codegen/index.ts +++ b/packages/astro/src/compiler/codegen/index.ts @@ -543,7 +543,6 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile const { $scope: scopedClassName } = state.markers.insideMarkdown as Record<'$scope', any>; let { content: rendered } = await renderMarkdown(dedent(md), { ...(markdownOptions as AstroMarkdownOptions), - mode: 'astro-md', $: { scopedClassName: scopedClassName && scopedClassName.slice(1, -1) }, }); diff --git a/packages/astro/src/compiler/index.ts b/packages/astro/src/compiler/index.ts index 0f12cc7f0..f612e6165 100644 --- a/packages/astro/src/compiler/index.ts +++ b/packages/astro/src/compiler/index.ts @@ -3,7 +3,7 @@ import type { CompileResult, TransformResult } from '../@types/astro'; import type { CompileOptions } from '../@types/compiler.js'; import path from 'path'; -import { renderMarkdownWithFrontmatter } from '@astrojs/markdown-support'; +import { MarkdownRenderingOptions, renderMarkdownWithFrontmatter } from '@astrojs/markdown-support'; import { parse } from '@astrojs/parser'; import { transform } from './transform/index.js'; @@ -42,12 +42,12 @@ export async function convertAstroToJsx(template: string, opts: ConvertAstroOpti /** * .md -> .astro source */ -export async function convertMdToAstroSource(contents: string, { filename }: { filename: string }): Promise<string> { +export async function convertMdToAstroSource(contents: string, { filename }: { filename: string }, opts?: MarkdownRenderingOptions): Promise<string> { let { content, frontmatter: { layout, ...frontmatter }, ...data - } = await renderMarkdownWithFrontmatter(contents); + } = await renderMarkdownWithFrontmatter(contents, opts); if (frontmatter['astro'] !== undefined) { throw new Error(`"astro" is a reserved word but was used as a frontmatter value!\n\tat ${filename}`); @@ -75,7 +75,7 @@ async function convertMdToJsx( contents: string, { compileOptions, filename, fileID }: { compileOptions: CompileOptions; filename: string; fileID: string } ): Promise<TransformResult> { - const raw = await convertMdToAstroSource(contents, { filename }); + const raw = await convertMdToAstroSource(contents, { filename }, compileOptions.astroConfig.markdownOptions); const convertOptions = { compileOptions, filename, fileID }; return await convertAstroToJsx(raw, convertOptions); } diff --git a/packages/astro/test/astro-markdown-plugins.test.js b/packages/astro/test/astro-markdown-plugins.test.js new file mode 100644 index 000000000..44744e5d5 --- /dev/null +++ b/packages/astro/test/astro-markdown-plugins.test.js @@ -0,0 +1,29 @@ +import { suite } from 'uvu'; +import * as assert from 'uvu/assert'; +import { doc } from './test-utils.js'; +import { setup, setupBuild } from './helpers.js'; + +const MarkdownPlugin = suite('Astro Markdown plugin tests'); + +setup(MarkdownPlugin, './fixtures/astro-markdown-plugins'); +setupBuild(MarkdownPlugin, './fixtures/astro-markdown-plugins'); + +MarkdownPlugin('Can render markdown with plugins', async ({ runtime }) => { + const result = await runtime.load('/'); + if (result.error) throw new Error(result.error); + + const $ = doc(result.contents); + assert.equal($('.toc').length, 1, 'Added a TOC'); + assert.ok($('#hello-world').hasClass('title'), 'Added .title to h1'); +}); + +MarkdownPlugin('Can render Astro <Markdown> with plugins', async ({ runtime }) => { + const result = await runtime.load('/astro'); + if (result.error) throw new Error(result.error); + + const $ = doc(result.contents); + assert.equal($('.toc').length, 1, 'Added a TOC'); + assert.ok($('#hello-world').hasClass('title'), 'Added .title to h1'); +}) + +MarkdownPlugin.run(); diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs b/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs new file mode 100644 index 000000000..c236c9215 --- /dev/null +++ b/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs @@ -0,0 +1,19 @@ +export default { + renderers: [ + '@astrojs/renderer-preact' + ], + markdownOptions: { + remarkPlugins: [ + 'remark-code-titles', + 'remark-slug', + ['remark-autolink-headings', { behavior: 'prepend' }], + ], + rehypePlugins: [ + ['rehype-toc', { headings: ["h2", "h3"] }], + ['rehype-add-classes', { 'h1,h2,h3': 'title', }], + ] + }, + buildOptions: { + sitemap: false, + }, +}; diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/snowpack.config.json b/packages/astro/test/fixtures/astro-markdown-plugins/snowpack.config.json new file mode 100644 index 000000000..8f034781d --- /dev/null +++ b/packages/astro/test/fixtures/astro-markdown-plugins/snowpack.config.json @@ -0,0 +1,3 @@ +{ + "workspaceRoot": "../../../../../" +} diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/src/layouts/content.astro b/packages/astro/test/fixtures/astro-markdown-plugins/src/layouts/content.astro new file mode 100644 index 000000000..925a243a9 --- /dev/null +++ b/packages/astro/test/fixtures/astro-markdown-plugins/src/layouts/content.astro @@ -0,0 +1,10 @@ +<html> + <head> + <!-- Head Stuff --> + </head> + <body> + <div class="container"> + <slot></slot> + </div> + </body> +</html> diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/astro.astro b/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/astro.astro new file mode 100644 index 000000000..a05a7c3ff --- /dev/null +++ b/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/astro.astro @@ -0,0 +1,10 @@ +--- +import { Markdown } from 'astro/components'; +import Layout from '../layouts/content.astro'; +--- + +<Layout> + <Markdown> + # Hello world + </Markdown> +</Layout> diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/index.md b/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/index.md new file mode 100644 index 000000000..832ccf0bc --- /dev/null +++ b/packages/astro/test/fixtures/astro-markdown-plugins/src/pages/index.md @@ -0,0 +1,5 @@ +--- +layout: ../layouts/content.astro +--- + +# Hello world diff --git a/packages/markdown-support/package.json b/packages/markdown-support/package.json index 8be2aa4a4..550fef7a7 100644 --- a/packages/markdown-support/package.json +++ b/packages/markdown-support/package.json @@ -2,7 +2,7 @@ "name": "@astrojs/markdown-support", "version": "0.1.2", "main": "./dist/index.js", - "type": "commonjs", + "type": "module", "repository": { "type": "git", "url": "https://github.com/snowpackjs/astro.git", @@ -16,6 +16,18 @@ "build": "astro-scripts build --format cjs \"src/**/*.ts\" && tsc -p tsconfig.json", "dev": "astro-scripts dev \"src/**/*.ts\"" }, + "dependencies": { + "@silvenon/remark-smartypants": "^1.0.0", + "gray-matter": "^4.0.2", + "mdast-util-mdx-expression": "^1.0.0", + "micromark-extension-mdx-expression": "^1.0.0", + "remark-footnotes": "^3.0.0", + "remark-gfm": "^1.0.0", + "remark-parse": "^9.0.0", + "remark-rehype": "^8.1.0", + "unified": "^9.2.1", + "unist-util-map": "^3.0.0" + }, "devDependencies": { "@types/github-slugger": "^1.3.0", "github-slugger": "^1.3.0", diff --git a/packages/markdown-support/src/index.ts b/packages/markdown-support/src/index.ts index 08f171c3c..f311efa7c 100644 --- a/packages/markdown-support/src/index.ts +++ b/packages/markdown-support/src/index.ts @@ -1,62 +1,67 @@ -import type { AstroMarkdownOptions } from './types'; +import type { AstroMarkdownOptions, MarkdownRenderingOptions } from './types'; import createCollectHeaders from './rehype-collect-headers.js'; import scopedStyles from './remark-scoped-styles.js'; -import { remarkCodeBlock, rehypeCodeBlock } from './codeblock.js'; +import remarkExpressions from './remark-expressions.js'; +import rehypeExpressions from './rehype-expressions.js'; +import { rehypeCodeBlock } from './codeblock.js'; +import { loadPlugins } from './load-plugins.js'; import raw from 'rehype-raw'; import unified from 'unified'; import markdown from 'remark-parse'; import markdownToHtml from 'remark-rehype'; -// import smartypants from '@silvenon/remark-smartypants'; import rehypeStringify from 'rehype-stringify'; -export interface MarkdownRenderingOptions extends Partial<AstroMarkdownOptions> { - $?: { - scopedClassName: string | null; - }; - mode: 'md' | 'astro-md'; -} +export { AstroMarkdownOptions, MarkdownRenderingOptions }; /** Internal utility for rendering a full markdown file and extracting Frontmatter data */ export async function renderMarkdownWithFrontmatter(contents: string, opts?: MarkdownRenderingOptions | null) { // Dynamic import to ensure that "gray-matter" isn't built by Snowpack const { default: matter } = await import('gray-matter'); const { data: frontmatter, content } = matter(contents); - const value = await renderMarkdown(content, { ...opts, mode: 'md' }); + const value = await renderMarkdown(content, opts); return { ...value, frontmatter }; } /** Shared utility for rendering markdown */ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOptions | null) { - const { $: { scopedClassName = null } = {}, mode = 'astro-md', footnotes: useFootnotes = true, gfm: useGfm = true } = opts ?? {}; + const { $: { scopedClassName = null } = {}, footnotes: useFootnotes = true, gfm: useGfm = true, remarkPlugins = [], rehypePlugins = [] } = opts ?? {}; const { headers, rehypeCollectHeaders } = createCollectHeaders(); + let parser = unified().use(markdown).use([remarkExpressions, { addResult: true }]); - let parser = unified().use(markdown).use(remarkCodeBlock()); + if (remarkPlugins.length === 0) { + if (useGfm) { + remarkPlugins.push('remark-gfm'); + } - if (scopedClassName) { - parser = parser.use(scopedStyles(scopedClassName)); - } + if (useFootnotes) { + remarkPlugins.push('remark-footnotes'); + } - if (useGfm) { - const { default: gfm } = await import('remark-gfm'); - parser = parser.use(gfm); + remarkPlugins.push('@silvenon/remark-smartypants'); } + const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins)); + const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins)); - if (useFootnotes) { - const { default: footnotes } = await import('remark-footnotes'); - parser = parser.use(footnotes); + loadedRemarkPlugins.forEach(([plugin, opts]) => { + parser.use(plugin, opts); + }); + + if (scopedClassName) { + parser.use(scopedStyles(scopedClassName)); } + parser.use(markdownToHtml, { allowDangerousHtml: true, passThrough: ['raw', 'mdxTextExpression'] }); + parser.use(rehypeExpressions); + + loadedRehypePlugins.forEach(([plugin, opts]) => { + parser.use(plugin, opts); + }); + let result: string; try { - const vfile = await parser - .use(markdownToHtml, { allowDangerousHtml: true, passThrough: ['raw'] }) - .use(raw) - .use(rehypeCollectHeaders) - .use(rehypeCodeBlock()) - .use(rehypeStringify) - .process(content); + const vfile = await parser.use(raw).use(rehypeCollectHeaders).use(rehypeCodeBlock()).use(rehypeStringify, { entities: { useNamedReferences: true }}).process(content); result = vfile.contents.toString(); } catch (err) { throw err; diff --git a/packages/markdown-support/src/load-plugins.ts b/packages/markdown-support/src/load-plugins.ts new file mode 100644 index 000000000..52bc287f8 --- /dev/null +++ b/packages/markdown-support/src/load-plugins.ts @@ -0,0 +1,27 @@ +import unified from "unified"; +import type { Plugin, UnifiedPluginImport } from "./types"; + +async function importPlugin(p: string | UnifiedPluginImport): UnifiedPluginImport { + if (typeof p === 'string') { + return await import(p); + } + + return await p; +} + +export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin] | [unified.Plugin, unified.Settings]>[] { + return items.map((p) => { + return new Promise((resolve, reject) => { + if (Array.isArray(p)) { + const [plugin, opts] = p; + return importPlugin(plugin) + .then((m) => resolve([m.default, opts])) + .catch((e) => reject(e)); + } + + return importPlugin(p) + .then((m) => resolve([m.default])) + .catch((e) => reject(e)); + }); + }); +} diff --git a/packages/markdown-support/src/rehype-collect-headers.ts b/packages/markdown-support/src/rehype-collect-headers.ts index edfcd29bc..de9b78692 100644 --- a/packages/markdown-support/src/rehype-collect-headers.ts +++ b/packages/markdown-support/src/rehype-collect-headers.ts @@ -14,11 +14,13 @@ export default function createCollectHeaders() { depth = Number.parseInt(depth); let text = ''; + visit(node, 'text', (child) => { text += child.value; }); - let slug = slugger.slug(text); + let slug = node.properties.id || slugger.slug(text); + node.properties = node.properties || {}; node.properties.id = slug; headers.push({ depth, slug, text }); diff --git a/packages/markdown-support/src/rehype-expressions.ts b/packages/markdown-support/src/rehype-expressions.ts new file mode 100644 index 000000000..2762f54fc --- /dev/null +++ b/packages/markdown-support/src/rehype-expressions.ts @@ -0,0 +1,12 @@ +import { map } from 'unist-util-map' + +export default function rehypeExpressions(): any { + return function(node: any): any { + return map(node, (child) => { + if (child.type === 'mdxTextExpression') { + return { type: 'text', value: `{${child.value}}` } + } + return child; + }) + } +} diff --git a/packages/markdown-support/src/remark-expressions.ts b/packages/markdown-support/src/remark-expressions.ts new file mode 100644 index 000000000..1cdb37894 --- /dev/null +++ b/packages/markdown-support/src/remark-expressions.ts @@ -0,0 +1,19 @@ +import {mdxExpression} from 'micromark-extension-mdx-expression' +import {mdxExpressionFromMarkdown, mdxExpressionToMarkdown} from 'mdast-util-mdx-expression' + +function remarkExpressions(this: any, options: any) { + let settings = options || {} + let data = this.data() + + add('micromarkExtensions', mdxExpression({})) + add('fromMarkdownExtensions', mdxExpressionFromMarkdown) + add('toMarkdownExtensions', mdxExpressionToMarkdown) + + function add(field: any, value: any) { + /* istanbul ignore if - other extensions. */ + if (data[field]) data[field].push(value) + else data[field] = [value] + } +} + +export default remarkExpressions; diff --git a/packages/markdown-support/src/types.ts b/packages/markdown-support/src/types.ts index b69f7fc28..6df601ae4 100644 --- a/packages/markdown-support/src/types.ts +++ b/packages/markdown-support/src/types.ts @@ -1,6 +1,20 @@ +import unified from 'unified'; + +export type UnifiedPluginImport = Promise<{ default: unified.Plugin }>; +export type Plugin = string | [string, unified.Settings] | UnifiedPluginImport | [UnifiedPluginImport, unified.Settings]; + export interface AstroMarkdownOptions { /** Enable or disable footnotes syntax extension */ footnotes: boolean; /** Enable or disable GitHub-flavored Markdown syntax extension */ gfm: boolean; + remarkPlugins: Plugin[]; + rehypePlugins: Plugin[]; +} + +export interface MarkdownRenderingOptions extends Partial<AstroMarkdownOptions> { + /** @internal */ + $?: { + scopedClassName: string | null; + }; } @@ -403,6 +403,11 @@ dependencies: purgecss "^3.1.3" +"@jsdevtools/rehype-toc@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@jsdevtools/rehype-toc/-/rehype-toc-3.0.2.tgz#29c32e6b40cd4b5dafd96cb90d5057ac5dab4a51" + integrity sha512-n5JEf16Wr4mdkRMZ8wMP/wN9/sHmTjRPbouXjJH371mZ2LEGDl72t8tEsMRNFerQN/QJtivOxqK1frdGa4QK5Q== + "@lerna/add@4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@lerna/add/-/add-4.0.0.tgz" @@ -1361,6 +1366,13 @@ resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@types/acorn@^4.0.0": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.5.tgz#e29fdf884695e77be4e99e67d748f5147255752d" + integrity sha512-603sPiZ4GVRHPvn6vNgEAvJewKsy+zwRWYS2MeIMemgoAtcjlw2G3lALxrb9OPA17J28bkB71R33yXlQbUatCA== + dependencies: + "@types/estree" "*" + "@types/babel-types@*", "@types/babel-types@^7.0.0": version "7.0.9" resolved "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.9.tgz" @@ -1404,6 +1416,18 @@ resolved "https://registry.npmjs.org/@types/degit/-/degit-2.8.2.tgz" integrity sha512-wUOqW7nZ8AYgm4OKa9i/RD72CrU/X4Vfx2Oez/51qC3RMgPyF3ZUQVLFjV8McV6/ivR7lOlfidRFgGZj7MZe1A== +"@types/estree-jsx@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-0.0.1.tgz#c36d7a1afeb47a95a8ee0b7bc8bc705db38f919d" + integrity sha512-gcLAYiMfQklDCPjQegGn0TBAn9it05ISEsEhlKQUddIk7o2XDokOcTN7HBO8tznM0D9dGezvHEfRZBfZf6me0A== + dependencies: + "@types/estree" "*" + +"@types/estree@*", "@types/estree@^0.0.48": + version "0.0.48" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74" + integrity sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew== + "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" @@ -1721,7 +1745,7 @@ acorn-globals@^3.0.0: dependencies: acorn "^4.0.4" -acorn-jsx@^5.0.0, acorn-jsx@^5.3.1: +acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== @@ -1755,11 +1779,6 @@ acorn@^7.0.0, acorn@^7.4.0: resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.0: - version "8.2.4" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz" - integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== - add-stream@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz" @@ -2217,7 +2236,7 @@ bluebird@^3.7.2: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -boolbase@^1.0.0: +boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= @@ -2471,6 +2490,11 @@ camelcase@^2.0.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + camelcase@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz" @@ -2814,7 +2838,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -comma-separated-tokens@^1.0.0: +comma-separated-tokens@^1.0.0, comma-separated-tokens@^1.0.2: version "1.0.8" resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== @@ -3099,6 +3123,11 @@ css-select@^4.1.2: domutils "^2.6.0" nth-check "^2.0.0" +css-selector-parser@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" + integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== + css-unit-converter@^1.1.1: version "1.1.2" resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz" @@ -3927,11 +3956,6 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== -estree-util-is-identifier-name@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-1.1.0.tgz" - integrity sha512-OVJZ3fGGt9By77Ix9NhaRbzfbDV/2rx9EP7YIDJTmsZSEc5kYn2vWcNccYyahJL2uAQZK2a5Or2i0wtIKTPoRQ== - estree-util-value-to-estree@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-1.2.0.tgz" @@ -3939,6 +3963,14 @@ estree-util-value-to-estree@^1.2.0: dependencies: is-plain-obj "^3.0.0" +estree-util-visit@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-1.1.0.tgz#c0ea7942c40ac7889a77b57a11e92f987744bc6f" + integrity sha512-3lXJ4Us9j8TUif9cWcQy81t9p5OLasnDuuhrFiqb+XstmKC1d1LmrQWYsY49/9URcfHE64mPypDBaNK9NwWDPQ== + dependencies: + "@types/estree-jsx" "^0.0.1" + "@types/unist" "^2.0.0" + estree-walker@^0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz" @@ -4434,7 +4466,7 @@ gitconfiglocal@^1.0.0: dependencies: ini "^1.3.2" -github-slugger@^1.2.1, github-slugger@^1.3.0: +github-slugger@^1.0.0, github-slugger@^1.2.1, github-slugger@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz" integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q== @@ -4720,6 +4752,11 @@ hast-util-from-parse5@^6.0.0: vfile-location "^3.2.0" web-namespaces "^1.0.0" +hast-util-has-property@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz#9f137565fad6082524b382c1e7d7d33ca5059f36" + integrity sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg== + hast-util-is-element@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz" @@ -4747,6 +4784,23 @@ hast-util-raw@^6.1.0: xtend "^4.0.0" zwitch "^1.0.0" +hast-util-select@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hast-util-select/-/hast-util-select-1.0.1.tgz#9f1591efa62ba0bdf5ea4298b301aaae1dad612d" + integrity sha1-nxWR76YroL316kKYswGqrh2tYS0= + dependencies: + camelcase "^3.0.0" + comma-separated-tokens "^1.0.2" + css-selector-parser "^1.3.0" + hast-util-has-property "^1.0.0" + hast-util-is-element "^1.0.0" + hast-util-whitespace "^1.0.0" + not "^0.1.0" + nth-check "^1.0.1" + property-information "^3.1.0" + space-separated-tokens "^1.1.0" + zwitch "^1.0.0" + hast-util-to-html@^7.1.1: version "7.1.3" resolved "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz" @@ -6235,39 +6289,13 @@ mdast-util-gfm@^0.1.0: mdast-util-gfm-task-list-item "^0.1.0" mdast-util-to-markdown "^0.6.1" -mdast-util-mdx-expression@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-0.1.1.tgz" - integrity sha512-SoO8y1B9NjMOYlNdwXMchuTVvqSTlUmXm1P5QvZNPv7OH7aa8qJV+3aA+vl1DHK9Vk1uZAlgwokjvDQhS6bINA== - dependencies: - strip-indent "^3.0.0" - -mdast-util-mdx-jsx@~0.1.0: - version "0.1.4" - resolved "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-0.1.4.tgz" - integrity sha512-67KOAvCmypBSpr+AJEAVQg1Obig5Wnguo4ETTxASe5WVP4TLt57bZjDX/9EW5sWYQsO4gPqLxkUOlypVn5rkhg== - dependencies: - mdast-util-to-markdown "^0.6.0" - parse-entities "^2.0.0" - stringify-entities "^3.1.0" - unist-util-remove-position "^3.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - -mdast-util-mdx@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-0.1.1.tgz" - integrity sha512-9nncdnHNYSb4HNxY3AwE6gU632jhbXsDGXe9PkkJoEawYWJ8tTwmEOHGlGa2TCRidtkd6FF5I8ogDU9pTDlQyA== +mdast-util-mdx-expression@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.0.0.tgz#588449f13c037762c59a5c3dd342c1c0d51f4092" + integrity sha512-lQ6zzJwGt2/smaC3Sv74aJHej1sk9rO8+unfbP69Iq0G/Nbs9gTAzcjTNNXS8P/mdAPlxfA+F/vdxhxWK9ZzJQ== dependencies: - mdast-util-mdx-expression "~0.1.0" - mdast-util-mdx-jsx "~0.1.0" - mdast-util-mdxjs-esm "~0.1.0" - mdast-util-to-markdown "^0.6.1" - -mdast-util-mdxjs-esm@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-0.1.1.tgz" - integrity sha512-kBiYeashz+nuhfv+712nc4THQhzXIH2gBFUDbuLxuDCqU/fZeg+9FAcdRBx9E13dkpk1p2Xwufzs3wsGJ+mISQ== + "@types/estree-jsx" "^0.0.1" + strip-indent "^4.0.0" mdast-util-to-hast@^10.2.0: version "10.2.0" @@ -6295,6 +6323,11 @@ mdast-util-to-markdown@^0.6.0, mdast-util-to-markdown@^0.6.1, mdast-util-to-mark repeat-string "^1.0.0" zwitch "^1.0.0" +mdast-util-to-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== + mdast-util-to-string@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz" @@ -6442,50 +6475,77 @@ micromark-extension-gfm@^0.3.0: micromark-extension-gfm-tagfilter "~0.3.0" micromark-extension-gfm-task-list-item "~0.3.0" -micromark-extension-mdx-expression@^0.3.0, micromark-extension-mdx-expression@^0.3.2, micromark-extension-mdx-expression@~0.3.0: - version "0.3.2" - resolved "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-0.3.2.tgz" - integrity sha512-Sh8YHLSAlbm/7TZkVKEC4wDcJE8XhVpZ9hUXBue1TcAicrrzs/oXu7PHH3NcyMemjGyMkiVS34Y0AHC5KG3y4A== +micromark-extension-mdx-expression@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.0.tgz#384758ff635c1942b01c7854a44a51dbfa68e56e" + integrity sha512-a433Der9h4ZCiK7MZhox45Dt6oD0Nm1v2GFt+PQjlgW4Ydt8OTOIgKOaurSXwsy5vp+PohT7W1PUx3Bv4VVcxw== dependencies: - micromark "~2.11.0" - vfile-message "^2.0.0" + micromark-factory-mdx-expression "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" -micromark-extension-mdx-jsx@~0.3.0: - version "0.3.3" - resolved "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-0.3.3.tgz" - integrity sha512-kG3VwaJlzAPdtIVDznfDfBfNGMTIzsHqKpTmMlew/iPnUCDRNkX+48ElpaOzXAtK5axtpFKE3Hu3VBriZDnRTQ== +micromark-factory-mdx-expression@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.0.tgz#b05f2120f9518e95d31093a5918d4ef837003818" + integrity sha512-UbIjQgRdeMdkKt9rkbjyYYJdegccu27ynI7JIHsbNAjtHQGrnsx3bBzJA5NrSjOmzzLaLr2FoVaynR2DwwTCAQ== + dependencies: + micromark-factory-whitespace "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-position-from-estree "^1.0.0" + vfile-message "^3.0.0" + +micromark-factory-space@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633" + integrity sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew== dependencies: - estree-util-is-identifier-name "^1.0.0" - micromark "~2.11.0" - micromark-extension-mdx-expression "^0.3.2" - vfile-message "^2.0.0" + micromark-util-character "^1.0.0" + micromark-util-types "^1.0.0" -micromark-extension-mdx-md@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-0.1.1.tgz" - integrity sha512-emlFQEyfx/2aPhwyEqeNDfKE6jPH1cvLTb5ANRo4qZBjaUObnzjLRdzK8RJ4Xc8+/dOmKN8TTRxFnOYF5/EAwQ== +micromark-factory-whitespace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c" + integrity sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" -micromark-extension-mdxjs-esm@~0.3.0: - version "0.3.1" - resolved "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-0.3.1.tgz" - integrity sha512-tuLgcELrgY1a5tPxjk+MrI3BdYtwW67UaHZdzKiDYD8loNbxwIscfdagI6A2BKuAkrfeyHF6FW3B8KuDK3ZMXw== +micromark-util-character@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.0.0.tgz#a6f2f5a9ad4a35a7888223b5fce901f00189f0e8" + integrity sha512-VdfDsHtUn/ocN2hGBkMunHHWcaN33llgwU0bmw2LA0tY1JvVkjHGvdiQSIk0pS3XeGCJLT6syS5i8y+1xbwDnQ== dependencies: - micromark "~2.11.0" - micromark-extension-mdx-expression "^0.3.0" - vfile-message "^2.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" -micromark-extension-mdxjs@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-0.3.0.tgz" - integrity sha512-NQuiYA0lw+eFDtSG4+c7ao3RG9dM4P0Kx/sn8OLyPhxtIc6k+9n14k5VfLxRKfAxYRTo8c5PLZPaRNmslGWxJw== +micromark-util-events-to-acorn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.0.0.tgz#b4628ce6cc913888f5b47ae739e4035fd8472ecb" + integrity sha512-1e6kdnEdqIDge9EX/6T/F2QDnV482J+IOhBnTV4MP/yD/ncCfDeWSQQuomRinlgEZxUhJ6tdgOldRVZkrw+qFg== dependencies: - acorn "^8.0.0" - acorn-jsx "^5.0.0" - micromark "~2.11.0" - micromark-extension-mdx-expression "~0.3.0" - micromark-extension-mdx-jsx "~0.3.0" - micromark-extension-mdx-md "~0.1.0" - micromark-extension-mdxjs-esm "~0.3.0" + "@types/acorn" "^4.0.0" + "@types/estree" "^0.0.48" + estree-util-visit "^1.0.0" + micromark-util-types "^1.0.0" + vfile-message "^3.0.0" + +micromark-util-symbol@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.0.tgz#91cdbcc9b2a827c0129a177d36241bcd3ccaa34d" + integrity sha512-NZA01jHRNCt4KlOROn8/bGi6vvpEmlXld7EHcRH+aYWUfL3Wc8JLUNNlqUMKa0hhz6GrpUWsHtzPmKof57v0gQ== + +micromark-util-types@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.0.tgz#0ebdfaea3fa7c15fc82b1e06ea1ef0152d0fb2f0" + integrity sha512-psf1WAaP1B77WpW4mBGDkTr+3RsPuDAgsvlP47GJzbH1jmjH8xjOx7Z6kp84L8oqHmy5pYO3Ev46odosZV+3AA== micromark@^2.11.3, micromark@~2.11.0, micromark@~2.11.3: version "2.11.4" @@ -6542,7 +6602,7 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -min-indent@^1.0.0: +min-indent@^1.0.0, min-indent@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== @@ -6922,6 +6982,11 @@ normalize-url@^4.1.0: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== +not@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/not/-/not-0.1.0.tgz#c9691c1746c55dcfbe54cbd8bd4ff041bc2b519d" + integrity sha1-yWkcF0bFXc++VMvYvU/wQbwrUZ0= + npm-bundled@^1.1.1: version "1.1.2" resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz" @@ -7035,6 +7100,13 @@ npmlog@^4.1.2: gauge "~2.7.3" set-blocking "~2.0.0" +nth-check@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + nth-check@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz" @@ -7899,6 +7971,11 @@ promzard@^0.3.0: dependencies: read "1" +property-information@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-3.2.0.tgz#fd1483c8fbac61808f5fe359e7693a1f48a58331" + integrity sha1-/RSDyPusYYCPX+NZ52k6H0ilgzE= + property-information@^5.0.0, property-information@^5.3.0: version "5.6.0" resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz" @@ -8406,6 +8483,13 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" +rehype-add-classes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rehype-add-classes/-/rehype-add-classes-1.0.0.tgz#3d8b37b13ce06e2eb8681b33ccf1c2995611a33b" + integrity sha512-Iz8t2KhCNAL+0AHKjxb+kVwsHk/pI3Cy4k0R70ZGzoQiZ7WQm3o8+3odJkMhFRfcNIK1lNShIHEdC90H5LwLdg== + dependencies: + hast-util-select "^1.0.1" + rehype-parse@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz" @@ -8428,6 +8512,28 @@ rehype-stringify@^8.0.0: dependencies: hast-util-to-html "^7.1.1" +rehype-toc@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rehype-toc/-/rehype-toc-3.0.2.tgz#0373e2abafddeb0606ee38229ff6714da6d86d68" + integrity sha512-DMt376+4i1KJGgHJL7Ezd65qKkJ7Eqp6JSB47BJ90ReBrohI9ufrornArM6f4oJjP2E2DVZZHufWucv/9t7GUQ== + dependencies: + "@jsdevtools/rehype-toc" "3.0.2" + +remark-autolink-headings@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/remark-autolink-headings/-/remark-autolink-headings-6.0.1.tgz#074470b8ec7714a0f06fa151e293152bf9723df9" + integrity sha512-LTV5G5NMjypHEr14tMNJ36yrP+xwT7mejJelZOPXKiF5WvRH9o36zXnr2QGqfms2yVASNpDaC9NBOwKlJJKuQw== + dependencies: + extend "^3.0.0" + unist-util-visit "^2.0.0" + +remark-code-titles@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/remark-code-titles/-/remark-code-titles-0.1.2.tgz#ae41b47c517eae4084c761a59a60df5f0bd54aa8" + integrity sha512-KsHQbaI4FX8Ozxqk7YErxwmBiveUqloKuVqyPG2YPLHojpgomodWgRfG4B+bOtmn/5bfJ8khw4rR0lvgVFl2Uw== + dependencies: + unist-util-visit "^1.4.0" + remark-footnotes@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz" @@ -8458,6 +8564,15 @@ remark-rehype@^8.1.0: dependencies: mdast-util-to-hast "^10.2.0" +remark-slug@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.0.0.tgz#2b54a14a7b50407a5e462ac2f376022cce263e2c" + integrity sha512-ln67v5BrGKHpETnm6z6adlJPhESFJwfuZZ3jrmi+lKTzeZxh2tzFzUfDD4Pm2hRGOarHLuGToO86MNMZ/hA67Q== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^2.0.0" + repeat-string@^1.0.0, repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" @@ -9109,7 +9224,7 @@ sourcemap-codec@^1.4.4: resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== -space-separated-tokens@^1.0.0: +space-separated-tokens@^1.0.0, space-separated-tokens@^1.1.0: version "1.1.5" resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== @@ -9315,7 +9430,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-entities@^3.0.1, stringify-entities@^3.1.0: +stringify-entities@^3.0.1: version "3.1.0" resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.1.0.tgz" integrity sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg== @@ -9410,6 +9525,13 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" @@ -9983,6 +10105,11 @@ unist-util-generated@^1.0.0: resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz" integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== +unist-util-is@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd" + integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== + unist-util-is@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz" @@ -9993,6 +10120,13 @@ unist-util-is@^5.0.0: resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.0.tgz" integrity sha512-pWspZ+AvTqYbC+xWeRmzGqbcY8Na08Eowlfs2xchWTYot8vBBAq+syrE/LWS0bw1D/JOu4lwzDbEb6Mz13tK+g== +unist-util-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unist-util-map/-/unist-util-map-3.0.0.tgz#ec4c3e4f3f65f559b6c232087af2a470f3e5db89" + integrity sha512-kyPbOAlOPZpytdyquF1g6qYpAjkpMpSPtR7TAj4SOQWSJfQ/LN+IFI2oWBvkxzhsPKxiMKZcgpp5ihZLLvNl6g== + dependencies: + "@types/unist" "^2.0.0" + unist-util-modify-children@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-2.0.0.tgz" @@ -10000,18 +10134,18 @@ unist-util-modify-children@^2.0.0: dependencies: array-iterate "^1.0.0" +unist-util-position-from-estree@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.0.tgz#31f5e0f771629ec718443765e10ea590231760c7" + integrity sha512-FveBeLp2Oc5XTn8DCX++DB4ETP8BaiRl0DuVGdD8s5I+V/boj81rBm0pNdwAixXUtGvVdsinPOT+Thy2yFrMEA== + dependencies: + "@types/unist" "^2.0.0" + unist-util-position@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz" integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== -unist-util-remove-position@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-3.0.0.tgz" - integrity sha512-17kIOuolVuK16LMb9KyMJlqdfCtlfQY5FjY3Sdo9iC7F5wqdXhNjMq0PBvMpkVNNnAmHxXssUW+rZ9T2zbP0Rg== - dependencies: - unist-util-visit "^2.0.0" - unist-util-stringify-position@^2.0.0: version "2.0.3" resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz" @@ -10019,11 +10153,25 @@ unist-util-stringify-position@^2.0.0: dependencies: "@types/unist" "^2.0.2" +unist-util-stringify-position@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz#d517d2883d74d0daa0b565adc3d10a02b4a8cde9" + integrity sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA== + dependencies: + "@types/unist" "^2.0.0" + unist-util-visit-children@^1.0.0: version "1.1.4" resolved "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-1.1.4.tgz" integrity sha512-sA/nXwYRCQVRwZU2/tQWUqJ9JSFM1X3x7JIOsIgSzrFHcfVt6NkzDtKzyxg2cZWkCwGF9CO8x4QNZRJRMK8FeQ== +unist-util-visit-parents@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9" + integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g== + dependencies: + unist-util-is "^3.0.0" + unist-util-visit-parents@^3.0.0: version "3.1.1" resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz" @@ -10040,6 +10188,13 @@ unist-util-visit-parents@^4.0.0: "@types/unist" "^2.0.0" unist-util-is "^5.0.0" +unist-util-visit@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3" + integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw== + dependencies: + unist-util-visit-parents "^2.0.0" + unist-util-visit@^2.0.0, unist-util-visit@^2.0.1: version "2.0.3" resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz" @@ -10203,6 +10358,14 @@ vfile-message@^2.0.0: "@types/unist" "^2.0.0" unist-util-stringify-position "^2.0.0" +vfile-message@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.0.1.tgz#b9bcf87cb5525e61777e0c6df07e816a577588a3" + integrity sha512-gYmSHcZZUEtYpTmaWaFJwsuUD70/rTY4v09COp8TGtOkix6gGxb/a8iTQByIY9ciTk9GwAwIXd/J9OPfM4Bvaw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile@^4.0.0: version "4.2.1" resolved "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz" |