@astrojs/markdown-remark 5.2.0 → 6.0.0-alpha.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.
@@ -0,0 +1 @@
1
+ export declare function isFrontmatterValid(frontmatter: Record<string, any>): boolean;
@@ -0,0 +1,11 @@
1
+ function isFrontmatterValid(frontmatter) {
2
+ try {
3
+ JSON.stringify(frontmatter);
4
+ } catch {
5
+ return false;
6
+ }
7
+ return typeof frontmatter === "object" && frontmatter !== null;
8
+ }
9
+ export {
10
+ isFrontmatterValid
11
+ };
@@ -1,7 +1,7 @@
1
1
  import type { Root } from 'hast';
2
2
  type Highlighter = (code: string, language: string, options?: {
3
3
  meta?: string;
4
- }) => Promise<string>;
4
+ }) => Promise<Root | string>;
5
5
  /**
6
6
  * A hast utility to syntax highlight code blocks with a given syntax highlighter.
7
7
  *
package/dist/highlight.js CHANGED
@@ -16,13 +16,13 @@ async function highlightCodeBlocks(tree, highlighter) {
16
16
  let languageMatch;
17
17
  let { className } = node.properties;
18
18
  if (typeof className === "string") {
19
- languageMatch = className.match(languagePattern);
19
+ languageMatch = languagePattern.exec(className);
20
20
  } else if (Array.isArray(className)) {
21
21
  for (const cls of className) {
22
22
  if (typeof cls !== "string") {
23
23
  continue;
24
24
  }
25
- languageMatch = cls.match(languagePattern);
25
+ languageMatch = languagePattern.exec(cls);
26
26
  if (languageMatch) {
27
27
  break;
28
28
  }
@@ -41,9 +41,14 @@ async function highlightCodeBlocks(tree, highlighter) {
41
41
  for (const { node, language, grandParent, parent } of nodes) {
42
42
  const meta = node.data?.meta ?? node.properties.metastring ?? void 0;
43
43
  const code = toText(node, { whitespace: "pre" });
44
- const html = await highlighter(code, language, { meta });
45
- const replacement = fromHtml(html, { fragment: true }).children[0];
46
- removePosition(replacement);
44
+ const result = await highlighter(code, language, { meta });
45
+ let replacement;
46
+ if (typeof result === "string") {
47
+ replacement = fromHtml(result, { fragment: true }).children[0];
48
+ removePosition(replacement);
49
+ } else {
50
+ replacement = result.children[0];
51
+ }
47
52
  const index = grandParent.children.indexOf(parent);
48
53
  grandParent.children[index] = replacement;
49
54
  }
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import type { AstroMarkdownOptions, MarkdownProcessor } from './types.js';
2
- export { InvalidAstroDataError, setVfileFrontmatter } from './frontmatter-injection.js';
3
2
  export { rehypeHeadingIds } from './rehype-collect-headings.js';
4
3
  export { remarkCollectImages } from './remark-collect-images.js';
5
4
  export { rehypePrism } from './rehype-prism.js';
6
5
  export { rehypeShiki } from './rehype-shiki.js';
7
- export { createShikiHighlighter, type ShikiHighlighter } from './shiki.js';
6
+ export { isFrontmatterValid } from './frontmatter.js';
7
+ export { createShikiHighlighter, type ShikiHighlighter, type CreateShikiHighlighterOptions, type ShikiHighlighterHighlightOptions, } from './shiki.js';
8
8
  export * from './types.js';
9
9
  export declare const markdownConfigDefaults: Required<AstroMarkdownOptions>;
10
10
  /**
package/dist/index.js CHANGED
@@ -1,8 +1,3 @@
1
- import {
2
- InvalidAstroDataError,
3
- safelyGetAstroData,
4
- setVfileFrontmatter
5
- } from "./frontmatter-injection.js";
6
1
  import { loadPlugins } from "./load-plugins.js";
7
2
  import { rehypeHeadingIds } from "./rehype-collect-headings.js";
8
3
  import { rehypePrism } from "./rehype-prism.js";
@@ -17,12 +12,14 @@ import remarkSmartypants from "remark-smartypants";
17
12
  import { unified } from "unified";
18
13
  import { VFile } from "vfile";
19
14
  import { rehypeImages } from "./rehype-images.js";
20
- import { InvalidAstroDataError as InvalidAstroDataError2, setVfileFrontmatter as setVfileFrontmatter2 } from "./frontmatter-injection.js";
21
15
  import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings.js";
22
16
  import { remarkCollectImages as remarkCollectImages2 } from "./remark-collect-images.js";
23
17
  import { rehypePrism as rehypePrism2 } from "./rehype-prism.js";
24
18
  import { rehypeShiki as rehypeShiki2 } from "./rehype-shiki.js";
25
- import { createShikiHighlighter } from "./shiki.js";
19
+ import { isFrontmatterValid } from "./frontmatter.js";
20
+ import {
21
+ createShikiHighlighter
22
+ } from "./shiki.js";
26
23
  export * from "./types.js";
27
24
  const markdownConfigDefaults = {
28
25
  syntaxHighlight: "shiki",
@@ -89,23 +86,26 @@ async function createMarkdownProcessor(opts) {
89
86
  parser.use(rehypeRaw).use(rehypeStringify, { allowDangerousHtml: true });
90
87
  return {
91
88
  async render(content, renderOpts) {
92
- const vfile = new VFile({ value: content, path: renderOpts?.fileURL });
93
- setVfileFrontmatter(vfile, renderOpts?.frontmatter ?? {});
89
+ const vfile = new VFile({
90
+ value: content,
91
+ path: renderOpts?.fileURL,
92
+ data: {
93
+ astro: {
94
+ frontmatter: renderOpts?.frontmatter ?? {}
95
+ }
96
+ }
97
+ });
94
98
  const result = await parser.process(vfile).catch((err) => {
95
99
  err = prefixError(err, `Failed to parse Markdown file "${vfile.path}"`);
96
100
  console.error(err);
97
101
  throw err;
98
102
  });
99
- const astroData = safelyGetAstroData(result.data);
100
- if (astroData instanceof InvalidAstroDataError) {
101
- throw astroData;
102
- }
103
103
  return {
104
104
  code: String(result.value),
105
105
  metadata: {
106
- headings: result.data.__astroHeadings ?? [],
107
- imagePaths: result.data.imagePaths ?? /* @__PURE__ */ new Set(),
108
- frontmatter: astroData.frontmatter ?? {}
106
+ headings: result.data.astro?.headings ?? [],
107
+ imagePaths: result.data.astro?.imagePaths ?? [],
108
+ frontmatter: result.data.astro?.frontmatter ?? {}
109
109
  }
110
110
  };
111
111
  }
@@ -117,7 +117,7 @@ function prefixError(err, prefix) {
117
117
  err.message = `${prefix}:
118
118
  ${err.message}`;
119
119
  return err;
120
- } catch (error) {
120
+ } catch {
121
121
  }
122
122
  }
123
123
  const wrappedError = new Error(`${prefix}${err ? `: ${err}` : ""}`);
@@ -129,13 +129,12 @@ ${err.message}`;
129
129
  return wrappedError;
130
130
  }
131
131
  export {
132
- InvalidAstroDataError2 as InvalidAstroDataError,
133
132
  createMarkdownProcessor,
134
133
  createShikiHighlighter,
134
+ isFrontmatterValid,
135
135
  markdownConfigDefaults,
136
136
  rehypeHeadingIds2 as rehypeHeadingIds,
137
137
  rehypePrism2 as rehypePrism,
138
138
  rehypeShiki2 as rehypeShiki,
139
- remarkCollectImages2 as remarkCollectImages,
140
- setVfileFrontmatter2 as setVfileFrontmatter
139
+ remarkCollectImages2 as remarkCollectImages
141
140
  };
@@ -1,19 +1,18 @@
1
1
  import Slugger from "github-slugger";
2
2
  import { visit } from "unist-util-visit";
3
- import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js";
4
3
  const rawNodeTypes = /* @__PURE__ */ new Set(["text", "raw", "mdxTextExpression"]);
5
4
  const codeTagNames = /* @__PURE__ */ new Set(["code", "pre"]);
6
5
  function rehypeHeadingIds() {
7
6
  return function(tree, file) {
8
7
  const headings = [];
8
+ const frontmatter = file.data.astro?.frontmatter;
9
9
  const slugger = new Slugger();
10
10
  const isMDX = isMDXFile(file);
11
- const astroData = safelyGetAstroData(file.data);
12
11
  visit(tree, (node) => {
13
12
  if (node.type !== "element") return;
14
13
  const { tagName } = node;
15
14
  if (tagName[0] !== "h") return;
16
- const [, level] = tagName.match(/h([0-6])/) ?? [];
15
+ const [, level] = /h([0-6])/.exec(tagName) ?? [];
17
16
  if (!level) return;
18
17
  const depth = Number.parseInt(level);
19
18
  let text = "";
@@ -22,17 +21,20 @@ function rehypeHeadingIds() {
22
21
  return;
23
22
  }
24
23
  if (child.type === "raw") {
25
- if (child.value.match(/^\n?<.*>\n?$/)) {
24
+ if (/^\n?<.*>\n?$/.test(child.value)) {
26
25
  return;
27
26
  }
28
27
  }
29
28
  if (rawNodeTypes.has(child.type)) {
30
29
  if (isMDX || codeTagNames.has(parent.tagName)) {
31
30
  let value = child.value;
32
- if (isMdxTextExpression(child) && !(astroData instanceof InvalidAstroDataError)) {
31
+ if (isMdxTextExpression(child) && frontmatter) {
33
32
  const frontmatterPath = getMdxFrontmatterVariablePath(child);
34
33
  if (Array.isArray(frontmatterPath) && frontmatterPath.length > 0) {
35
- const frontmatterValue = getMdxFrontmatterVariableValue(astroData, frontmatterPath);
34
+ const frontmatterValue = getMdxFrontmatterVariableValue(
35
+ frontmatter,
36
+ frontmatterPath
37
+ );
36
38
  if (typeof frontmatterValue === "string") {
37
39
  value = frontmatterValue;
38
40
  }
@@ -52,7 +54,8 @@ function rehypeHeadingIds() {
52
54
  }
53
55
  headings.push({ depth, slug: node.properties.id, text });
54
56
  });
55
- file.data.__astroHeadings = headings;
57
+ file.data.astro ??= {};
58
+ file.data.astro.headings = headings;
56
59
  };
57
60
  }
58
61
  function isMDXFile(file) {
@@ -74,8 +77,8 @@ function getMdxFrontmatterVariablePath(node) {
74
77
  if (expression.type !== "Identifier" || expression.name !== "frontmatter") return new Error();
75
78
  return expressionPath.reverse();
76
79
  }
77
- function getMdxFrontmatterVariableValue(astroData, path) {
78
- let value = astroData.frontmatter;
80
+ function getMdxFrontmatterVariableValue(frontmatter, path) {
81
+ let value = frontmatter;
79
82
  for (const key of path) {
80
83
  if (!value[key]) return void 0;
81
84
  value = value[key];
@@ -1,2 +1,2 @@
1
- import type { MarkdownVFile } from './types.js';
2
- export declare function rehypeImages(): () => (tree: any, file: MarkdownVFile) => void;
1
+ import type { VFile } from 'vfile';
2
+ export declare function rehypeImages(): () => (tree: any, file: VFile) => void;
@@ -7,7 +7,7 @@ function rehypeImages() {
7
7
  if (node.tagName !== "img") return;
8
8
  if (node.properties?.src) {
9
9
  node.properties.src = decodeURI(node.properties.src);
10
- if (file.data.imagePaths?.has(node.properties.src)) {
10
+ if (file.data.astro?.imagePaths?.includes(node.properties.src)) {
11
11
  const { ...props } = node.properties;
12
12
  const index = imageOccurrenceMap.get(node.properties.src) || 0;
13
13
  imageOccurrenceMap.set(node.properties.src, index + 1);
@@ -3,9 +3,20 @@ import { createShikiHighlighter } from "./shiki.js";
3
3
  const rehypeShiki = (config) => {
4
4
  let highlighterAsync;
5
5
  return async (tree) => {
6
- highlighterAsync ??= createShikiHighlighter(config);
6
+ highlighterAsync ??= createShikiHighlighter({
7
+ langs: config?.langs,
8
+ theme: config?.theme,
9
+ themes: config?.themes
10
+ });
7
11
  const highlighter = await highlighterAsync;
8
- await highlightCodeBlocks(tree, highlighter.highlight);
12
+ await highlightCodeBlocks(tree, (code, language, options) => {
13
+ return highlighter.codeToHast(code, language, {
14
+ meta: options?.meta,
15
+ wrap: config?.wrap,
16
+ defaultColor: config?.defaultColor,
17
+ transformers: config?.transformers
18
+ });
19
+ });
9
20
  };
10
21
  };
11
22
  export {
@@ -1,2 +1,2 @@
1
- import type { MarkdownVFile } from './types.js';
2
- export declare function remarkCollectImages(): (tree: any, vfile: MarkdownVFile) => void;
1
+ import type { VFile } from 'vfile';
2
+ export declare function remarkCollectImages(): (tree: any, vfile: VFile) => void;
@@ -17,7 +17,8 @@ function remarkCollectImages() {
17
17
  }
18
18
  }
19
19
  });
20
- vfile.data.imagePaths = imagePaths;
20
+ vfile.data.astro ??= {};
21
+ vfile.data.astro.imagePaths = Array.from(imagePaths);
21
22
  };
22
23
  }
23
24
  function shouldOptimizeImage(src) {
package/dist/shiki.d.ts CHANGED
@@ -1,12 +1,42 @@
1
- import type { ShikiConfig } from './types.js';
1
+ import type { Root } from 'hast';
2
+ import { type LanguageRegistration, type ShikiTransformer, type ThemeRegistration, type ThemeRegistrationRaw } from 'shiki';
3
+ import type { ThemePresets } from './types.js';
2
4
  export interface ShikiHighlighter {
3
- highlight(code: string, lang?: string, options?: {
4
- inline?: boolean;
5
- attributes?: Record<string, string>;
6
- /**
7
- * Raw `meta` information to be used by Shiki transformers
8
- */
9
- meta?: string;
10
- }): Promise<string>;
5
+ codeToHast(code: string, lang?: string, options?: ShikiHighlighterHighlightOptions): Promise<Root>;
6
+ codeToHtml(code: string, lang?: string, options?: ShikiHighlighterHighlightOptions): Promise<string>;
11
7
  }
12
- export declare function createShikiHighlighter({ langs, theme, themes, defaultColor, wrap, transformers, }?: ShikiConfig): Promise<ShikiHighlighter>;
8
+ export interface CreateShikiHighlighterOptions {
9
+ langs?: LanguageRegistration[];
10
+ theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
11
+ themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
12
+ }
13
+ export interface ShikiHighlighterHighlightOptions {
14
+ /**
15
+ * Generate inline code element only, without the pre element wrapper.
16
+ */
17
+ inline?: boolean;
18
+ /**
19
+ * Enable word wrapping.
20
+ * - true: enabled.
21
+ * - false: disabled.
22
+ * - null: All overflow styling removed. Code will overflow the element by default.
23
+ */
24
+ wrap?: boolean | null;
25
+ /**
26
+ * Chooses a theme from the "themes" option that you've defined as the default styling theme.
27
+ */
28
+ defaultColor?: 'light' | 'dark' | string | false;
29
+ /**
30
+ * Shiki transformers to customize the generated HTML by manipulating the hast tree.
31
+ */
32
+ transformers?: ShikiTransformer[];
33
+ /**
34
+ * Additional attributes to be added to the root code block element.
35
+ */
36
+ attributes?: Record<string, string>;
37
+ /**
38
+ * Raw `meta` information to be used by Shiki transformers.
39
+ */
40
+ meta?: string;
41
+ }
42
+ export declare function createShikiHighlighter({ langs, theme, themes, }?: CreateShikiHighlighterOptions): Promise<ShikiHighlighter>;
package/dist/shiki.js CHANGED
@@ -1,126 +1,102 @@
1
1
  import {
2
2
  createCssVariablesTheme,
3
- getHighlighter,
3
+ createHighlighter,
4
4
  isSpecialLang
5
5
  } from "shiki";
6
- import { visit } from "unist-util-visit";
7
- const ASTRO_COLOR_REPLACEMENTS = {
8
- "--astro-code-foreground": "--astro-code-color-text",
9
- "--astro-code-background": "--astro-code-color-background"
10
- };
11
- const COLOR_REPLACEMENT_REGEX = new RegExp(
12
- `${Object.keys(ASTRO_COLOR_REPLACEMENTS).join("|")}`,
13
- "g"
14
- );
15
6
  let _cssVariablesTheme;
16
7
  const cssVariablesTheme = () => _cssVariablesTheme ?? (_cssVariablesTheme = createCssVariablesTheme({ variablePrefix: "--astro-code-" }));
17
8
  async function createShikiHighlighter({
18
9
  langs = [],
19
10
  theme = "github-dark",
20
- themes = {},
21
- defaultColor,
22
- wrap = false,
23
- transformers = []
11
+ themes = {}
24
12
  } = {}) {
25
13
  theme = theme === "css-variables" ? cssVariablesTheme() : theme;
26
- const highlighter = await getHighlighter({
14
+ const highlighter = await createHighlighter({
27
15
  langs: ["plaintext", ...langs],
28
16
  themes: Object.values(themes).length ? Object.values(themes) : [theme]
29
17
  });
30
- return {
31
- async highlight(code, lang = "plaintext", options) {
32
- const loadedLanguages = highlighter.getLoadedLanguages();
33
- if (!isSpecialLang(lang) && !loadedLanguages.includes(lang)) {
34
- try {
35
- await highlighter.loadLanguage(lang);
36
- } catch (_err) {
37
- console.warn(
38
- `[Shiki] The language "${lang}" doesn't exist, falling back to "plaintext".`
39
- );
40
- lang = "plaintext";
41
- }
18
+ async function highlight(code, lang = "plaintext", options, to) {
19
+ const loadedLanguages = highlighter.getLoadedLanguages();
20
+ if (!isSpecialLang(lang) && !loadedLanguages.includes(lang)) {
21
+ try {
22
+ await highlighter.loadLanguage(lang);
23
+ } catch (_err) {
24
+ console.warn(`[Shiki] The language "${lang}" doesn't exist, falling back to "plaintext".`);
25
+ lang = "plaintext";
42
26
  }
43
- const themeOptions = Object.values(themes).length ? { themes } : { theme };
44
- const inline = options?.inline ?? false;
45
- return highlighter.codeToHtml(code, {
46
- ...themeOptions,
47
- defaultColor,
48
- lang,
49
- // NOTE: while we can spread `options.attributes` here so that Shiki can auto-serialize this as rendered
50
- // attributes on the top-level tag, it's not clear whether it is fine to pass all attributes as meta, as
51
- // they're technically not meta, nor parsed from Shiki's `parseMetaString` API.
52
- meta: options?.meta ? { __raw: options?.meta } : void 0,
53
- transformers: [
54
- {
55
- pre(node) {
56
- if (inline) {
57
- node.tagName = "code";
58
- }
59
- const {
60
- class: attributesClass,
61
- style: attributesStyle,
62
- ...rest
63
- } = options?.attributes ?? {};
64
- Object.assign(node.properties, rest);
65
- const classValue = (normalizePropAsString(node.properties.class) ?? "") + (attributesClass ? ` ${attributesClass}` : "");
66
- const styleValue = (normalizePropAsString(node.properties.style) ?? "") + (attributesStyle ? `; ${attributesStyle}` : "");
67
- node.properties.class = classValue.replace(/shiki/g, "astro-code");
68
- node.properties.dataLanguage = lang;
69
- if (wrap === false) {
70
- node.properties.style = styleValue + "; overflow-x: auto;";
71
- } else if (wrap === true) {
72
- node.properties.style = styleValue + "; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;";
73
- }
74
- },
75
- line(node) {
76
- if (lang === "diff") {
77
- const innerSpanNode = node.children[0];
78
- const innerSpanTextNode = innerSpanNode?.type === "element" && innerSpanNode.children?.[0];
79
- if (innerSpanTextNode && innerSpanTextNode.type === "text") {
80
- const start = innerSpanTextNode.value[0];
81
- if (start === "+" || start === "-") {
82
- innerSpanTextNode.value = innerSpanTextNode.value.slice(1);
83
- innerSpanNode.children.unshift({
84
- type: "element",
85
- tagName: "span",
86
- properties: { style: "user-select: none;" },
87
- children: [{ type: "text", value: start }]
88
- });
89
- }
27
+ }
28
+ const themeOptions = Object.values(themes).length ? { themes } : { theme };
29
+ const inline = options?.inline ?? false;
30
+ return highlighter[to === "html" ? "codeToHtml" : "codeToHast"](code, {
31
+ ...themeOptions,
32
+ defaultColor: options.defaultColor,
33
+ lang,
34
+ // NOTE: while we can spread `options.attributes` here so that Shiki can auto-serialize this as rendered
35
+ // attributes on the top-level tag, it's not clear whether it is fine to pass all attributes as meta, as
36
+ // they're technically not meta, nor parsed from Shiki's `parseMetaString` API.
37
+ meta: options?.meta ? { __raw: options?.meta } : void 0,
38
+ transformers: [
39
+ {
40
+ pre(node) {
41
+ if (inline) {
42
+ node.tagName = "code";
43
+ }
44
+ const {
45
+ class: attributesClass,
46
+ style: attributesStyle,
47
+ ...rest
48
+ } = options?.attributes ?? {};
49
+ Object.assign(node.properties, rest);
50
+ const classValue = (normalizePropAsString(node.properties.class) ?? "") + (attributesClass ? ` ${attributesClass}` : "");
51
+ const styleValue = (normalizePropAsString(node.properties.style) ?? "") + (attributesStyle ? `; ${attributesStyle}` : "");
52
+ node.properties.class = classValue.replace(/shiki/g, "astro-code");
53
+ node.properties.dataLanguage = lang;
54
+ if (options.wrap === false || options.wrap === void 0) {
55
+ node.properties.style = styleValue + "; overflow-x: auto;";
56
+ } else if (options.wrap === true) {
57
+ node.properties.style = styleValue + "; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;";
58
+ }
59
+ },
60
+ line(node) {
61
+ if (lang === "diff") {
62
+ const innerSpanNode = node.children[0];
63
+ const innerSpanTextNode = innerSpanNode?.type === "element" && innerSpanNode.children?.[0];
64
+ if (innerSpanTextNode && innerSpanTextNode.type === "text") {
65
+ const start = innerSpanTextNode.value[0];
66
+ if (start === "+" || start === "-") {
67
+ innerSpanTextNode.value = innerSpanTextNode.value.slice(1);
68
+ innerSpanNode.children.unshift({
69
+ type: "element",
70
+ tagName: "span",
71
+ properties: { style: "user-select: none;" },
72
+ children: [{ type: "text", value: start }]
73
+ });
90
74
  }
91
75
  }
92
- },
93
- code(node) {
94
- if (inline) {
95
- return node.children[0];
96
- }
97
- },
98
- root(node) {
99
- if (Object.values(themes).length) {
100
- return;
101
- }
102
- const themeName = typeof theme === "string" ? theme : theme.name;
103
- if (themeName === "css-variables") {
104
- visit(node, "element", (child) => {
105
- if (child.properties?.style) {
106
- child.properties.style = replaceCssVariables(child.properties.style);
107
- }
108
- });
109
- }
110
76
  }
111
77
  },
112
- ...transformers
113
- ]
114
- });
78
+ code(node) {
79
+ if (inline) {
80
+ return node.children[0];
81
+ }
82
+ }
83
+ },
84
+ ...options.transformers ?? []
85
+ ]
86
+ });
87
+ }
88
+ return {
89
+ codeToHast(code, lang, options = {}) {
90
+ return highlight(code, lang, options, "hast");
91
+ },
92
+ codeToHtml(code, lang, options = {}) {
93
+ return highlight(code, lang, options, "html");
115
94
  }
116
95
  };
117
96
  }
118
97
  function normalizePropAsString(value) {
119
98
  return Array.isArray(value) ? value.join(" ") : value;
120
99
  }
121
- function replaceCssVariables(str) {
122
- return str.replace(COLOR_REPLACEMENT_REGEX, (match) => ASTRO_COLOR_REPLACEMENTS[match] || match);
123
- }
124
100
  export {
125
101
  createShikiHighlighter
126
102
  };
package/dist/types.d.ts CHANGED
@@ -1,26 +1,26 @@
1
1
  import type * as hast from 'hast';
2
2
  import type * as mdast from 'mdast';
3
3
  import type { Options as RemarkRehypeOptions } from 'remark-rehype';
4
- import type { BuiltinTheme, LanguageRegistration, ShikiTransformer, ThemeRegistration, ThemeRegistrationRaw } from 'shiki';
4
+ import type { BuiltinTheme } from 'shiki';
5
5
  import type * as unified from 'unified';
6
- import type { DataMap, VFile } from 'vfile';
6
+ import type { CreateShikiHighlighterOptions, ShikiHighlighterHighlightOptions } from './shiki.js';
7
7
  export type { Node } from 'unist';
8
- export type MarkdownAstroData = {
9
- frontmatter: Record<string, any>;
10
- };
8
+ declare module 'vfile' {
9
+ interface DataMap {
10
+ astro: {
11
+ headings?: MarkdownHeading[];
12
+ imagePaths?: string[];
13
+ frontmatter?: Record<string, any>;
14
+ };
15
+ }
16
+ }
11
17
  export type RemarkPlugin<PluginParameters extends any[] = any[]> = unified.Plugin<PluginParameters, mdast.Root>;
12
18
  export type RemarkPlugins = (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[];
13
19
  export type RehypePlugin<PluginParameters extends any[] = any[]> = unified.Plugin<PluginParameters, hast.Root>;
14
20
  export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
15
21
  export type RemarkRehype = RemarkRehypeOptions;
16
22
  export type ThemePresets = BuiltinTheme | 'css-variables';
17
- export interface ShikiConfig {
18
- langs?: LanguageRegistration[];
19
- theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
20
- themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
21
- defaultColor?: 'light' | 'dark' | string | false;
22
- wrap?: boolean | null;
23
- transformers?: ShikiTransformer[];
23
+ export interface ShikiConfig extends Pick<CreateShikiHighlighterOptions, 'langs' | 'theme' | 'themes'>, Pick<ShikiHighlighterHighlightOptions, 'defaultColor' | 'wrap' | 'transformers'> {
24
24
  }
25
25
  export interface AstroMarkdownOptions {
26
26
  syntaxHighlight?: 'shiki' | 'prism' | false;
@@ -42,7 +42,7 @@ export interface MarkdownProcessorRenderResult {
42
42
  code: string;
43
43
  metadata: {
44
44
  headings: MarkdownHeading[];
45
- imagePaths: Set<string>;
45
+ imagePaths: string[];
46
46
  frontmatter: Record<string, any>;
47
47
  };
48
48
  }
@@ -51,9 +51,3 @@ export interface MarkdownHeading {
51
51
  slug: string;
52
52
  text: string;
53
53
  }
54
- export interface MarkdownVFile extends VFile {
55
- data: Record<string, unknown> & Partial<DataMap> & {
56
- __astroHeadings?: MarkdownHeading[];
57
- imagePaths?: Set<string>;
58
- };
59
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/markdown-remark",
3
- "version": "5.2.0",
3
+ "version": "6.0.0-alpha.1",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",
@@ -13,8 +13,7 @@
13
13
  "homepage": "https://astro.build",
14
14
  "main": "./dist/index.js",
15
15
  "exports": {
16
- ".": "./dist/index.js",
17
- "./dist/internal.js": "./dist/internal.js"
16
+ ".": "./dist/index.js"
18
17
  },
19
18
  "imports": {
20
19
  "#import-plugin": {
@@ -27,7 +26,7 @@
27
26
  ],
28
27
  "dependencies": {
29
28
  "github-slugger": "^2.0.0",
30
- "hast-util-from-html": "^2.0.1",
29
+ "hast-util-from-html": "^2.0.2",
31
30
  "hast-util-to-text": "^4.0.2",
32
31
  "import-meta-resolve": "^4.1.0",
33
32
  "mdast-util-definitions": "^6.0.0",
@@ -37,19 +36,19 @@
37
36
  "remark-parse": "^11.0.0",
38
37
  "remark-rehype": "^11.1.0",
39
38
  "remark-smartypants": "^3.0.2",
40
- "shiki": "^1.10.3",
39
+ "shiki": "^1.16.1",
41
40
  "unified": "^11.0.5",
42
41
  "unist-util-remove-position": "^5.0.0",
43
42
  "unist-util-visit": "^5.0.0",
44
43
  "unist-util-visit-parents": "^6.0.1",
45
- "vfile": "^6.0.2",
44
+ "vfile": "^6.0.3",
46
45
  "@astrojs/prism": "3.1.0"
47
46
  },
48
47
  "devDependencies": {
49
48
  "@types/estree": "^1.0.5",
50
49
  "@types/hast": "^3.0.4",
51
50
  "@types/mdast": "^4.0.4",
52
- "@types/unist": "^3.0.2",
51
+ "@types/unist": "^3.0.3",
53
52
  "esbuild": "^0.21.5",
54
53
  "mdast-util-mdx-expression": "^2.0.0",
55
54
  "astro-scripts": "0.0.14"
@@ -61,7 +60,6 @@
61
60
  "prepublish": "pnpm build",
62
61
  "build": "astro-scripts build \"src/**/*.ts\" && tsc -p tsconfig.json",
63
62
  "build:ci": "astro-scripts build \"src/**/*.ts\"",
64
- "postbuild": "astro-scripts copy \"src/**/*.js\"",
65
63
  "dev": "astro-scripts dev \"src/**/*.ts\"",
66
64
  "test": "astro-scripts test \"test/**/*.test.js\""
67
65
  }
@@ -1,6 +0,0 @@
1
- import type { VFileData as Data, VFile } from 'vfile';
2
- import type { MarkdownAstroData } from './types.js';
3
- export declare class InvalidAstroDataError extends TypeError {
4
- }
5
- export declare function safelyGetAstroData(vfileData: Data): MarkdownAstroData | InvalidAstroDataError;
6
- export declare function setVfileFrontmatter(vfile: VFile, frontmatter: Record<string, any>): void;
@@ -1,31 +0,0 @@
1
- function isValidAstroData(obj) {
2
- if (typeof obj === "object" && obj !== null && obj.hasOwnProperty("frontmatter")) {
3
- const { frontmatter } = obj;
4
- try {
5
- JSON.stringify(frontmatter);
6
- } catch {
7
- return false;
8
- }
9
- return typeof frontmatter === "object" && frontmatter !== null;
10
- }
11
- return false;
12
- }
13
- class InvalidAstroDataError extends TypeError {
14
- }
15
- function safelyGetAstroData(vfileData) {
16
- const { astro } = vfileData;
17
- if (!astro || !isValidAstroData(astro)) {
18
- return new InvalidAstroDataError();
19
- }
20
- return astro;
21
- }
22
- function setVfileFrontmatter(vfile, frontmatter) {
23
- vfile.data ??= {};
24
- vfile.data.astro ??= {};
25
- vfile.data.astro.frontmatter = frontmatter;
26
- }
27
- export {
28
- InvalidAstroDataError,
29
- safelyGetAstroData,
30
- setVfileFrontmatter
31
- };
@@ -1 +0,0 @@
1
- export { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';
package/dist/internal.js DELETED
@@ -1,5 +0,0 @@
1
- import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js";
2
- export {
3
- InvalidAstroDataError,
4
- safelyGetAstroData
5
- };