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>
This commit is contained in:
Pavel Mineev 2021-07-01 19:55:22 +03:00 committed by GitHub
parent e773771b91
commit d3969436dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 742 additions and 145 deletions

View file

@ -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'}],
]
},
}
```

View file

@ -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
### Remark 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.
**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!
Also, Astro supports third-party plugins for Markdown. You can provide your plugins in `astro.config.mjs`.
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.
> **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'}],
]
},
};
```
You can provide names of the plugins as well as import them:
```js
// astro.config.js
export default {
markdownOptions: {
remarkPlugins: [
import('remark-slug'),
[import('remark-autolink-headings'), { behavior: 'prepend' }],
],
},
};
```
### Markdown Pages

View file

@ -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

View file

@ -0,0 +1,2 @@
## force pnpm to hoist
shamefully-hoist = true

View file

@ -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 dont 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'
},
};

View file

@ -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": "../.."
}
}

View file

@ -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>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -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;
}

View file

@ -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>

View file

@ -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>

View file

@ -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 <>...</>
}
```

View file

@ -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",

View file

@ -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;

View file

@ -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) },
});

View file

@ -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);
}

View file

@ -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();

View file

@ -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,
},
};

View file

@ -0,0 +1,3 @@
{
"workspaceRoot": "../../../../../"
}

View file

@ -0,0 +1,10 @@
<html>
<head>
<!-- Head Stuff -->
</head>
<body>
<div class="container">
<slot></slot>
</div>
</body>
</html>

View file

@ -0,0 +1,10 @@
---
import { Markdown } from 'astro/components';
import Layout from '../layouts/content.astro';
---
<Layout>
<Markdown>
# Hello world
</Markdown>
</Layout>

View file

@ -0,0 +1,5 @@
---
layout: ../layouts/content.astro
---
# Hello world

View file

@ -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",

View file

@ -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 (scopedClassName) {
parser = parser.use(scopedStyles(scopedClassName));
}
if (remarkPlugins.length === 0) {
if (useGfm) {
const { default: gfm } = await import('remark-gfm');
parser = parser.use(gfm);
remarkPlugins.push('remark-gfm');
}
if (useFootnotes) {
const { default: footnotes } = await import('remark-footnotes');
parser = parser.use(footnotes);
remarkPlugins.push('remark-footnotes');
}
remarkPlugins.push('@silvenon/remark-smartypants');
}
const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
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;

View file

@ -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));
});
});
}

View file

@ -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 });

View file

@ -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;
})
}
}

View file

@ -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;

View file

@ -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;
};
}

349
yarn.lock
View file

@ -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==
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:
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==
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:
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-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-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-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-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:
micromark "~2.11.0"
micromark-extension-mdx-expression "^0.3.0"
vfile-message "^2.0.0"
micromark-util-character "^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-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:
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"
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-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-util-symbol "^1.0.0"
micromark-util-types "^1.0.0"
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:
"@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"