fix: import local plugins into markdown (#2534)
* Replaced "UnifiedPluginImport" for a function * Updated tests * Updated docs * Updated examples * Added changeset * Fixed tests * Removed unused "UnifiedPluginImport" * Duplicated add-classes.mjs
This commit is contained in:
parent
8f9b1cbc8b
commit
cfeaa9414a
9 changed files with 41 additions and 22 deletions
5
.changeset/curly-wasps-sin.md
Normal file
5
.changeset/curly-wasps-sin.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@astrojs/markdown-remark': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Now you can use local plugins by passing a function instead of an `import`
|
|
@ -69,6 +69,8 @@ export default {
|
||||||
You can provide names of the plugins as well as import them:
|
You can provide names of the plugins as well as import them:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import autolinkHeadings from 'remark-autolink-headings'
|
||||||
|
|
||||||
// astro.config.mjs
|
// astro.config.mjs
|
||||||
export default {
|
export default {
|
||||||
markdownOptions: {
|
markdownOptions: {
|
||||||
|
@ -76,7 +78,7 @@ export default {
|
||||||
'@astrojs/markdown-remark',
|
'@astrojs/markdown-remark',
|
||||||
{
|
{
|
||||||
remarkPlugins: [
|
remarkPlugins: [
|
||||||
[import('remark-autolink-headings'), { behavior: 'prepend' }],
|
[autolinkHeadings, { behavior: 'prepend' }],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
// helpful tooltips, and warnings if your exported object is invalid.
|
// helpful tooltips, and warnings if your exported object is invalid.
|
||||||
// You can disable this by removing "@ts-check" and `@type` comments below.
|
// You can disable this by removing "@ts-check" and `@type` comments below.
|
||||||
import astroRemark from '@astrojs/markdown-remark';
|
import astroRemark from '@astrojs/markdown-remark';
|
||||||
|
import addClasses from './add-classes.mjs';
|
||||||
|
|
||||||
// @ts-check
|
// @ts-check
|
||||||
export default /** @type {import('astro').AstroUserConfig} */ ({
|
export default /** @type {import('astro').AstroUserConfig} */ ({
|
||||||
|
@ -15,12 +16,7 @@ export default /** @type {import('astro').AstroUserConfig} */ ({
|
||||||
astroRemark,
|
astroRemark,
|
||||||
{
|
{
|
||||||
remarkPlugins: ['remark-code-titles'],
|
remarkPlugins: ['remark-code-titles'],
|
||||||
rehypePlugins: [
|
rehypePlugins: [['rehype-autolink-headings', { behavior: 'prepend' }], ['rehype-toc', { headings: ['h2', 'h3'] }], [addClasses, { 'h1,h2,h3': 'title' }], 'rehype-slug'],
|
||||||
['rehype-autolink-headings', { behavior: 'prepend' }],
|
|
||||||
['rehype-toc', { headings: ['h2', 'h3'] }],
|
|
||||||
[new URL('./add-classes.mjs', import.meta.url).pathname, { 'h1,h2,h3': 'title' }],
|
|
||||||
'rehype-slug',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -125,6 +125,7 @@
|
||||||
"@types/yargs-parser": "^20.2.1",
|
"@types/yargs-parser": "^20.2.1",
|
||||||
"chai": "^4.3.4",
|
"chai": "^4.3.4",
|
||||||
"cheerio": "^1.0.0-rc.10",
|
"cheerio": "^1.0.0-rc.10",
|
||||||
|
"hast-util-select": "^5.0.1",
|
||||||
"mocha": "^9.1.3",
|
"mocha": "^9.1.3",
|
||||||
"vite": "~2.6.10"
|
"vite": "~2.6.10"
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { expect } from 'chai';
|
||||||
import cheerio from 'cheerio';
|
import cheerio from 'cheerio';
|
||||||
import { loadFixture } from './test-utils.js';
|
import { loadFixture } from './test-utils.js';
|
||||||
import markdownRemark from '@astrojs/markdown-remark';
|
import markdownRemark from '@astrojs/markdown-remark';
|
||||||
|
import addClasses from './fixtures/astro-markdown-plugins/add-classes.mjs';
|
||||||
|
|
||||||
describe('Astro Markdown plugins', () => {
|
describe('Astro Markdown plugins', () => {
|
||||||
let fixture;
|
let fixture;
|
||||||
|
@ -15,11 +16,7 @@ describe('Astro Markdown plugins', () => {
|
||||||
markdownRemark,
|
markdownRemark,
|
||||||
{
|
{
|
||||||
remarkPlugins: ['remark-code-titles', ['rehype-autolink-headings', { behavior: 'prepend' }]],
|
remarkPlugins: ['remark-code-titles', ['rehype-autolink-headings', { behavior: 'prepend' }]],
|
||||||
rehypePlugins: [
|
rehypePlugins: [['rehype-toc', { headings: ['h2', 'h3'] }], [addClasses, { 'h1,h2,h3': 'title' }], 'rehype-slug'],
|
||||||
[import('rehype-toc'), { headings: ['h2', 'h3'] }],
|
|
||||||
[import('../../../examples/with-markdown-plugins/add-classes.mjs'), { 'h1,h2,h3': 'title' }],
|
|
||||||
'rehype-slug',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
18
packages/astro/test/fixtures/astro-markdown-plugins/add-classes.mjs
vendored
Normal file
18
packages/astro/test/fixtures/astro-markdown-plugins/add-classes.mjs
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { selectAll } from 'hast-util-select';
|
||||||
|
|
||||||
|
export default (additions) => {
|
||||||
|
const adders = Object.entries(additions).map(adder);
|
||||||
|
return (node) => adders.forEach((a) => a(node));
|
||||||
|
};
|
||||||
|
|
||||||
|
const adder = ([selector, className]) => {
|
||||||
|
const writer = write(className);
|
||||||
|
return (node) => selectAll(selector, node).forEach(writer);
|
||||||
|
};
|
||||||
|
|
||||||
|
const write =
|
||||||
|
(className) =>
|
||||||
|
({ properties }) => {
|
||||||
|
if (!properties.className) properties.className = className;
|
||||||
|
else properties.className += ` ${className}`;
|
||||||
|
};
|
|
@ -1,26 +1,27 @@
|
||||||
import * as unified from 'unified';
|
import * as unified from 'unified';
|
||||||
import type { Plugin, UnifiedPluginImport } from './types';
|
import type { Plugin } from './types';
|
||||||
|
|
||||||
async function importPlugin(p: string | UnifiedPluginImport): UnifiedPluginImport {
|
async function importPlugin(p: string | unified.Plugin): Promise<unified.Plugin> {
|
||||||
if (typeof p === 'string') {
|
if (typeof p === 'string') {
|
||||||
return await import(p);
|
const importResult = await import(p);
|
||||||
|
return importResult.default;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin] | [unified.Plugin, any]>[] {
|
export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin, any?]>[] {
|
||||||
return items.map((p) => {
|
return items.map((p) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (Array.isArray(p)) {
|
if (Array.isArray(p)) {
|
||||||
const [plugin, opts] = p;
|
const [plugin, opts] = p;
|
||||||
return importPlugin(plugin)
|
return importPlugin(plugin)
|
||||||
.then((m) => resolve([m.default, opts]))
|
.then((m) => resolve([m, opts]))
|
||||||
.catch((e) => reject(e));
|
.catch((e) => reject(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
return importPlugin(p)
|
return importPlugin(p)
|
||||||
.then((m) => resolve([m.default]))
|
.then((m) => resolve([m]))
|
||||||
.catch((e) => reject(e));
|
.catch((e) => reject(e));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type * as unified from 'unified';
|
import type * as unified from 'unified';
|
||||||
import type * as shiki from 'shiki';
|
import type * as shiki from 'shiki';
|
||||||
|
|
||||||
export type UnifiedPluginImport = Promise<{ default: unified.Plugin }>;
|
export type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any];
|
||||||
export type Plugin = string | [string, any] | UnifiedPluginImport | [UnifiedPluginImport, any];
|
|
||||||
|
|
||||||
export interface AstroMarkdownOptions {
|
export interface AstroMarkdownOptions {
|
||||||
mode?: 'md' | 'mdx';
|
mode?: 'md' | 'mdx';
|
||||||
|
|
|
@ -4978,7 +4978,7 @@ hast-util-raw@^7.2.0:
|
||||||
web-namespaces "^2.0.0"
|
web-namespaces "^2.0.0"
|
||||||
zwitch "^2.0.0"
|
zwitch "^2.0.0"
|
||||||
|
|
||||||
hast-util-select@5.0.1:
|
hast-util-select@5.0.1, hast-util-select@^5.0.1:
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/hast-util-select/-/hast-util-select-5.0.1.tgz#ed3788ad1a8d2d7f16a6bf8153ce9378edbe9d6d"
|
resolved "https://registry.yarnpkg.com/hast-util-select/-/hast-util-select-5.0.1.tgz#ed3788ad1a8d2d7f16a6bf8153ce9378edbe9d6d"
|
||||||
integrity sha512-cxnImmR/tN/ipvbwGrKtEErmy83K1xWx8Bu7nImiwTOJ7X/fW1X6L1241ux+MYUXDwx8GxrE4LVmXRlEnbQsQA==
|
integrity sha512-cxnImmR/tN/ipvbwGrKtEErmy83K1xWx8Bu7nImiwTOJ7X/fW1X6L1241ux+MYUXDwx8GxrE4LVmXRlEnbQsQA==
|
||||||
|
|
Loading…
Reference in a new issue