@astrojs/markdown-remark 3.4.0 → 3.5.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/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { rehypeHeadingIds } from './rehype-collect-headings.js';
4
4
  export { remarkCollectImages } from './remark-collect-images.js';
5
5
  export { remarkPrism } from './remark-prism.js';
6
6
  export { remarkShiki } from './remark-shiki.js';
7
+ export { createShikiHighlighter, replaceCssVariables, type ShikiHighlighter } from './shiki.js';
7
8
  export * from './types.js';
8
9
  export declare const markdownConfigDefaults: Omit<Required<AstroMarkdownOptions>, 'drafts'>;
9
10
  /**
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings
22
22
  import { remarkCollectImages as remarkCollectImages2 } from "./remark-collect-images.js";
23
23
  import { remarkPrism as remarkPrism2 } from "./remark-prism.js";
24
24
  import { remarkShiki as remarkShiki2 } from "./remark-shiki.js";
25
+ import { createShikiHighlighter, replaceCssVariables } from "./shiki.js";
25
26
  export * from "./types.js";
26
27
  const markdownConfigDefaults = {
27
28
  syntaxHighlight: "shiki",
@@ -147,11 +148,13 @@ ${err.message}`;
147
148
  export {
148
149
  InvalidAstroDataError2 as InvalidAstroDataError,
149
150
  createMarkdownProcessor,
151
+ createShikiHighlighter,
150
152
  markdownConfigDefaults,
151
153
  rehypeHeadingIds2 as rehypeHeadingIds,
152
154
  remarkCollectImages2 as remarkCollectImages,
153
155
  remarkPrism2 as remarkPrism,
154
156
  remarkShiki2 as remarkShiki,
155
157
  renderMarkdown,
158
+ replaceCssVariables,
156
159
  setVfileFrontmatter2 as setVfileFrontmatter
157
160
  };
@@ -1,2 +1,2 @@
1
1
  import type { RemarkPlugin, ShikiConfig } from './types.js';
2
- export declare function remarkShiki({ langs, theme, experimentalThemes, wrap, }?: ShikiConfig): ReturnType<RemarkPlugin>;
2
+ export declare function remarkShiki(config?: ShikiConfig): ReturnType<RemarkPlugin>;
@@ -1,84 +1,19 @@
1
- import { bundledLanguages, getHighlighter } from "shikiji";
2
1
  import { visit } from "unist-util-visit";
3
- const ASTRO_COLOR_REPLACEMENTS = {
4
- "#000001": "var(--astro-code-color-text)",
5
- "#000002": "var(--astro-code-color-background)",
6
- "#000004": "var(--astro-code-token-constant)",
7
- "#000005": "var(--astro-code-token-string)",
8
- "#000006": "var(--astro-code-token-comment)",
9
- "#000007": "var(--astro-code-token-keyword)",
10
- "#000008": "var(--astro-code-token-parameter)",
11
- "#000009": "var(--astro-code-token-function)",
12
- "#000010": "var(--astro-code-token-string-expression)",
13
- "#000011": "var(--astro-code-token-punctuation)",
14
- "#000012": "var(--astro-code-token-link)"
15
- };
16
- const COLOR_REPLACEMENT_REGEX = new RegExp(
17
- `(${Object.keys(ASTRO_COLOR_REPLACEMENTS).join("|")})`,
18
- "g"
19
- );
20
- const highlighterCacheAsync = /* @__PURE__ */ new Map();
21
- function remarkShiki({
22
- langs = [],
23
- theme = "github-dark",
24
- experimentalThemes = {},
25
- wrap = false
26
- } = {}) {
27
- const themes = experimentalThemes;
28
- const cacheId = Object.values(themes).map((t) => typeof t === "string" ? t : t.name ?? "").join(",") + (typeof theme === "string" ? theme : theme.name ?? "") + langs.map((l) => l.name ?? l.id).join(",");
29
- let highlighterAsync = highlighterCacheAsync.get(cacheId);
30
- if (!highlighterAsync) {
31
- highlighterAsync = getHighlighter({
32
- langs: langs.length ? langs : Object.keys(bundledLanguages),
33
- themes: Object.values(themes).length ? Object.values(themes) : [theme]
34
- });
35
- highlighterCacheAsync.set(cacheId, highlighterAsync);
36
- }
2
+ import { createShikiHighlighter } from "./shiki.js";
3
+ function remarkShiki(config) {
4
+ let highlighterAsync;
37
5
  return async (tree) => {
6
+ highlighterAsync ??= createShikiHighlighter(config);
38
7
  const highlighter = await highlighterAsync;
39
8
  visit(tree, "code", (node) => {
40
- let lang;
41
- if (typeof node.lang === "string") {
42
- const langExists = highlighter.getLoadedLanguages().includes(node.lang);
43
- if (langExists) {
44
- lang = node.lang;
45
- } else {
46
- console.warn(`The language "${node.lang}" doesn't exist, falling back to plaintext.`);
47
- lang = "plaintext";
48
- }
49
- } else {
50
- lang = "plaintext";
51
- }
52
- let themeOptions = Object.values(themes).length ? { themes } : { theme };
53
- let html = highlighter.codeToHtml(node.value, { ...themeOptions, lang });
54
- html = html.replace(/<pre class="(.*?)shiki(.*?)"/, `<pre class="$1astro-code$2"`);
55
- if (node.lang === "diff") {
56
- html = html.replace(
57
- /<span class="line"><span style="(.*?)">([\+|\-])/g,
58
- '<span class="line"><span style="$1"><span style="user-select: none;">$2</span>'
59
- );
60
- }
61
- if (wrap === false) {
62
- html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"');
63
- } else if (wrap === true) {
64
- html = html.replace(
65
- /style="(.*?)"/,
66
- 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"'
67
- );
68
- }
69
- const themeName = typeof theme === "string" ? theme : theme.name;
70
- if (themeName === "css-variables") {
71
- html = html.replace(/style="(.*?)"/g, (m) => replaceCssVariables(m));
72
- }
9
+ const lang = typeof node.lang === "string" ? node.lang : "plaintext";
10
+ const html = highlighter.highlight(node.value, lang);
73
11
  node.type = "html";
74
12
  node.value = html;
75
13
  node.children = [];
76
14
  });
77
15
  };
78
16
  }
79
- function replaceCssVariables(str) {
80
- return str.replace(COLOR_REPLACEMENT_REGEX, (match) => ASTRO_COLOR_REPLACEMENTS[match] || match);
81
- }
82
17
  export {
83
18
  remarkShiki
84
19
  };
@@ -0,0 +1,7 @@
1
+ import type { ShikiConfig } from './types.js';
2
+ export interface ShikiHighlighter {
3
+ highlight(code: string, lang?: string, options?: {
4
+ inline?: boolean;
5
+ }): string;
6
+ }
7
+ export declare function createShikiHighlighter({ langs, theme, experimentalThemes, wrap, }?: ShikiConfig): Promise<ShikiHighlighter>;
package/dist/shiki.js ADDED
@@ -0,0 +1,104 @@
1
+ import { bundledLanguages, getHighlighter } from "shikiji";
2
+ import { visit } from "unist-util-visit";
3
+ const ASTRO_COLOR_REPLACEMENTS = {
4
+ "#000001": "var(--astro-code-color-text)",
5
+ "#000002": "var(--astro-code-color-background)",
6
+ "#000004": "var(--astro-code-token-constant)",
7
+ "#000005": "var(--astro-code-token-string)",
8
+ "#000006": "var(--astro-code-token-comment)",
9
+ "#000007": "var(--astro-code-token-keyword)",
10
+ "#000008": "var(--astro-code-token-parameter)",
11
+ "#000009": "var(--astro-code-token-function)",
12
+ "#000010": "var(--astro-code-token-string-expression)",
13
+ "#000011": "var(--astro-code-token-punctuation)",
14
+ "#000012": "var(--astro-code-token-link)"
15
+ };
16
+ const COLOR_REPLACEMENT_REGEX = new RegExp(
17
+ `(${Object.keys(ASTRO_COLOR_REPLACEMENTS).join("|")})`,
18
+ "g"
19
+ );
20
+ async function createShikiHighlighter({
21
+ langs = [],
22
+ theme = "github-dark",
23
+ experimentalThemes = {},
24
+ wrap = false
25
+ } = {}) {
26
+ const themes = experimentalThemes;
27
+ const highlighter = await getHighlighter({
28
+ langs: langs.length ? langs : Object.keys(bundledLanguages),
29
+ themes: Object.values(themes).length ? Object.values(themes) : [theme]
30
+ });
31
+ const loadedLanguages = highlighter.getLoadedLanguages();
32
+ return {
33
+ highlight(code, lang = "plaintext", options) {
34
+ if (lang !== "plaintext" && !loadedLanguages.includes(lang)) {
35
+ console.warn(`[Shiki] The language "${lang}" doesn't exist, falling back to "plaintext".`);
36
+ lang = "plaintext";
37
+ }
38
+ const themeOptions = Object.values(themes).length ? { themes } : { theme };
39
+ const inline = options?.inline ?? false;
40
+ return highlighter.codeToHtml(code, {
41
+ ...themeOptions,
42
+ lang,
43
+ transforms: {
44
+ pre(node) {
45
+ if (inline) {
46
+ node.tagName = "code";
47
+ }
48
+ const classValue = node.properties.class ?? "";
49
+ const styleValue = node.properties.style ?? "";
50
+ node.properties.class = classValue.replace(/shiki/g, "astro-code");
51
+ if (wrap === false) {
52
+ node.properties.style = styleValue + "; overflow-x: auto;";
53
+ } else if (wrap === true) {
54
+ node.properties.style = styleValue + "; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;";
55
+ }
56
+ },
57
+ line(node) {
58
+ if (lang === "diff") {
59
+ const innerSpanNode = node.children[0];
60
+ const innerSpanTextNode = innerSpanNode?.type === "element" && innerSpanNode.children?.[0];
61
+ if (innerSpanTextNode && innerSpanTextNode.type === "text") {
62
+ const start = innerSpanTextNode.value[0];
63
+ if (start === "+" || start === "-") {
64
+ innerSpanTextNode.value = innerSpanTextNode.value.slice(1);
65
+ innerSpanNode.children.unshift({
66
+ type: "element",
67
+ tagName: "span",
68
+ properties: { style: "user-select: none;" },
69
+ children: [{ type: "text", value: start }]
70
+ });
71
+ }
72
+ }
73
+ }
74
+ },
75
+ code(node) {
76
+ if (inline) {
77
+ return node.children[0];
78
+ }
79
+ },
80
+ root(node) {
81
+ if (Object.values(experimentalThemes).length) {
82
+ return;
83
+ }
84
+ const themeName = typeof theme === "string" ? theme : theme.name;
85
+ if (themeName === "css-variables") {
86
+ visit(node, "element", (child) => {
87
+ if (child.properties?.style) {
88
+ child.properties.style = replaceCssVariables(child.properties.style);
89
+ }
90
+ });
91
+ }
92
+ }
93
+ }
94
+ });
95
+ }
96
+ };
97
+ }
98
+ function replaceCssVariables(str) {
99
+ return str.replace(COLOR_REPLACEMENT_REGEX, (match) => ASTRO_COLOR_REPLACEMENTS[match] || match);
100
+ }
101
+ export {
102
+ createShikiHighlighter,
103
+ replaceCssVariables
104
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",