@astrojs/markdown-remark 3.3.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,12 +22,14 @@ 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",
28
29
  shikiConfig: {
29
30
  langs: [],
30
31
  theme: "github-dark",
32
+ experimentalThemes: {},
31
33
  wrap: false
32
34
  },
33
35
  remarkPlugins: [],
@@ -146,11 +148,13 @@ ${err.message}`;
146
148
  export {
147
149
  InvalidAstroDataError2 as InvalidAstroDataError,
148
150
  createMarkdownProcessor,
151
+ createShikiHighlighter,
149
152
  markdownConfigDefaults,
150
153
  rehypeHeadingIds2 as rehypeHeadingIds,
151
154
  remarkCollectImages2 as remarkCollectImages,
152
155
  remarkPrism2 as remarkPrism,
153
156
  remarkShiki2 as remarkShiki,
154
157
  renderMarkdown,
158
+ replaceCssVariables,
155
159
  setVfileFrontmatter2 as setVfileFrontmatter
156
160
  };
@@ -1,2 +1,2 @@
1
1
  import type { RemarkPlugin, ShikiConfig } from './types.js';
2
- export declare function remarkShiki({ langs, theme, wrap, }?: ShikiConfig): ReturnType<RemarkPlugin>;
2
+ export declare function remarkShiki(config?: ShikiConfig): ReturnType<RemarkPlugin>;
@@ -1,81 +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
- wrap = false
25
- } = {}) {
26
- const cacheId = (typeof theme === "string" ? theme : theme.name ?? "") + langs.map((l) => l.name ?? l.id).join(",");
27
- let highlighterAsync = highlighterCacheAsync.get(cacheId);
28
- if (!highlighterAsync) {
29
- highlighterAsync = getHighlighter({
30
- langs: langs.length ? langs : Object.keys(bundledLanguages),
31
- themes: [theme]
32
- });
33
- highlighterCacheAsync.set(cacheId, highlighterAsync);
34
- }
2
+ import { createShikiHighlighter } from "./shiki.js";
3
+ function remarkShiki(config) {
4
+ let highlighterAsync;
35
5
  return async (tree) => {
6
+ highlighterAsync ??= createShikiHighlighter(config);
36
7
  const highlighter = await highlighterAsync;
37
8
  visit(tree, "code", (node) => {
38
- let lang;
39
- if (typeof node.lang === "string") {
40
- const langExists = highlighter.getLoadedLanguages().includes(node.lang);
41
- if (langExists) {
42
- lang = node.lang;
43
- } else {
44
- console.warn(`The language "${node.lang}" doesn't exist, falling back to plaintext.`);
45
- lang = "plaintext";
46
- }
47
- } else {
48
- lang = "plaintext";
49
- }
50
- let html = highlighter.codeToHtml(node.value, { lang, theme });
51
- html = html.replace(/<pre class="(.*?)shiki(.*?)"/, `<pre class="$1astro-code$2"`);
52
- if (node.lang === "diff") {
53
- html = html.replace(
54
- /<span class="line"><span style="(.*?)">([\+|\-])/g,
55
- '<span class="line"><span style="$1"><span style="user-select: none;">$2</span>'
56
- );
57
- }
58
- if (wrap === false) {
59
- html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"');
60
- } else if (wrap === true) {
61
- html = html.replace(
62
- /style="(.*?)"/,
63
- 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"'
64
- );
65
- }
66
- const themeName = typeof theme === "string" ? theme : theme.name;
67
- if (themeName === "css-variables") {
68
- html = html.replace(/style="(.*?)"/g, (m) => replaceCssVariables(m));
69
- }
9
+ const lang = typeof node.lang === "string" ? node.lang : "plaintext";
10
+ const html = highlighter.highlight(node.value, lang);
70
11
  node.type = "html";
71
12
  node.value = html;
72
13
  node.children = [];
73
14
  });
74
15
  };
75
16
  }
76
- function replaceCssVariables(str) {
77
- return str.replace(COLOR_REPLACEMENT_REGEX, (match) => ASTRO_COLOR_REPLACEMENTS[match] || match);
78
- }
79
17
  export {
80
18
  remarkShiki
81
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/dist/types.d.ts CHANGED
@@ -19,6 +19,7 @@ export type RemarkRehype = Omit<RemarkRehypeOptions, 'handlers' | 'unknownHandle
19
19
  export interface ShikiConfig {
20
20
  langs?: LanguageRegistration[];
21
21
  theme?: BuiltinTheme | ThemeRegistration | ThemeRegistrationRaw;
22
+ experimentalThemes?: Record<string, BuiltinTheme | ThemeRegistration | ThemeRegistrationRaw>;
22
23
  wrap?: boolean | null;
23
24
  }
24
25
  export interface AstroMarkdownOptions {
@@ -41,8 +42,6 @@ export interface MarkdownProcessor {
41
42
  render: (content: string, opts?: MarkdownProcessorRenderOptions) => Promise<MarkdownProcessorRenderResult>;
42
43
  }
43
44
  export interface MarkdownProcessorRenderOptions {
44
- /** @internal */
45
- fileURL?: URL;
46
45
  /** Used for frontmatter injection plugins */
47
46
  frontmatter?: Record<string, any>;
48
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",
@@ -20,7 +20,7 @@
20
20
  "dist"
21
21
  ],
22
22
  "peerDependencies": {
23
- "astro": "^3.3.0"
23
+ "astro": "^3.0.0"
24
24
  },
25
25
  "dependencies": {
26
26
  "@astrojs/prism": "^3.0.0",