@astrojs/markdown-remark 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -4
- package/dist/index.js +10 -3
- package/dist/load-plugins.d.ts +1 -1
- package/dist/load-plugins.js +6 -5
- package/dist/remark-shiki.d.ts +30 -0
- package/dist/remark-shiki.js +29 -0
- package/dist/types.d.ts +5 -5
- package/package.json +2 -1
- package/src/index.ts +9 -1
- package/src/load-plugins.ts +8 -7
- package/src/remark-shiki.ts +62 -0
- package/src/types.ts +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @astrojs/markdown-remark
|
|
2
2
|
|
|
3
|
+
## 0.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#2534](https://github.com/withastro/astro/pull/2534) [`cfeaa941`](https://github.com/withastro/astro/commit/cfeaa9414acdecec6f5d66ee0e33fe4fde574eee) Thanks [@JuanM04](https://github.com/JuanM04)! - Now you can use local plugins by passing a function instead of an `import`
|
|
8
|
+
|
|
9
|
+
* [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added the ability to use custom themes and langs with Shiki (`<Code />` and `@astrojs/markdown-remark`)
|
|
10
|
+
|
|
11
|
+
- [#2497](https://github.com/withastro/astro/pull/2497) [`6fe1b027`](https://github.com/withastro/astro/commit/6fe1b0279fce5a7a0e90ff79746ea0b641da3e21) Thanks [@JuanM04](https://github.com/JuanM04)! - Add Shiki as an alternative to Prism
|
|
12
|
+
|
|
13
|
+
* [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added `wrap` to Shiki config
|
|
14
|
+
|
|
15
|
+
- [#2564](https://github.com/withastro/astro/pull/2564) [`d71c4620`](https://github.com/withastro/astro/commit/d71c46207af40de6811596ca4f5e10aa9006377b) Thanks [@JuanM04](https://github.com/JuanM04)! - Fixed curly braces inside Shiki codeblocks
|
|
16
|
+
|
|
17
|
+
## 0.6.1-next.2
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#2564](https://github.com/withastro/astro/pull/2564) [`d71c4620`](https://github.com/withastro/astro/commit/d71c46207af40de6811596ca4f5e10aa9006377b) Thanks [@JuanM04](https://github.com/JuanM04)! - Fixed curly braces inside Shiki codeblocks
|
|
22
|
+
|
|
23
|
+
## 0.6.1-next.1
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- [#2534](https://github.com/withastro/astro/pull/2534) [`cfeaa941`](https://github.com/withastro/astro/commit/cfeaa9414acdecec6f5d66ee0e33fe4fde574eee) Thanks [@JuanM04](https://github.com/JuanM04)! - Now you can use local plugins by passing a function instead of an `import`
|
|
28
|
+
|
|
29
|
+
* [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added the ability to use custom themes and langs with Shiki (`<Code />` and `@astrojs/markdown-remark`)
|
|
30
|
+
|
|
31
|
+
- [#2518](https://github.com/withastro/astro/pull/2518) [`2bc91543`](https://github.com/withastro/astro/commit/2bc91543ceeb5f3dd45e201bf75d79f186e85141) Thanks [@JuanM04](https://github.com/JuanM04)! - Added `wrap` to Shiki config
|
|
32
|
+
|
|
33
|
+
## 0.6.1-next.0
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- [#2497](https://github.com/withastro/astro/pull/2497) [`6fe1b027`](https://github.com/withastro/astro/commit/6fe1b0279fce5a7a0e90ff79746ea0b641da3e21) Thanks [@JuanM04](https://github.com/JuanM04)! - Add Shiki as an alternative to Prism
|
|
38
|
+
|
|
3
39
|
## 0.6.0
|
|
4
40
|
|
|
5
41
|
### Minor Changes
|
|
@@ -105,10 +141,10 @@
|
|
|
105
141
|
|
|
106
142
|
```js
|
|
107
143
|
export default {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
144
|
+
markdownOptions: {
|
|
145
|
+
remarkPlugins: ['remark-slug', ['remark-autolink-headings', { behavior: 'prepend' }]],
|
|
146
|
+
rehypePlugins: ['rehype-slug', ['rehype-autolink-headings', { behavior: 'prepend' }]],
|
|
147
|
+
},
|
|
112
148
|
};
|
|
113
149
|
```
|
|
114
150
|
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,7 @@ import { remarkJsx, loadRemarkJsx } from "./remark-jsx.js";
|
|
|
26
26
|
import rehypeJsx from "./rehype-jsx.js";
|
|
27
27
|
import rehypeEscape from "./rehype-escape.js";
|
|
28
28
|
import remarkPrism from "./remark-prism.js";
|
|
29
|
+
import remarkShiki from "./remark-shiki.js";
|
|
29
30
|
import remarkUnwrap from "./remark-unwrap.js";
|
|
30
31
|
import { loadPlugins } from "./load-plugins.js";
|
|
31
32
|
import { unified } from "unified";
|
|
@@ -42,10 +43,12 @@ async function renderMarkdownWithFrontmatter(contents, opts) {
|
|
|
42
43
|
const DEFAULT_REMARK_PLUGINS = ["remark-gfm", "remark-smartypants"];
|
|
43
44
|
const DEFAULT_REHYPE_PLUGINS = ["rehype-slug"];
|
|
44
45
|
async function renderMarkdown(content, opts) {
|
|
45
|
-
var _a, _b;
|
|
46
|
+
var _a, _b, _c, _d;
|
|
46
47
|
let { remarkPlugins = [], rehypePlugins = [] } = opts != null ? opts : {};
|
|
47
48
|
const scopedClassName = (_a = opts == null ? void 0 : opts.$) == null ? void 0 : _a.scopedClassName;
|
|
48
49
|
const mode = (_b = opts == null ? void 0 : opts.mode) != null ? _b : "mdx";
|
|
50
|
+
const syntaxHighlight = (_c = opts == null ? void 0 : opts.syntaxHighlight) != null ? _c : "prism";
|
|
51
|
+
const shikiConfig = (_d = opts == null ? void 0 : opts.shikiConfig) != null ? _d : {};
|
|
49
52
|
const isMDX = mode === "mdx";
|
|
50
53
|
const { headers, rehypeCollectHeaders } = createCollectHeaders();
|
|
51
54
|
await Promise.all([loadRemarkExpressions(), loadRemarkJsx()]);
|
|
@@ -62,7 +65,11 @@ async function renderMarkdown(content, opts) {
|
|
|
62
65
|
if (scopedClassName) {
|
|
63
66
|
parser.use([scopedStyles(scopedClassName)]);
|
|
64
67
|
}
|
|
65
|
-
|
|
68
|
+
if (syntaxHighlight === "prism") {
|
|
69
|
+
parser.use([remarkPrism(scopedClassName)]);
|
|
70
|
+
} else if (syntaxHighlight === "shiki") {
|
|
71
|
+
parser.use([await remarkShiki(shikiConfig)]);
|
|
72
|
+
}
|
|
66
73
|
parser.use([[markdownToHtml, { allowDangerousHtml: true, passThrough: ["raw", "mdxTextExpression", "mdxJsxTextElement", "mdxJsxFlowElement"] }]]);
|
|
67
74
|
loadedRehypePlugins.forEach(([plugin, opts2]) => {
|
|
68
75
|
parser.use([[plugin, opts2]]);
|
|
@@ -89,4 +96,4 @@ export {
|
|
|
89
96
|
renderMarkdown,
|
|
90
97
|
renderMarkdownWithFrontmatter
|
|
91
98
|
};
|
|
92
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
99
|
+
//# sourceMappingURL=data:application/json;base64,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
|
package/dist/load-plugins.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as unified from 'unified';
|
|
2
2
|
import type { Plugin } from './types';
|
|
3
|
-
export declare function loadPlugins(items: Plugin[]): Promise<[unified.Plugin
|
|
3
|
+
export declare function loadPlugins(items: Plugin[]): Promise<[unified.Plugin, any?]>[];
|
package/dist/load-plugins.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
async function importPlugin(p) {
|
|
2
2
|
if (typeof p === "string") {
|
|
3
|
-
|
|
3
|
+
const importResult = await import(p);
|
|
4
|
+
return importResult.default;
|
|
4
5
|
}
|
|
5
|
-
return
|
|
6
|
+
return p;
|
|
6
7
|
}
|
|
7
8
|
function loadPlugins(items) {
|
|
8
9
|
return items.map((p) => {
|
|
9
10
|
return new Promise((resolve, reject) => {
|
|
10
11
|
if (Array.isArray(p)) {
|
|
11
12
|
const [plugin, opts] = p;
|
|
12
|
-
return importPlugin(plugin).then((m) => resolve([m
|
|
13
|
+
return importPlugin(plugin).then((m) => resolve([m, opts])).catch((e) => reject(e));
|
|
13
14
|
}
|
|
14
|
-
return importPlugin(p).then((m) => resolve([m
|
|
15
|
+
return importPlugin(p).then((m) => resolve([m])).catch((e) => reject(e));
|
|
15
16
|
});
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
19
|
export {
|
|
19
20
|
loadPlugins
|
|
20
21
|
};
|
|
21
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2xvYWQtcGx1Z2lucy50cyJdLAogICJtYXBwaW5ncyI6ICJBQUdBLDRCQUE0QixHQUFxRDtBQUNoRixNQUFJLE9BQU8sTUFBTSxVQUFVO0FBQzFCLFVBQU0sZUFBZSxNQUFNLE9BQU87QUFDbEMsV0FBTyxhQUFhO0FBQUE7QUFHckIsU0FBTztBQUFBO0FBR0QscUJBQXFCLE9BQW9EO0FBQy9FLFNBQU8sTUFBTSxJQUFJLENBQUMsTUFBTTtBQUN2QixXQUFPLElBQUksUUFBUSxDQUFDLFNBQVMsV0FBVztBQUN2QyxVQUFJLE1BQU0sUUFBUSxJQUFJO0FBQ3JCLGNBQU0sQ0FBQyxRQUFRLFFBQVE7QUFDdkIsZUFBTyxhQUFhLFFBQ2xCLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQyxHQUFHLFFBQ3hCLE1BQU0sQ0FBQyxNQUFNLE9BQU87QUFBQTtBQUd2QixhQUFPLGFBQWEsR0FDbEIsS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDLEtBQ3JCLE1BQU0sQ0FBQyxNQUFNLE9BQU87QUFBQTtBQUFBO0FBQUE7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import shiki from 'shiki';
|
|
2
|
+
export interface ShikiConfig {
|
|
3
|
+
/**
|
|
4
|
+
* The languages loaded to Shiki.
|
|
5
|
+
* Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
|
|
6
|
+
* Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
|
|
7
|
+
*
|
|
8
|
+
* @default []
|
|
9
|
+
*/
|
|
10
|
+
langs?: shiki.ILanguageRegistration[];
|
|
11
|
+
/**
|
|
12
|
+
* The styling theme.
|
|
13
|
+
* Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
|
|
14
|
+
* Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
|
|
15
|
+
*
|
|
16
|
+
* @default "github-dark"
|
|
17
|
+
*/
|
|
18
|
+
theme?: shiki.IThemeRegistration;
|
|
19
|
+
/**
|
|
20
|
+
* Enable word wrapping.
|
|
21
|
+
* - true: enabled.
|
|
22
|
+
* - false: enabled.
|
|
23
|
+
* - null: All overflow styling removed. Code will overflow the element by default.
|
|
24
|
+
*
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
wrap?: boolean | null;
|
|
28
|
+
}
|
|
29
|
+
declare const remarkShiki: ({ langs, theme, wrap }: ShikiConfig) => Promise<() => (tree: any) => void>;
|
|
30
|
+
export default remarkShiki;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import shiki from "shiki";
|
|
2
|
+
import { visit } from "unist-util-visit";
|
|
3
|
+
const remarkShiki = async ({ langs = [], theme = "github-dark", wrap = false }) => {
|
|
4
|
+
const highlighter = await shiki.getHighlighter({ theme });
|
|
5
|
+
for (const lang of langs) {
|
|
6
|
+
await highlighter.loadLanguage(lang);
|
|
7
|
+
}
|
|
8
|
+
return () => (tree) => {
|
|
9
|
+
visit(tree, "code", (node) => {
|
|
10
|
+
var _a;
|
|
11
|
+
let html = highlighter.codeToHtml(node.value, { lang: (_a = node.lang) != null ? _a : "plaintext" });
|
|
12
|
+
html = html.replace('<pre class="shiki"', '<pre data-astro-raw class="astro-code"');
|
|
13
|
+
html = html.replace(/style="(background-)?color: var\(--shiki-/g, 'style="$1color: var(--astro-code-');
|
|
14
|
+
if (wrap === false) {
|
|
15
|
+
html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"');
|
|
16
|
+
} else if (wrap === true) {
|
|
17
|
+
html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"');
|
|
18
|
+
}
|
|
19
|
+
node.type = "html";
|
|
20
|
+
node.value = html;
|
|
21
|
+
node.children = [];
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
var remark_shiki_default = remarkShiki;
|
|
26
|
+
export {
|
|
27
|
+
remark_shiki_default as default
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3JlbWFyay1zaGlraS50cyJdLAogICJtYXBwaW5ncyI6ICJBQUFBO0FBQ0E7QUE4QkEsTUFBTSxjQUFjLE9BQU8sRUFBRSxRQUFRLElBQUksUUFBUSxlQUFlLE9BQU8sWUFBeUI7QUFDL0YsUUFBTSxjQUFjLE1BQU0sTUFBTSxlQUFlLEVBQUU7QUFFakQsYUFBVyxRQUFRLE9BQU87QUFDekIsVUFBTSxZQUFZLGFBQWE7QUFBQTtBQUdoQyxTQUFPLE1BQU0sQ0FBQyxTQUFjO0FBQzNCLFVBQU0sTUFBTSxRQUFRLENBQUMsU0FBUztBQXZDaEM7QUF3Q0csVUFBSSxPQUFPLFlBQVksV0FBVyxLQUFLLE9BQU8sRUFBRSxNQUFNLFdBQUssU0FBTCxZQUFhO0FBR25FLGFBQU8sS0FBSyxRQUFRLHNCQUFzQjtBQUUxQyxhQUFPLEtBQUssUUFBUSw4Q0FBOEM7QUFHbEUsVUFBSSxTQUFTLE9BQU87QUFDbkIsZUFBTyxLQUFLLFFBQVEsaUJBQWlCO0FBQUEsaUJBQzNCLFNBQVMsTUFBTTtBQUN6QixlQUFPLEtBQUssUUFBUSxpQkFBaUI7QUFBQTtBQUd0QyxXQUFLLE9BQU87QUFDWixXQUFLLFFBQVE7QUFDYixXQUFLLFdBQVc7QUFBQTtBQUFBO0FBQUE7QUFLbkIsSUFBTyx1QkFBUTsiLAogICJuYW1lcyI6IFtdCn0K
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as unified from 'unified';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}>;
|
|
5
|
-
export declare type Plugin = string | [string, any] | UnifiedPluginImport | [UnifiedPluginImport, any];
|
|
1
|
+
import type * as unified from 'unified';
|
|
2
|
+
import type { ShikiConfig } from './remark-shiki';
|
|
3
|
+
export declare type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any];
|
|
6
4
|
export interface AstroMarkdownOptions {
|
|
7
5
|
mode?: 'md' | 'mdx';
|
|
6
|
+
syntaxHighlight?: 'prism' | 'shiki' | false;
|
|
7
|
+
shikiConfig?: ShikiConfig;
|
|
8
8
|
remarkPlugins?: Plugin[];
|
|
9
9
|
rehypePlugins?: Plugin[];
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/markdown-remark",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "withastro",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"remark-parse": "^10.0.1",
|
|
39
39
|
"remark-rehype": "^10.0.1",
|
|
40
40
|
"remark-smartypants": "^2.0.0",
|
|
41
|
+
"shiki": "^0.10.0",
|
|
41
42
|
"unified": "^10.1.1",
|
|
42
43
|
"unist-util-map": "^3.0.0",
|
|
43
44
|
"unist-util-visit": "^4.1.0"
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { remarkJsx, loadRemarkJsx } from './remark-jsx.js';
|
|
|
9
9
|
import rehypeJsx from './rehype-jsx.js';
|
|
10
10
|
import rehypeEscape from './rehype-escape.js';
|
|
11
11
|
import remarkPrism from './remark-prism.js';
|
|
12
|
+
import remarkShiki from './remark-shiki.js';
|
|
12
13
|
import remarkUnwrap from './remark-unwrap.js';
|
|
13
14
|
import { loadPlugins } from './load-plugins.js';
|
|
14
15
|
|
|
@@ -37,6 +38,8 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
|
|
|
37
38
|
let { remarkPlugins = [], rehypePlugins = [] } = opts ?? {};
|
|
38
39
|
const scopedClassName = opts?.$?.scopedClassName;
|
|
39
40
|
const mode = opts?.mode ?? 'mdx';
|
|
41
|
+
const syntaxHighlight = opts?.syntaxHighlight ?? 'prism';
|
|
42
|
+
const shikiConfig = opts?.shikiConfig ?? {};
|
|
40
43
|
const isMDX = mode === 'mdx';
|
|
41
44
|
const { headers, rehypeCollectHeaders } = createCollectHeaders();
|
|
42
45
|
|
|
@@ -64,7 +67,12 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
|
|
|
64
67
|
parser.use([scopedStyles(scopedClassName)]);
|
|
65
68
|
}
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
if (syntaxHighlight === 'prism') {
|
|
71
|
+
parser.use([remarkPrism(scopedClassName)]);
|
|
72
|
+
} else if (syntaxHighlight === 'shiki') {
|
|
73
|
+
parser.use([await remarkShiki(shikiConfig)]);
|
|
74
|
+
}
|
|
75
|
+
|
|
68
76
|
parser.use([[markdownToHtml as any, { allowDangerousHtml: true, passThrough: ['raw', 'mdxTextExpression', 'mdxJsxTextElement', 'mdxJsxFlowElement'] }]]);
|
|
69
77
|
|
|
70
78
|
loadedRehypePlugins.forEach(([plugin, opts]) => {
|
package/src/load-plugins.ts
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import * as unified from 'unified';
|
|
2
|
-
import type { Plugin
|
|
2
|
+
import type { Plugin } from './types';
|
|
3
3
|
|
|
4
|
-
async function importPlugin(p: string |
|
|
4
|
+
async function importPlugin(p: string | unified.Plugin): Promise<unified.Plugin> {
|
|
5
5
|
if (typeof p === 'string') {
|
|
6
|
-
|
|
6
|
+
const importResult = await import(p);
|
|
7
|
+
return importResult.default;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
return
|
|
10
|
+
return p;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin
|
|
13
|
+
export function loadPlugins(items: Plugin[]): Promise<[unified.Plugin, any?]>[] {
|
|
13
14
|
return items.map((p) => {
|
|
14
15
|
return new Promise((resolve, reject) => {
|
|
15
16
|
if (Array.isArray(p)) {
|
|
16
17
|
const [plugin, opts] = p;
|
|
17
18
|
return importPlugin(plugin)
|
|
18
|
-
.then((m) => resolve([m
|
|
19
|
+
.then((m) => resolve([m, opts]))
|
|
19
20
|
.catch((e) => reject(e));
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
return importPlugin(p)
|
|
23
|
-
.then((m) => resolve([m
|
|
24
|
+
.then((m) => resolve([m]))
|
|
24
25
|
.catch((e) => reject(e));
|
|
25
26
|
});
|
|
26
27
|
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import shiki from 'shiki';
|
|
2
|
+
import { visit } from 'unist-util-visit';
|
|
3
|
+
|
|
4
|
+
export interface ShikiConfig {
|
|
5
|
+
/**
|
|
6
|
+
* The languages loaded to Shiki.
|
|
7
|
+
* Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
|
|
8
|
+
* Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
|
|
9
|
+
*
|
|
10
|
+
* @default []
|
|
11
|
+
*/
|
|
12
|
+
langs?: shiki.ILanguageRegistration[];
|
|
13
|
+
/**
|
|
14
|
+
* The styling theme.
|
|
15
|
+
* Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
|
|
16
|
+
* Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
|
|
17
|
+
*
|
|
18
|
+
* @default "github-dark"
|
|
19
|
+
*/
|
|
20
|
+
theme?: shiki.IThemeRegistration;
|
|
21
|
+
/**
|
|
22
|
+
* Enable word wrapping.
|
|
23
|
+
* - true: enabled.
|
|
24
|
+
* - false: enabled.
|
|
25
|
+
* - null: All overflow styling removed. Code will overflow the element by default.
|
|
26
|
+
*
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
wrap?: boolean | null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const remarkShiki = async ({ langs = [], theme = 'github-dark', wrap = false }: ShikiConfig) => {
|
|
33
|
+
const highlighter = await shiki.getHighlighter({ theme });
|
|
34
|
+
|
|
35
|
+
for (const lang of langs) {
|
|
36
|
+
await highlighter.loadLanguage(lang);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return () => (tree: any) => {
|
|
40
|
+
visit(tree, 'code', (node) => {
|
|
41
|
+
let html = highlighter.codeToHtml(node.value, { lang: node.lang ?? 'plaintext' });
|
|
42
|
+
|
|
43
|
+
// Replace "shiki" class naming with "astro" and add "data-astro-raw".
|
|
44
|
+
html = html.replace('<pre class="shiki"', '<pre data-astro-raw class="astro-code"');
|
|
45
|
+
// Replace "shiki" css variable naming with "astro".
|
|
46
|
+
html = html.replace(/style="(background-)?color: var\(--shiki-/g, 'style="$1color: var(--astro-code-');
|
|
47
|
+
// Handle code wrapping
|
|
48
|
+
// if wrap=null, do nothing.
|
|
49
|
+
if (wrap === false) {
|
|
50
|
+
html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"');
|
|
51
|
+
} else if (wrap === true) {
|
|
52
|
+
html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
node.type = 'html';
|
|
56
|
+
node.value = html;
|
|
57
|
+
node.children = [];
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default remarkShiki;
|
package/src/types.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import * as unified from 'unified';
|
|
1
|
+
import type * as unified from 'unified';
|
|
2
|
+
import type { ShikiConfig } from './remark-shiki';
|
|
2
3
|
|
|
3
|
-
export type
|
|
4
|
-
export type Plugin = string | [string, any] | UnifiedPluginImport | [UnifiedPluginImport, any];
|
|
4
|
+
export type Plugin = string | [string, any] | unified.Plugin | [unified.Plugin, any];
|
|
5
5
|
|
|
6
6
|
export interface AstroMarkdownOptions {
|
|
7
7
|
mode?: 'md' | 'mdx';
|
|
8
|
+
syntaxHighlight?: 'prism' | 'shiki' | false;
|
|
9
|
+
shikiConfig?: ShikiConfig;
|
|
8
10
|
remarkPlugins?: Plugin[];
|
|
9
11
|
rehypePlugins?: Plugin[];
|
|
10
12
|
}
|