make Remark rehype options available in astro config (#4138)
* make remark-rehype config available in astro.config.mjs * add test for remark-rehype config, checks that footnotes can be translated * update lockfile to take the added test into account * omit handlers and unkownHandler from the RemarkRehype type * define RemarkRehype with proper references to the handler and handlers types * formatting * changeset Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
parent
b680c3eb97
commit
839097c84e
9 changed files with 108 additions and 1 deletions
6
.changeset/giant-pandas-roll.md
Normal file
6
.changeset/giant-pandas-roll.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'astro': minor
|
||||||
|
'@astrojs/markdown-remark': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Makes remark-rehype options available in astro.config.mjs
|
|
@ -4,6 +4,7 @@ import type {
|
||||||
MarkdownRenderingResult,
|
MarkdownRenderingResult,
|
||||||
RehypePlugins,
|
RehypePlugins,
|
||||||
RemarkPlugins,
|
RemarkPlugins,
|
||||||
|
RemarkRehype,
|
||||||
ShikiConfig,
|
ShikiConfig,
|
||||||
} from '@astrojs/markdown-remark';
|
} from '@astrojs/markdown-remark';
|
||||||
import type * as babel from '@babel/core';
|
import type * as babel from '@babel/core';
|
||||||
|
@ -680,6 +681,23 @@ export interface AstroUserConfig {
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
rehypePlugins?: RehypePlugins;
|
rehypePlugins?: RehypePlugins;
|
||||||
|
/**
|
||||||
|
* @docs
|
||||||
|
* @name markdown.remarkRehype
|
||||||
|
* @type {RemarkRehype}
|
||||||
|
* @description
|
||||||
|
* Pass options to [remark-rehype](https://github.com/remarkjs/remark-rehype#api) .
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* {
|
||||||
|
* markdown: {
|
||||||
|
* // Example: Translate the footnotes text to another language, here are the default English values
|
||||||
|
* remarkRehype: { footnoteLabel: "Footnotes", footnoteBackLabel: "Back to content"},
|
||||||
|
* },
|
||||||
|
* };
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
remarkRehype?: RemarkRehype;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { RehypePlugin, RemarkPlugin } from '@astrojs/markdown-remark';
|
import type { RehypePlugin, RemarkPlugin, RemarkRehype } from '@astrojs/markdown-remark';
|
||||||
import type * as Postcss from 'postcss';
|
import type * as Postcss from 'postcss';
|
||||||
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
|
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
|
||||||
import type { Arguments as Flags } from 'yargs-parser';
|
import type { Arguments as Flags } from 'yargs-parser';
|
||||||
|
@ -51,6 +51,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
|
||||||
},
|
},
|
||||||
remarkPlugins: [],
|
remarkPlugins: [],
|
||||||
rehypePlugins: [],
|
rehypePlugins: [],
|
||||||
|
remarkRehype: {},
|
||||||
},
|
},
|
||||||
vite: {},
|
vite: {},
|
||||||
legacy: {
|
legacy: {
|
||||||
|
@ -214,6 +215,10 @@ export const AstroConfigSchema = z.object({
|
||||||
])
|
])
|
||||||
.array()
|
.array()
|
||||||
.default(ASTRO_CONFIG_DEFAULTS.markdown.rehypePlugins),
|
.default(ASTRO_CONFIG_DEFAULTS.markdown.rehypePlugins),
|
||||||
|
remarkRehype: z
|
||||||
|
.custom<RemarkRehype>((data) => data instanceof Object && !Array.isArray(data))
|
||||||
|
.optional()
|
||||||
|
.default(ASTRO_CONFIG_DEFAULTS.markdown.remarkRehype),
|
||||||
})
|
})
|
||||||
.default({}),
|
.default({}),
|
||||||
vite: z
|
vite: z
|
||||||
|
|
43
packages/astro/test/astro-markdown-remarkRehype.test.js
Normal file
43
packages/astro/test/astro-markdown-remarkRehype.test.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import * as cheerio from 'cheerio';
|
||||||
|
import { loadFixture } from './test-utils.js';
|
||||||
|
|
||||||
|
describe('Astro Markdown without remark-rehype config', () => {
|
||||||
|
let fixture;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
fixture = await loadFixture({
|
||||||
|
root: './fixtures/astro-markdown-remarkRehype/',
|
||||||
|
});
|
||||||
|
await fixture.build();
|
||||||
|
});
|
||||||
|
it('Renders footnotes with default English labels', async () => {
|
||||||
|
const html = await fixture.readFile('/index.html');
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
expect($('#footnote-label').text()).to.equal('Footnotes');
|
||||||
|
expect($('.data-footnote-backref').first().attr('aria-label')).to.equal('Back to content');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Astro Markdown with remark-rehype config', () => {
|
||||||
|
let fixture;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
fixture = await loadFixture({
|
||||||
|
root: './fixtures/astro-markdown-remarkRehype/',
|
||||||
|
markdown: {
|
||||||
|
remarkRehype: {
|
||||||
|
footnoteLabel: 'Catatan kaki',
|
||||||
|
footnoteBackLabel: 'Kembali ke konten',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await fixture.build();
|
||||||
|
});
|
||||||
|
it('Renders footnotes with values from the configuration', async () => {
|
||||||
|
const html = await fixture.readFile('/index.html');
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
expect($('#footnote-label').text()).to.equal('Catatan kaki');
|
||||||
|
expect($('.data-footnote-backref').first().attr('aria-label')).to.equal('Kembali ke konten');
|
||||||
|
});
|
||||||
|
});
|
8
packages/astro/test/fixtures/astro-markdown-remarkRehype/package.json
vendored
Normal file
8
packages/astro/test/fixtures/astro-markdown-remarkRehype/package.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "@test/astro-markdown-remarkRehype",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"astro": "workspace:*"
|
||||||
|
}
|
||||||
|
}
|
9
packages/astro/test/fixtures/astro-markdown-remarkRehype/src/pages/index.md
vendored
Normal file
9
packages/astro/test/fixtures/astro-markdown-remarkRehype/src/pages/index.md
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
foo: bar
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hello world
|
||||||
|
|
||||||
|
This[^1] should be visible.
|
||||||
|
|
||||||
|
[^1]: And there would be a footnote.
|
|
@ -38,6 +38,7 @@ export async function renderMarkdown(
|
||||||
shikiConfig = {},
|
shikiConfig = {},
|
||||||
remarkPlugins = [],
|
remarkPlugins = [],
|
||||||
rehypePlugins = [],
|
rehypePlugins = [],
|
||||||
|
remarkRehype = {},
|
||||||
isAstroFlavoredMd = false,
|
isAstroFlavoredMd = false,
|
||||||
} = opts;
|
} = opts;
|
||||||
const input = new VFile({ value: content, path: fileURL });
|
const input = new VFile({ value: content, path: fileURL });
|
||||||
|
@ -85,6 +86,7 @@ export async function renderMarkdown(
|
||||||
'mdxTextExpression',
|
'mdxTextExpression',
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
|
...remarkRehype,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import type * as hast from 'hast';
|
import type * as hast from 'hast';
|
||||||
import type * as mdast from 'mdast';
|
import type * as mdast from 'mdast';
|
||||||
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
|
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
|
||||||
|
import type {
|
||||||
|
Options as RemarkRehypeOptions,
|
||||||
|
all as Handlers,
|
||||||
|
one as Handler,
|
||||||
|
} from 'remark-rehype';
|
||||||
import type * as unified from 'unified';
|
import type * as unified from 'unified';
|
||||||
import type { VFile } from 'vfile';
|
import type { VFile } from 'vfile';
|
||||||
|
|
||||||
|
@ -20,6 +25,10 @@ export type RehypePlugin<PluginParameters extends any[] = any[]> = unified.Plugi
|
||||||
|
|
||||||
export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
|
export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
|
||||||
|
|
||||||
|
export type RemarkRehype = Omit<RemarkRehypeOptions, 'handlers' | 'unknownHandler'> & {
|
||||||
|
handlers: typeof Handlers;
|
||||||
|
} & { handler: typeof Handler };
|
||||||
|
|
||||||
export interface ShikiConfig {
|
export interface ShikiConfig {
|
||||||
langs?: ILanguageRegistration[];
|
langs?: ILanguageRegistration[];
|
||||||
theme?: Theme | IThemeRegistration;
|
theme?: Theme | IThemeRegistration;
|
||||||
|
@ -33,6 +42,7 @@ export interface AstroMarkdownOptions {
|
||||||
shikiConfig?: ShikiConfig;
|
shikiConfig?: ShikiConfig;
|
||||||
remarkPlugins?: RemarkPlugins;
|
remarkPlugins?: RemarkPlugins;
|
||||||
rehypePlugins?: RehypePlugins;
|
rehypePlugins?: RehypePlugins;
|
||||||
|
remarkRehype?: RemarkRehype;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
|
export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
|
||||||
|
|
|
@ -1296,6 +1296,12 @@ importers:
|
||||||
hast-util-select: 5.0.2
|
hast-util-select: 5.0.2
|
||||||
rehype-slug: 5.0.1
|
rehype-slug: 5.0.1
|
||||||
|
|
||||||
|
packages/astro/test/fixtures/astro-markdown-remarkRehype:
|
||||||
|
specifiers:
|
||||||
|
astro: workspace:*
|
||||||
|
dependencies:
|
||||||
|
astro: link:../../..
|
||||||
|
|
||||||
packages/astro/test/fixtures/astro-markdown-shiki/langs:
|
packages/astro/test/fixtures/astro-markdown-shiki/langs:
|
||||||
specifiers:
|
specifiers:
|
||||||
astro: workspace:*
|
astro: workspace:*
|
||||||
|
|
Loading…
Reference in a new issue