@shikijs/rehype 3.23.0 → 4.0.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/dist/core.d.mts CHANGED
@@ -1,10 +1,9 @@
1
- import { HighlighterGeneric } from '@shikijs/types';
2
- import { Root } from 'hast';
3
- import { Transformer } from 'unified';
4
- import { R as RehypeShikiCoreOptions } from './shared/rehype.DcMmi29I.mjs';
5
- export { M as MapLike, a as RehypeShikiExtraOptions } from './shared/rehype.DcMmi29I.mjs';
6
- import 'shiki';
1
+ import { n as RehypeShikiCoreOptions, r as RehypeShikiExtraOptions, t as MapLike } from "./types-Wi2EaRpk.mjs";
2
+ import { HighlighterGeneric } from "@shikijs/types";
3
+ import { Root } from "hast";
4
+ import { Transformer } from "unified";
7
5
 
6
+ //#region src/core.d.ts
8
7
  declare function rehypeShikiFromHighlighter(highlighter: HighlighterGeneric<any, any>, options: RehypeShikiCoreOptions): Transformer<Root, Root>;
9
-
10
- export { RehypeShikiCoreOptions, rehypeShikiFromHighlighter as default };
8
+ //#endregion
9
+ export { MapLike, RehypeShikiCoreOptions, RehypeShikiExtraOptions, rehypeShikiFromHighlighter as default };
package/dist/core.mjs CHANGED
@@ -1,167 +1,92 @@
1
- import { isSpecialLang } from 'shiki/core';
2
- import { visit } from 'unist-util-visit';
3
- import { toString } from 'hast-util-to-string';
4
-
5
- const InlineCodeHandlers = {
6
- "tailing-curly-colon": (_tree, node) => {
7
- const raw = toString(node);
8
- const match = raw.match(/(.+)\{:([\w-]+)\}$/);
9
- if (!match)
10
- return;
11
- return {
12
- type: "inline",
13
- code: match[1] ?? raw,
14
- lang: match.at(2)
15
- };
16
- }
17
- };
18
- const languagePrefix$1 = "language-";
19
- const PreHandler = (_tree, node) => {
20
- const head = node.children[0];
21
- if (!head || head.type !== "element" || head.tagName !== "code" || !head.properties) {
22
- return;
23
- }
24
- const classes = head.properties.className;
25
- const languageClass = Array.isArray(classes) ? classes.find(
26
- (d) => typeof d === "string" && d.startsWith(languagePrefix$1)
27
- ) : void 0;
28
- return {
29
- type: "pre",
30
- lang: typeof languageClass === "string" ? languageClass.slice(languagePrefix$1.length) : void 0,
31
- code: toString(head),
32
- meta: head.data?.meta ?? head.properties.metastring?.toString() ?? ""
33
- };
34
- };
1
+ import { n as PreHandler, t as InlineCodeHandlers } from "./handlers-DyniaZhL.mjs";
2
+ import { isSpecialLang } from "shiki/core";
3
+ import { visit } from "unist-util-visit";
35
4
 
5
+ //#region src/core.ts
36
6
  const languagePrefix = "language-";
37
7
  function rehypeShikiFromHighlighter(highlighter, options) {
38
- const {
39
- addLanguageClass = false,
40
- parseMetaString,
41
- cache,
42
- defaultLanguage,
43
- fallbackLanguage,
44
- onError,
45
- stripEndNewline = true,
46
- inline = false,
47
- lazy = false,
48
- ...rest
49
- } = options;
50
- function highlight(lang, code, metaString = "", meta = {}) {
51
- const cacheKey = `${lang}:${metaString}:${code}`;
52
- const cachedValue = cache?.get(cacheKey);
53
- if (cachedValue) {
54
- return cachedValue;
55
- }
56
- const codeOptions = {
57
- ...rest,
58
- lang,
59
- meta: {
60
- ...rest.meta,
61
- ...meta,
62
- __raw: metaString
63
- }
64
- };
65
- if (addLanguageClass) {
66
- codeOptions.transformers = [
67
- ...codeOptions.transformers ?? [],
68
- {
69
- name: "rehype-shiki:code-language-class",
70
- code(node) {
71
- this.addClassToHast(node, `${languagePrefix}${lang}`);
72
- return node;
73
- }
74
- }
75
- ];
76
- }
77
- if (stripEndNewline && code.endsWith("\n"))
78
- code = code.slice(0, -1);
79
- try {
80
- const fragment = highlighter.codeToHast(code, codeOptions);
81
- cache?.set(cacheKey, fragment);
82
- return fragment;
83
- } catch (error) {
84
- if (onError)
85
- onError(error);
86
- else
87
- throw error;
88
- }
89
- }
90
- return (tree) => {
91
- const queue = [];
92
- visit(tree, "element", (node, index, parent) => {
93
- let handler;
94
- if (!parent || index == null)
95
- return;
96
- if (node.tagName === "pre") {
97
- handler = PreHandler;
98
- } else if (node.tagName === "code" && inline) {
99
- handler = InlineCodeHandlers[inline];
100
- } else {
101
- return;
102
- }
103
- const parsed = handler(tree, node);
104
- if (!parsed)
105
- return;
106
- let lang;
107
- let lazyLoad = false;
108
- if (!parsed.lang) {
109
- lang = defaultLanguage;
110
- } else if (highlighter.getLoadedLanguages().includes(parsed.lang) || isSpecialLang(parsed.lang)) {
111
- lang = parsed.lang;
112
- } else if (lazy) {
113
- lazyLoad = true;
114
- lang = parsed.lang;
115
- } else if (fallbackLanguage) {
116
- lang = fallbackLanguage;
117
- }
118
- if (!lang)
119
- return;
120
- const meta = parsed.meta ? parseMetaString?.(parsed.meta, node, tree) : void 0;
121
- const processNode = (targetLang) => {
122
- const fragment = highlight(targetLang, parsed.code, parsed.meta, meta ?? {});
123
- if (!fragment)
124
- return;
125
- if (parsed.type === "inline") {
126
- const head = fragment.children[0];
127
- if (head.type === "element" && head.tagName === "pre") {
128
- head.tagName = "span";
129
- }
130
- }
131
- parent.children[index] = fragment;
132
- };
133
- if (lazyLoad) {
134
- try {
135
- queue.push(
136
- highlighter.loadLanguage(lang).then(() => processNode(lang)).catch((error) => {
137
- if (fallbackLanguage) {
138
- processNode(fallbackLanguage);
139
- } else if (onError) {
140
- onError(error);
141
- } else {
142
- throw error;
143
- }
144
- })
145
- );
146
- } catch (error) {
147
- if (fallbackLanguage)
148
- return processNode(fallbackLanguage);
149
- else if (onError)
150
- onError(error);
151
- else throw error;
152
- }
153
- } else {
154
- processNode(lang);
155
- }
156
- return "skip";
157
- });
158
- if (queue.length > 0) {
159
- async function run() {
160
- await Promise.all(queue);
161
- }
162
- return run();
163
- }
164
- };
8
+ const { addLanguageClass = false, parseMetaString, cache, defaultLanguage, fallbackLanguage, onError, stripEndNewline = true, inline = false, lazy = false, ...rest } = options;
9
+ function highlight(lang, code, metaString = "", meta = {}) {
10
+ const cacheKey = `${lang}:${metaString}:${code}`;
11
+ const cachedValue = cache?.get(cacheKey);
12
+ if (cachedValue) return cachedValue;
13
+ const codeOptions = {
14
+ ...rest,
15
+ lang,
16
+ meta: {
17
+ ...rest.meta,
18
+ ...meta,
19
+ __raw: metaString
20
+ }
21
+ };
22
+ if (addLanguageClass) codeOptions.transformers = [...codeOptions.transformers ?? [], {
23
+ name: "rehype-shiki:code-language-class",
24
+ code(node) {
25
+ this.addClassToHast(node, `${languagePrefix}${lang}`);
26
+ return node;
27
+ }
28
+ }];
29
+ if (stripEndNewline && code.endsWith("\n")) code = code.slice(0, -1);
30
+ try {
31
+ const fragment = highlighter.codeToHast(code, codeOptions);
32
+ cache?.set(cacheKey, fragment);
33
+ return fragment;
34
+ } catch (error) {
35
+ if (onError) onError(error);
36
+ else throw error;
37
+ }
38
+ }
39
+ return (tree) => {
40
+ const queue = [];
41
+ visit(tree, "element", (node, index, parent) => {
42
+ let handler;
43
+ if (!parent || index == null) return;
44
+ if (node.tagName === "pre") handler = PreHandler;
45
+ else if (node.tagName === "code" && inline) handler = InlineCodeHandlers[inline];
46
+ else return;
47
+ const parsed = handler(tree, node);
48
+ if (!parsed) return;
49
+ let lang;
50
+ let lazyLoad = false;
51
+ if (!parsed.lang) lang = defaultLanguage;
52
+ else if (highlighter.getLoadedLanguages().includes(parsed.lang) || isSpecialLang(parsed.lang)) lang = parsed.lang;
53
+ else if (lazy) {
54
+ lazyLoad = true;
55
+ lang = parsed.lang;
56
+ } else if (fallbackLanguage) lang = fallbackLanguage;
57
+ if (!lang) return;
58
+ const meta = parsed.meta ? parseMetaString?.(parsed.meta, node, tree) : void 0;
59
+ const processNode = (targetLang) => {
60
+ const fragment = highlight(targetLang, parsed.code, parsed.meta, meta ?? {});
61
+ if (!fragment) return;
62
+ if (parsed.type === "inline") {
63
+ const head = fragment.children[0];
64
+ if (head.type === "element" && head.tagName === "pre") head.tagName = "span";
65
+ }
66
+ parent.children[index] = fragment;
67
+ };
68
+ if (lazyLoad) try {
69
+ queue.push(highlighter.loadLanguage(lang).then(() => processNode(lang)).catch((error) => {
70
+ if (fallbackLanguage) processNode(fallbackLanguage);
71
+ else if (onError) onError(error);
72
+ else throw error;
73
+ }));
74
+ } catch (error) {
75
+ if (fallbackLanguage) return processNode(fallbackLanguage);
76
+ else if (onError) onError(error);
77
+ else throw error;
78
+ }
79
+ else processNode(lang);
80
+ return "skip";
81
+ });
82
+ if (queue.length > 0) {
83
+ async function run() {
84
+ await Promise.all(queue);
85
+ }
86
+ return run();
87
+ }
88
+ };
165
89
  }
166
90
 
167
- export { rehypeShikiFromHighlighter as default };
91
+ //#endregion
92
+ export { rehypeShikiFromHighlighter as default };
@@ -0,0 +1,29 @@
1
+ import { toString } from "hast-util-to-string";
2
+
3
+ //#region src/handlers.ts
4
+ const InlineCodeHandlers = { "tailing-curly-colon": (_tree, node) => {
5
+ const raw = toString(node);
6
+ const match = raw.match(/(.+)\{:([\w-]+)\}$/);
7
+ if (!match) return;
8
+ return {
9
+ type: "inline",
10
+ code: match[1] ?? raw,
11
+ lang: match.at(2)
12
+ };
13
+ } };
14
+ const languagePrefix = "language-";
15
+ const PreHandler = (_tree, node) => {
16
+ const head = node.children[0];
17
+ if (!head || head.type !== "element" || head.tagName !== "code" || !head.properties) return;
18
+ const classes = head.properties.className;
19
+ const languageClass = Array.isArray(classes) ? classes.find((d) => typeof d === "string" && d.startsWith(languagePrefix)) : void 0;
20
+ return {
21
+ type: "pre",
22
+ lang: typeof languageClass === "string" ? languageClass.slice(9) : void 0,
23
+ code: toString(head),
24
+ meta: head.data?.meta ?? head.properties.metastring?.toString() ?? ""
25
+ };
26
+ };
27
+
28
+ //#endregion
29
+ export { PreHandler as n, InlineCodeHandlers as t };
package/dist/index.d.mts CHANGED
@@ -1,23 +1,23 @@
1
- import { LanguageInput } from '@shikijs/types';
2
- import { Root } from 'hast';
3
- import { BuiltinLanguage } from 'shiki';
4
- import { Plugin } from 'unified';
5
- import { R as RehypeShikiCoreOptions } from './shared/rehype.DcMmi29I.mjs';
1
+ import { n as RehypeShikiCoreOptions } from "./types-Wi2EaRpk.mjs";
2
+ import { BuiltinLanguage } from "shiki";
3
+ import { LanguageInput } from "@shikijs/types";
4
+ import { Root } from "hast";
5
+ import { Plugin } from "unified";
6
6
 
7
+ //#region src/index.d.ts
7
8
  type RehypeShikiOptions = RehypeShikiCoreOptions & {
8
- /**
9
- * Language names to include.
10
- *
11
- * @default Object.keys(bundledLanguages)
12
- */
13
- langs?: Array<LanguageInput | BuiltinLanguage>;
14
- /**
15
- * Alias of languages
16
- * @example { 'my-lang': 'javascript' }
17
- */
18
- langAlias?: Record<string, string>;
9
+ /**
10
+ * Language names to include.
11
+ *
12
+ * @default Object.keys(bundledLanguages)
13
+ */
14
+ langs?: Array<LanguageInput | BuiltinLanguage>;
15
+ /**
16
+ * Alias of languages
17
+ * @example { 'my-lang': 'javascript' }
18
+ */
19
+ langAlias?: Record<string, string>;
19
20
  };
20
21
  declare const rehypeShiki: Plugin<[RehypeShikiOptions], Root>;
21
-
22
- export { rehypeShiki as default };
23
- export type { RehypeShikiOptions };
22
+ //#endregion
23
+ export { RehypeShikiOptions, rehypeShiki as default };
package/dist/index.mjs CHANGED
@@ -1,25 +1,21 @@
1
- import { bundledLanguages, getSingletonHighlighter } from 'shiki';
2
- import rehypeShikiFromHighlighter from './core.mjs';
3
- import 'shiki/core';
4
- import 'unist-util-visit';
5
- import 'hast-util-to-string';
1
+ import rehypeShikiFromHighlighter from "./core.mjs";
2
+ import { bundledLanguages, getSingletonHighlighter } from "shiki";
6
3
 
4
+ //#region src/index.ts
7
5
  const rehypeShiki = function(options = {}) {
8
- const themeNames = ("themes" in options ? Object.values(options.themes) : [options.theme]).filter(Boolean);
9
- const langs = options.langs || Object.keys(bundledLanguages);
10
- const langAlias = options.langAlias || {};
11
- let getHandler;
12
- return async (tree) => {
13
- if (!getHandler) {
14
- getHandler = getSingletonHighlighter({
15
- themes: themeNames,
16
- langs,
17
- langAlias
18
- }).then((highlighter) => rehypeShikiFromHighlighter.call(this, highlighter, options));
19
- }
20
- const handler = await getHandler;
21
- return handler(tree);
22
- };
6
+ const themeNames = ("themes" in options ? Object.values(options.themes) : [options.theme]).filter(Boolean);
7
+ const langs = options.langs || Object.keys(bundledLanguages);
8
+ const langAlias = options.langAlias || {};
9
+ let getHandler;
10
+ return async (tree) => {
11
+ if (!getHandler) getHandler = getSingletonHighlighter({
12
+ themes: themeNames,
13
+ langs,
14
+ langAlias
15
+ }).then((highlighter) => rehypeShikiFromHighlighter.call(this, highlighter, options));
16
+ return (await getHandler)(tree);
17
+ };
23
18
  };
24
19
 
25
- export { rehypeShiki as default };
20
+ //#endregion
21
+ export { rehypeShiki as default };
@@ -0,0 +1,69 @@
1
+ import { BuiltinTheme, CodeOptionsMeta, CodeOptionsThemes, CodeToHastOptionsCommon, TransformerOptions } from "shiki";
2
+ import { Element, Root } from "hast";
3
+
4
+ //#region src/types.d.ts
5
+ interface MapLike<K = any, V = any> {
6
+ get: (key: K) => V | undefined;
7
+ set: (key: K, value: V) => this;
8
+ }
9
+ interface RehypeShikiExtraOptions {
10
+ /**
11
+ * Add `language-*` class to code element
12
+ *
13
+ * @default false
14
+ */
15
+ addLanguageClass?: boolean;
16
+ /**
17
+ * The default language to use when is not specified
18
+ */
19
+ defaultLanguage?: string;
20
+ /**
21
+ * The fallback language to use when specified language is not loaded, or not included in the bundle
22
+ */
23
+ fallbackLanguage?: string;
24
+ /**
25
+ * Load languages and themes on-demand.
26
+ * When enable, this would make requires the unified pipeline to be async.
27
+ *
28
+ * @default false
29
+ */
30
+ lazy?: boolean;
31
+ /**
32
+ * `mdast-util-to-hast` adds a newline to the end of code blocks
33
+ *
34
+ * This option strips that newline from the code block
35
+ *
36
+ * @default true
37
+ * @see https://github.com/syntax-tree/mdast-util-to-hast/blob/f511a93817b131fb73419bf7d24d73a5b8b0f0c2/lib/handlers/code.js#L22
38
+ */
39
+ stripEndNewline?: boolean;
40
+ /**
41
+ * Custom meta string parser
42
+ * Return an object to merge with `meta`
43
+ */
44
+ parseMetaString?: (metaString: string, node: Element, tree: Root) => Record<string, any> | undefined | null;
45
+ /**
46
+ * Highlight inline code blocks
47
+ *
48
+ * - `false`: disable inline code block highlighting
49
+ * - `tailing-curly-colon`: highlight with `\`code{:lang}\``
50
+ *
51
+ * @see https://shiki.style/packages/rehype#inline-code
52
+ * @default false
53
+ */
54
+ inline?: false | 'tailing-curly-colon';
55
+ /**
56
+ * Custom map to cache transformed codeToHast result
57
+ *
58
+ * @default undefined
59
+ */
60
+ cache?: MapLike<string, Root>;
61
+ /**
62
+ * Chance to handle the error
63
+ * If not provided, the error will be thrown
64
+ */
65
+ onError?: (error: unknown) => void;
66
+ }
67
+ type RehypeShikiCoreOptions = CodeOptionsThemes<BuiltinTheme> & TransformerOptions & CodeOptionsMeta & RehypeShikiExtraOptions & Omit<CodeToHastOptionsCommon, 'lang'>;
68
+ //#endregion
69
+ export { RehypeShikiCoreOptions as n, RehypeShikiExtraOptions as r, MapLike as t };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shikijs/rehype",
3
3
  "type": "module",
4
- "version": "3.23.0",
4
+ "version": "4.0.1",
5
5
  "description": "rehype integration for shiki",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -27,23 +27,26 @@
27
27
  "files": [
28
28
  "dist"
29
29
  ],
30
+ "engines": {
31
+ "node": ">=20"
32
+ },
30
33
  "dependencies": {
31
34
  "@types/hast": "^3.0.4",
32
35
  "hast-util-to-string": "^3.0.1",
33
36
  "unified": "^11.0.5",
34
37
  "unist-util-visit": "^5.1.0",
35
- "@shikijs/types": "3.23.0",
36
- "shiki": "3.23.0"
38
+ "shiki": "4.0.1",
39
+ "@shikijs/types": "4.0.1"
37
40
  },
38
41
  "devDependencies": {
39
42
  "rehype-raw": "^7.0.0",
40
43
  "rehype-stringify": "^10.0.1",
41
44
  "remark-parse": "^11.0.0",
42
45
  "remark-rehype": "^11.1.2",
43
- "@shikijs/transformers": "3.23.0"
46
+ "@shikijs/transformers": "4.0.1"
44
47
  },
45
48
  "scripts": {
46
- "build": "unbuild",
47
- "dev": "unbuild --stub"
49
+ "build": "tsdown",
50
+ "dev": "tsdown --watch"
48
51
  }
49
52
  }
@@ -1,68 +0,0 @@
1
- import { Element, Root } from 'hast';
2
- import { CodeOptionsThemes, BuiltinTheme, TransformerOptions, CodeOptionsMeta, CodeToHastOptionsCommon } from 'shiki';
3
-
4
- interface MapLike<K = any, V = any> {
5
- get: (key: K) => V | undefined;
6
- set: (key: K, value: V) => this;
7
- }
8
- interface RehypeShikiExtraOptions {
9
- /**
10
- * Add `language-*` class to code element
11
- *
12
- * @default false
13
- */
14
- addLanguageClass?: boolean;
15
- /**
16
- * The default language to use when is not specified
17
- */
18
- defaultLanguage?: string;
19
- /**
20
- * The fallback language to use when specified language is not loaded, or not included in the bundle
21
- */
22
- fallbackLanguage?: string;
23
- /**
24
- * Load languages and themes on-demand.
25
- * When enable, this would make requires the unified pipeline to be async.
26
- *
27
- * @default false
28
- */
29
- lazy?: boolean;
30
- /**
31
- * `mdast-util-to-hast` adds a newline to the end of code blocks
32
- *
33
- * This option strips that newline from the code block
34
- *
35
- * @default true
36
- * @see https://github.com/syntax-tree/mdast-util-to-hast/blob/f511a93817b131fb73419bf7d24d73a5b8b0f0c2/lib/handlers/code.js#L22
37
- */
38
- stripEndNewline?: boolean;
39
- /**
40
- * Custom meta string parser
41
- * Return an object to merge with `meta`
42
- */
43
- parseMetaString?: (metaString: string, node: Element, tree: Root) => Record<string, any> | undefined | null;
44
- /**
45
- * Highlight inline code blocks
46
- *
47
- * - `false`: disable inline code block highlighting
48
- * - `tailing-curly-colon`: highlight with `\`code{:lang}\``
49
- *
50
- * @see https://shiki.style/packages/rehype#inline-code
51
- * @default false
52
- */
53
- inline?: false | 'tailing-curly-colon';
54
- /**
55
- * Custom map to cache transformed codeToHast result
56
- *
57
- * @default undefined
58
- */
59
- cache?: MapLike<string, Root>;
60
- /**
61
- * Chance to handle the error
62
- * If not provided, the error will be thrown
63
- */
64
- onError?: (error: unknown) => void;
65
- }
66
- type RehypeShikiCoreOptions = CodeOptionsThemes<BuiltinTheme> & TransformerOptions & CodeOptionsMeta & RehypeShikiExtraOptions & Omit<CodeToHastOptionsCommon, 'lang'>;
67
-
68
- export type { MapLike as M, RehypeShikiCoreOptions as R, RehypeShikiExtraOptions as a };