@shikijs/rehype 1.14.0 → 1.15.0

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,54 +1,10 @@
1
- import { CodeOptionsThemes, TransformerOptions, CodeOptionsMeta, CodeToHastOptionsCommon, HighlighterGeneric } from 'shiki/core';
2
- import { Element, Root } from 'hast';
3
- import { BuiltinTheme } from 'shiki';
1
+ import { HighlighterGeneric } from 'shiki/core';
2
+ import { Root } from 'hast';
4
3
  import { Transformer } from 'unified';
4
+ import { R as RehypeShikiCoreOptions } from './shared/rehype.198b1df4.mjs';
5
+ export { M as MapLike, a as RehypeShikiExtraOptions } from './shared/rehype.198b1df4.mjs';
6
+ import 'shiki';
5
7
 
6
- interface MapLike<K = any, V = any> {
7
- get: (key: K) => V | undefined;
8
- set: (key: K, value: V) => this;
9
- }
10
- interface RehypeShikiExtraOptions {
11
- /**
12
- * Add `language-*` class to code element
13
- *
14
- * @default false
15
- */
16
- addLanguageClass?: boolean;
17
- /**
18
- * The default language to use when is not specified
19
- */
20
- defaultLanguage?: string;
21
- /**
22
- * The fallback language to use when specified language is not loaded
23
- */
24
- fallbackLanguage?: string;
25
- /**
26
- * `mdast-util-to-hast` adds a newline to the end of code blocks
27
- *
28
- * This option strips that newline from the code block
29
- *
30
- * @default true
31
- * @see https://github.com/syntax-tree/mdast-util-to-hast/blob/f511a93817b131fb73419bf7d24d73a5b8b0f0c2/lib/handlers/code.js#L22
32
- */
33
- stripEndNewline?: boolean;
34
- /**
35
- * Custom meta string parser
36
- * Return an object to merge with `meta`
37
- */
38
- parseMetaString?: (metaString: string, node: Element, tree: Root) => Record<string, any> | undefined | null;
39
- /**
40
- * Custom map to cache transformed codeToHast result
41
- *
42
- * @default undefined
43
- */
44
- cache?: MapLike;
45
- /**
46
- * Chance to handle the error
47
- * If not provided, the error will be thrown
48
- */
49
- onError?: (error: unknown) => void;
50
- }
51
- type RehypeShikiCoreOptions = CodeOptionsThemes<BuiltinTheme> & TransformerOptions & CodeOptionsMeta & RehypeShikiExtraOptions & Omit<CodeToHastOptionsCommon, 'lang'>;
52
8
  declare function rehypeShikiFromHighlighter(highlighter: HighlighterGeneric<any, any>, options: RehypeShikiCoreOptions): Transformer<Root, Root>;
53
9
 
54
- export { type MapLike, type RehypeShikiCoreOptions, type RehypeShikiExtraOptions, rehypeShikiFromHighlighter as default };
10
+ export { RehypeShikiCoreOptions, rehypeShikiFromHighlighter as default };
package/dist/core.d.ts CHANGED
@@ -1,54 +1,10 @@
1
- import { CodeOptionsThemes, TransformerOptions, CodeOptionsMeta, CodeToHastOptionsCommon, HighlighterGeneric } from 'shiki/core';
2
- import { Element, Root } from 'hast';
3
- import { BuiltinTheme } from 'shiki';
1
+ import { HighlighterGeneric } from 'shiki/core';
2
+ import { Root } from 'hast';
4
3
  import { Transformer } from 'unified';
4
+ import { R as RehypeShikiCoreOptions } from './shared/rehype.198b1df4.js';
5
+ export { M as MapLike, a as RehypeShikiExtraOptions } from './shared/rehype.198b1df4.js';
6
+ import 'shiki';
5
7
 
6
- interface MapLike<K = any, V = any> {
7
- get: (key: K) => V | undefined;
8
- set: (key: K, value: V) => this;
9
- }
10
- interface RehypeShikiExtraOptions {
11
- /**
12
- * Add `language-*` class to code element
13
- *
14
- * @default false
15
- */
16
- addLanguageClass?: boolean;
17
- /**
18
- * The default language to use when is not specified
19
- */
20
- defaultLanguage?: string;
21
- /**
22
- * The fallback language to use when specified language is not loaded
23
- */
24
- fallbackLanguage?: string;
25
- /**
26
- * `mdast-util-to-hast` adds a newline to the end of code blocks
27
- *
28
- * This option strips that newline from the code block
29
- *
30
- * @default true
31
- * @see https://github.com/syntax-tree/mdast-util-to-hast/blob/f511a93817b131fb73419bf7d24d73a5b8b0f0c2/lib/handlers/code.js#L22
32
- */
33
- stripEndNewline?: boolean;
34
- /**
35
- * Custom meta string parser
36
- * Return an object to merge with `meta`
37
- */
38
- parseMetaString?: (metaString: string, node: Element, tree: Root) => Record<string, any> | undefined | null;
39
- /**
40
- * Custom map to cache transformed codeToHast result
41
- *
42
- * @default undefined
43
- */
44
- cache?: MapLike;
45
- /**
46
- * Chance to handle the error
47
- * If not provided, the error will be thrown
48
- */
49
- onError?: (error: unknown) => void;
50
- }
51
- type RehypeShikiCoreOptions = CodeOptionsThemes<BuiltinTheme> & TransformerOptions & CodeOptionsMeta & RehypeShikiExtraOptions & Omit<CodeToHastOptionsCommon, 'lang'>;
52
8
  declare function rehypeShikiFromHighlighter(highlighter: HighlighterGeneric<any, any>, options: RehypeShikiCoreOptions): Transformer<Root, Root>;
53
9
 
54
- export { type MapLike, type RehypeShikiCoreOptions, type RehypeShikiExtraOptions, rehypeShikiFromHighlighter as default };
10
+ export { RehypeShikiCoreOptions, rehypeShikiFromHighlighter as default };
package/dist/core.mjs CHANGED
@@ -1,6 +1,27 @@
1
1
  import { toString } from 'hast-util-to-string';
2
2
  import { visit } from 'unist-util-visit';
3
3
 
4
+ const InlineCodeProcessors = {
5
+ "tailing-curly-colon": ({ node, getLanguage, highlight }) => {
6
+ const raw = toString(node);
7
+ const match = raw.match(/(.+)\{:([\w-]+)\}$/);
8
+ if (!match)
9
+ return;
10
+ const lang = getLanguage(match[2]);
11
+ if (!lang)
12
+ return;
13
+ const code = match[1] ?? raw;
14
+ const fragment = highlight(lang, code);
15
+ if (!fragment)
16
+ return;
17
+ const head = fragment.children[0];
18
+ if (head.type === "element" && head.tagName === "pre") {
19
+ head.tagName = "span";
20
+ }
21
+ return fragment;
22
+ }
23
+ };
24
+
4
25
  const languagePrefix = "language-";
5
26
  function rehypeShikiFromHighlighter(highlighter, options) {
6
27
  const langs = highlighter.getLoadedLanguages();
@@ -12,63 +33,89 @@ function rehypeShikiFromHighlighter(highlighter, options) {
12
33
  fallbackLanguage,
13
34
  onError,
14
35
  stripEndNewline = true,
36
+ inline = false,
15
37
  ...rest
16
38
  } = options;
39
+ function getLanguage(lang = defaultLanguage) {
40
+ if (lang && fallbackLanguage && !langs.includes(lang))
41
+ return fallbackLanguage;
42
+ return lang;
43
+ }
44
+ function highlight(lang, code, metaString = "", meta = {}) {
45
+ const cacheKey = `${lang}:${metaString}:${code}`;
46
+ const cachedValue = cache?.get(cacheKey);
47
+ if (cachedValue) {
48
+ return cachedValue;
49
+ }
50
+ const codeOptions = {
51
+ ...rest,
52
+ lang,
53
+ meta: {
54
+ ...rest.meta,
55
+ ...meta,
56
+ __raw: metaString
57
+ }
58
+ };
59
+ if (addLanguageClass) {
60
+ codeOptions.transformers = [
61
+ ...codeOptions.transformers ?? [],
62
+ {
63
+ name: "rehype-shiki:code-language-class",
64
+ code(node) {
65
+ this.addClassToHast(node, `${languagePrefix}${lang}`);
66
+ return node;
67
+ }
68
+ }
69
+ ];
70
+ }
71
+ if (stripEndNewline && code.endsWith("\n"))
72
+ code = code.slice(0, -1);
73
+ try {
74
+ const fragment = highlighter.codeToHast(code, codeOptions);
75
+ cache?.set(cacheKey, fragment);
76
+ return fragment;
77
+ } catch (error) {
78
+ if (onError)
79
+ onError(error);
80
+ else
81
+ throw error;
82
+ }
83
+ }
84
+ function processPre(tree, node) {
85
+ const head = node.children[0];
86
+ if (!head || head.type !== "element" || head.tagName !== "code" || !head.properties) {
87
+ return;
88
+ }
89
+ const classes = head.properties.className;
90
+ const languageClass = Array.isArray(classes) ? classes.find(
91
+ (d) => typeof d === "string" && d.startsWith(languagePrefix)
92
+ ) : void 0;
93
+ const lang = getLanguage(
94
+ typeof languageClass === "string" ? languageClass.slice(languagePrefix.length) : void 0
95
+ );
96
+ if (!lang)
97
+ return;
98
+ const code = toString(head);
99
+ const metaString = head.data?.meta ?? head.properties.metastring?.toString() ?? "";
100
+ const meta = parseMetaString?.(metaString, node, tree) || {};
101
+ return highlight(lang, code, metaString, meta);
102
+ }
17
103
  return function(tree) {
18
104
  visit(tree, "element", (node, index, parent) => {
19
- if (!parent || index == null || node.tagName !== "pre")
20
- return;
21
- const head = node.children[0];
22
- if (!head || head.type !== "element" || head.tagName !== "code" || !head.properties) {
105
+ if (!parent || index == null)
23
106
  return;
24
- }
25
- const classes = head.properties.className;
26
- const languageClass = Array.isArray(classes) ? classes.find(
27
- (d) => typeof d === "string" && d.startsWith(languagePrefix)
28
- ) : void 0;
29
- let lang = typeof languageClass === "string" ? languageClass.slice(languagePrefix.length) : defaultLanguage;
30
- if (!lang)
31
- return;
32
- if (fallbackLanguage && !langs.includes(lang))
33
- lang = fallbackLanguage;
34
- let code = toString(head);
35
- if (stripEndNewline && code.endsWith("\n"))
36
- code = code.slice(0, -1);
37
- const cachedValue = cache?.get(code);
38
- if (cachedValue) {
39
- parent.children.splice(index, 1, ...cachedValue);
40
- return;
41
- }
42
- const metaString = head.data?.meta ?? head.properties.metastring?.toString() ?? "";
43
- const meta = parseMetaString?.(metaString, node, tree) || {};
44
- const codeOptions = {
45
- ...rest,
46
- lang,
47
- meta: {
48
- ...rest.meta,
49
- ...meta,
50
- __raw: metaString
107
+ if (node.tagName === "pre") {
108
+ const result = processPre(tree, node);
109
+ if (result) {
110
+ parent.children.splice(index, 1, ...result.children);
51
111
  }
52
- };
53
- if (addLanguageClass) {
54
- codeOptions.transformers || (codeOptions.transformers = []);
55
- codeOptions.transformers.push({
56
- name: "rehype-shiki:code-language-class",
57
- code(node2) {
58
- this.addClassToHast(node2, `${languagePrefix}${lang}`);
59
- return node2;
60
- }
61
- });
112
+ return "skip";
62
113
  }
63
- try {
64
- const fragment = highlighter.codeToHast(code, codeOptions);
65
- cache?.set(code, fragment.children);
66
- parent.children.splice(index, 1, ...fragment.children);
67
- } catch (error) {
68
- if (onError)
69
- onError(error);
70
- else
71
- throw error;
114
+ if (node.tagName === "code" && inline) {
115
+ const result = InlineCodeProcessors[inline]?.({ node, getLanguage, highlight });
116
+ if (result) {
117
+ parent.children.splice(index, 1, ...result.children);
118
+ }
72
119
  }
73
120
  });
74
121
  };
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ import { LanguageInput } from 'shiki/core';
2
2
  import { BuiltinLanguage } from 'shiki';
3
3
  import { Plugin } from 'unified';
4
4
  import { Root } from 'hast';
5
- import { RehypeShikiCoreOptions } from './core.mjs';
5
+ import { R as RehypeShikiCoreOptions } from './shared/rehype.198b1df4.mjs';
6
6
 
7
7
  type RehypeShikiOptions = RehypeShikiCoreOptions & {
8
8
  /**
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { LanguageInput } from 'shiki/core';
2
2
  import { BuiltinLanguage } from 'shiki';
3
3
  import { Plugin } from 'unified';
4
4
  import { Root } from 'hast';
5
- import { RehypeShikiCoreOptions } from './core.js';
5
+ import { R as RehypeShikiCoreOptions } from './shared/rehype.198b1df4.js';
6
6
 
7
7
  type RehypeShikiOptions = RehypeShikiCoreOptions & {
8
8
  /**
@@ -0,0 +1,61 @@
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
21
+ */
22
+ fallbackLanguage?: string;
23
+ /**
24
+ * `mdast-util-to-hast` adds a newline to the end of code blocks
25
+ *
26
+ * This option strips that newline from the code block
27
+ *
28
+ * @default true
29
+ * @see https://github.com/syntax-tree/mdast-util-to-hast/blob/f511a93817b131fb73419bf7d24d73a5b8b0f0c2/lib/handlers/code.js#L22
30
+ */
31
+ stripEndNewline?: boolean;
32
+ /**
33
+ * Custom meta string parser
34
+ * Return an object to merge with `meta`
35
+ */
36
+ parseMetaString?: (metaString: string, node: Element, tree: Root) => Record<string, any> | undefined | null;
37
+ /**
38
+ * Highlight inline code blocks
39
+ *
40
+ * - `false`: disable inline code block highlighting
41
+ * - `tailing-curly-colon`: highlight with `\`code{:lang}\``
42
+ *
43
+ * @see https://shiki.style/packages/rehype#inline-code
44
+ * @default false
45
+ */
46
+ inline?: false | 'tailing-curly-colon';
47
+ /**
48
+ * Custom map to cache transformed codeToHast result
49
+ *
50
+ * @default undefined
51
+ */
52
+ cache?: MapLike<string, Root>;
53
+ /**
54
+ * Chance to handle the error
55
+ * If not provided, the error will be thrown
56
+ */
57
+ onError?: (error: unknown) => void;
58
+ }
59
+ type RehypeShikiCoreOptions = CodeOptionsThemes<BuiltinTheme> & TransformerOptions & CodeOptionsMeta & RehypeShikiExtraOptions & Omit<CodeToHastOptionsCommon, 'lang'>;
60
+
61
+ export type { MapLike as M, RehypeShikiCoreOptions as R, RehypeShikiExtraOptions as a };
@@ -0,0 +1,61 @@
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
21
+ */
22
+ fallbackLanguage?: string;
23
+ /**
24
+ * `mdast-util-to-hast` adds a newline to the end of code blocks
25
+ *
26
+ * This option strips that newline from the code block
27
+ *
28
+ * @default true
29
+ * @see https://github.com/syntax-tree/mdast-util-to-hast/blob/f511a93817b131fb73419bf7d24d73a5b8b0f0c2/lib/handlers/code.js#L22
30
+ */
31
+ stripEndNewline?: boolean;
32
+ /**
33
+ * Custom meta string parser
34
+ * Return an object to merge with `meta`
35
+ */
36
+ parseMetaString?: (metaString: string, node: Element, tree: Root) => Record<string, any> | undefined | null;
37
+ /**
38
+ * Highlight inline code blocks
39
+ *
40
+ * - `false`: disable inline code block highlighting
41
+ * - `tailing-curly-colon`: highlight with `\`code{:lang}\``
42
+ *
43
+ * @see https://shiki.style/packages/rehype#inline-code
44
+ * @default false
45
+ */
46
+ inline?: false | 'tailing-curly-colon';
47
+ /**
48
+ * Custom map to cache transformed codeToHast result
49
+ *
50
+ * @default undefined
51
+ */
52
+ cache?: MapLike<string, Root>;
53
+ /**
54
+ * Chance to handle the error
55
+ * If not provided, the error will be thrown
56
+ */
57
+ onError?: (error: unknown) => void;
58
+ }
59
+ type RehypeShikiCoreOptions = CodeOptionsThemes<BuiltinTheme> & TransformerOptions & CodeOptionsMeta & RehypeShikiExtraOptions & Omit<CodeToHastOptionsCommon, 'lang'>;
60
+
61
+ export type { MapLike as M, RehypeShikiCoreOptions as R, RehypeShikiExtraOptions as a };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shikijs/rehype",
3
3
  "type": "module",
4
- "version": "1.14.0",
4
+ "version": "1.15.0",
5
5
  "description": "rehype integration for shiki",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -49,8 +49,8 @@
49
49
  "hast-util-to-string": "^3.0.0",
50
50
  "unified": "^11.0.5",
51
51
  "unist-util-visit": "^5.0.0",
52
- "@shikijs/transformers": "1.14.0",
53
- "shiki": "1.14.0"
52
+ "@shikijs/transformers": "1.15.0",
53
+ "shiki": "1.15.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "rehype-raw": "^7.0.0",