@astrojs/markdown-remark 4.2.0 → 4.3.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/frontmatter-injection.d.ts +1 -1
- package/dist/highlight.d.ts +13 -0
- package/dist/highlight.js +44 -0
- package/dist/import-plugin-default.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +18 -12
- package/dist/rehype-images.js +1 -0
- package/dist/rehype-prism.d.ts +3 -0
- package/dist/rehype-prism.js +11 -0
- package/dist/rehype-shiki.d.ts +4 -0
- package/dist/rehype-shiki.js +13 -0
- package/dist/remark-prism.d.ts +3 -0
- package/dist/remark-shiki.d.ts +3 -0
- package/dist/shiki.d.ts +2 -1
- package/dist/shiki.js +12 -7
- package/dist/types.d.ts +3 -3
- package/package.json +7 -5
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Root } from 'hast';
|
|
2
|
+
type Highlighter = (code: string, language: string) => string;
|
|
3
|
+
/**
|
|
4
|
+
* A hast utility to syntax highlight code blocks with a given syntax highlighter.
|
|
5
|
+
*
|
|
6
|
+
* @param tree
|
|
7
|
+
* The hast tree in which to syntax highlight code blocks.
|
|
8
|
+
* @param highlighter
|
|
9
|
+
* A fnction which receives the code and language, and returns the HTML of a syntax
|
|
10
|
+
* highlighted `<pre>` element.
|
|
11
|
+
*/
|
|
12
|
+
export declare function highlightCodeBlocks(tree: Root, highlighter: Highlighter): void;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { fromHtml } from "hast-util-from-html";
|
|
2
|
+
import { toText } from "hast-util-to-text";
|
|
3
|
+
import { removePosition } from "unist-util-remove-position";
|
|
4
|
+
import { visitParents } from "unist-util-visit-parents";
|
|
5
|
+
const languagePattern = /\blanguage-(\S+)\b/;
|
|
6
|
+
function highlightCodeBlocks(tree, highlighter) {
|
|
7
|
+
visitParents(tree, { type: "element", tagName: "code" }, (node, ancestors) => {
|
|
8
|
+
const parent = ancestors.at(-1);
|
|
9
|
+
if (parent?.type !== "element" || parent.tagName !== "pre") {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (parent.children.length !== 1) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
let languageMatch;
|
|
16
|
+
let { className } = node.properties;
|
|
17
|
+
if (typeof className === "string") {
|
|
18
|
+
languageMatch = className.match(languagePattern);
|
|
19
|
+
} else if (Array.isArray(className)) {
|
|
20
|
+
for (const cls of className) {
|
|
21
|
+
if (typeof cls !== "string") {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
languageMatch = cls.match(languagePattern);
|
|
25
|
+
if (languageMatch) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (languageMatch?.[1] === "math") {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const code = toText(node, { whitespace: "pre" });
|
|
34
|
+
const html = highlighter(code, languageMatch?.[1] || "plaintext");
|
|
35
|
+
const replacement = fromHtml(html, { fragment: true }).children[0];
|
|
36
|
+
removePosition(replacement);
|
|
37
|
+
const grandParent = ancestors.at(-2);
|
|
38
|
+
const index = grandParent.children.indexOf(parent);
|
|
39
|
+
grandParent.children[index] = replacement;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
highlightCodeBlocks
|
|
44
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { resolve as importMetaResolve } from "import-meta-resolve";
|
|
2
1
|
import path from "node:path";
|
|
3
2
|
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { resolve as importMetaResolve } from "import-meta-resolve";
|
|
4
4
|
let cwdUrlStr;
|
|
5
5
|
async function importPlugin(p) {
|
|
6
6
|
try {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import type { AstroMarkdownOptions, MarkdownProcessor } from './types.js';
|
|
|
2
2
|
export { InvalidAstroDataError, setVfileFrontmatter } from './frontmatter-injection.js';
|
|
3
3
|
export { rehypeHeadingIds } from './rehype-collect-headings.js';
|
|
4
4
|
export { remarkCollectImages } from './remark-collect-images.js';
|
|
5
|
+
export { rehypePrism } from './rehype-prism.js';
|
|
6
|
+
export { rehypeShiki } from './rehype-shiki.js';
|
|
5
7
|
export { remarkPrism } from './remark-prism.js';
|
|
6
8
|
export { remarkShiki } from './remark-shiki.js';
|
|
7
9
|
export { createShikiHighlighter, replaceCssVariables, type ShikiHighlighter } from './shiki.js';
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
} from "./frontmatter-injection.js";
|
|
6
6
|
import { loadPlugins } from "./load-plugins.js";
|
|
7
7
|
import { rehypeHeadingIds } from "./rehype-collect-headings.js";
|
|
8
|
+
import { rehypePrism } from "./rehype-prism.js";
|
|
9
|
+
import { rehypeShiki } from "./rehype-shiki.js";
|
|
8
10
|
import { remarkCollectImages } from "./remark-collect-images.js";
|
|
9
|
-
import { remarkPrism } from "./remark-prism.js";
|
|
10
|
-
import { remarkShiki } from "./remark-shiki.js";
|
|
11
11
|
import rehypeRaw from "rehype-raw";
|
|
12
12
|
import rehypeStringify from "rehype-stringify";
|
|
13
13
|
import remarkGfm from "remark-gfm";
|
|
@@ -20,8 +20,10 @@ import { rehypeImages } from "./rehype-images.js";
|
|
|
20
20
|
import { InvalidAstroDataError as InvalidAstroDataError2, setVfileFrontmatter as setVfileFrontmatter2 } from "./frontmatter-injection.js";
|
|
21
21
|
import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings.js";
|
|
22
22
|
import { remarkCollectImages as remarkCollectImages2 } from "./remark-collect-images.js";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
23
|
+
import { rehypePrism as rehypePrism2 } from "./rehype-prism.js";
|
|
24
|
+
import { rehypeShiki as rehypeShiki2 } from "./rehype-shiki.js";
|
|
25
|
+
import { remarkPrism } from "./remark-prism.js";
|
|
26
|
+
import { remarkShiki } from "./remark-shiki.js";
|
|
25
27
|
import { createShikiHighlighter, replaceCssVariables } from "./shiki.js";
|
|
26
28
|
export * from "./types.js";
|
|
27
29
|
const markdownConfigDefaults = {
|
|
@@ -29,7 +31,7 @@ const markdownConfigDefaults = {
|
|
|
29
31
|
shikiConfig: {
|
|
30
32
|
langs: [],
|
|
31
33
|
theme: "github-dark",
|
|
32
|
-
|
|
34
|
+
themes: {},
|
|
33
35
|
wrap: false,
|
|
34
36
|
transformers: []
|
|
35
37
|
},
|
|
@@ -65,11 +67,6 @@ async function createMarkdownProcessor(opts) {
|
|
|
65
67
|
parser.use(plugin, pluginOpts);
|
|
66
68
|
}
|
|
67
69
|
if (!isPerformanceBenchmark) {
|
|
68
|
-
if (syntaxHighlight === "shiki") {
|
|
69
|
-
parser.use(remarkShiki, shikiConfig);
|
|
70
|
-
} else if (syntaxHighlight === "prism") {
|
|
71
|
-
parser.use(remarkPrism);
|
|
72
|
-
}
|
|
73
70
|
parser.use(remarkCollectImages);
|
|
74
71
|
}
|
|
75
72
|
parser.use(remarkRehype, {
|
|
@@ -77,6 +74,13 @@ async function createMarkdownProcessor(opts) {
|
|
|
77
74
|
passThrough: [],
|
|
78
75
|
...remarkRehypeOptions
|
|
79
76
|
});
|
|
77
|
+
if (!isPerformanceBenchmark) {
|
|
78
|
+
if (syntaxHighlight === "shiki") {
|
|
79
|
+
parser.use(rehypeShiki, shikiConfig);
|
|
80
|
+
} else if (syntaxHighlight === "prism") {
|
|
81
|
+
parser.use(rehypePrism);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
80
84
|
for (const [plugin, pluginOpts] of loadedRehypePlugins) {
|
|
81
85
|
parser.use(plugin, pluginOpts);
|
|
82
86
|
}
|
|
@@ -132,9 +136,11 @@ export {
|
|
|
132
136
|
createShikiHighlighter,
|
|
133
137
|
markdownConfigDefaults,
|
|
134
138
|
rehypeHeadingIds2 as rehypeHeadingIds,
|
|
139
|
+
rehypePrism2 as rehypePrism,
|
|
140
|
+
rehypeShiki2 as rehypeShiki,
|
|
135
141
|
remarkCollectImages2 as remarkCollectImages,
|
|
136
|
-
|
|
137
|
-
|
|
142
|
+
remarkPrism,
|
|
143
|
+
remarkShiki,
|
|
138
144
|
replaceCssVariables,
|
|
139
145
|
setVfileFrontmatter2 as setVfileFrontmatter
|
|
140
146
|
};
|
package/dist/rehype-images.js
CHANGED
|
@@ -8,6 +8,7 @@ function rehypeImages() {
|
|
|
8
8
|
if (node.tagName !== "img")
|
|
9
9
|
return;
|
|
10
10
|
if (node.properties?.src) {
|
|
11
|
+
node.properties.src = decodeURI(node.properties.src);
|
|
11
12
|
if (file.data.imagePaths?.has(node.properties.src)) {
|
|
12
13
|
const { ...props } = node.properties;
|
|
13
14
|
const index = imageOccurrenceMap.get(node.properties.src) || 0;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runHighlighterWithAstro } from "@astrojs/prism/dist/highlighter";
|
|
2
|
+
import { highlightCodeBlocks } from "./highlight.js";
|
|
3
|
+
const rehypePrism = () => (tree) => {
|
|
4
|
+
highlightCodeBlocks(tree, (code, language) => {
|
|
5
|
+
let { html, classLanguage } = runHighlighterWithAstro(language, code);
|
|
6
|
+
return `<pre class="${classLanguage}"><code is:raw class="${classLanguage}">${html}</code></pre>`;
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
rehypePrism
|
|
11
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { highlightCodeBlocks } from "./highlight.js";
|
|
2
|
+
import { createShikiHighlighter } from "./shiki.js";
|
|
3
|
+
const rehypeShiki = (config) => {
|
|
4
|
+
let highlighterAsync;
|
|
5
|
+
return async (tree) => {
|
|
6
|
+
highlighterAsync ??= createShikiHighlighter(config);
|
|
7
|
+
const highlighter = await highlighterAsync;
|
|
8
|
+
highlightCodeBlocks(tree, highlighter.highlight);
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
rehypeShiki
|
|
13
|
+
};
|
package/dist/remark-prism.d.ts
CHANGED
package/dist/remark-shiki.d.ts
CHANGED
package/dist/shiki.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ShikiConfig } from './types.js';
|
|
|
2
2
|
export interface ShikiHighlighter {
|
|
3
3
|
highlight(code: string, lang?: string, options?: {
|
|
4
4
|
inline?: boolean;
|
|
5
|
+
attributes?: Record<string, string>;
|
|
5
6
|
}): string;
|
|
6
7
|
}
|
|
7
|
-
export declare function createShikiHighlighter({ langs, theme,
|
|
8
|
+
export declare function createShikiHighlighter({ langs, theme, themes, wrap, transformers, }?: ShikiConfig): Promise<ShikiHighlighter>;
|
package/dist/shiki.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { bundledLanguages, createCssVariablesTheme, getHighlighter } from "
|
|
1
|
+
import { bundledLanguages, createCssVariablesTheme, getHighlighter } from "shiki";
|
|
2
2
|
import { visit } from "unist-util-visit";
|
|
3
3
|
const ASTRO_COLOR_REPLACEMENTS = {
|
|
4
4
|
"--astro-code-foreground": "--astro-code-color-text",
|
|
5
5
|
"--astro-code-background": "--astro-code-color-background"
|
|
6
6
|
};
|
|
7
7
|
const COLOR_REPLACEMENT_REGEX = new RegExp(
|
|
8
|
-
|
|
8
|
+
`${Object.keys(ASTRO_COLOR_REPLACEMENTS).join("|")}`,
|
|
9
9
|
"g"
|
|
10
10
|
);
|
|
11
11
|
let _cssVariablesTheme;
|
|
@@ -13,11 +13,10 @@ const cssVariablesTheme = () => _cssVariablesTheme ?? (_cssVariablesTheme = crea
|
|
|
13
13
|
async function createShikiHighlighter({
|
|
14
14
|
langs = [],
|
|
15
15
|
theme = "github-dark",
|
|
16
|
-
|
|
16
|
+
themes = {},
|
|
17
17
|
wrap = false,
|
|
18
18
|
transformers = []
|
|
19
19
|
} = {}) {
|
|
20
|
-
const themes = experimentalThemes;
|
|
21
20
|
theme = theme === "css-variables" ? cssVariablesTheme() : theme;
|
|
22
21
|
const highlighter = await getHighlighter({
|
|
23
22
|
langs: langs.length ? langs : Object.keys(bundledLanguages),
|
|
@@ -41,8 +40,14 @@ async function createShikiHighlighter({
|
|
|
41
40
|
if (inline) {
|
|
42
41
|
node.tagName = "code";
|
|
43
42
|
}
|
|
44
|
-
const
|
|
45
|
-
|
|
43
|
+
const {
|
|
44
|
+
class: attributesClass,
|
|
45
|
+
style: attributesStyle,
|
|
46
|
+
...rest
|
|
47
|
+
} = options?.attributes ?? {};
|
|
48
|
+
Object.assign(node.properties, rest);
|
|
49
|
+
const classValue = (normalizePropAsString(node.properties.class) ?? "") + (attributesClass ? ` ${attributesClass}` : "");
|
|
50
|
+
const styleValue = (normalizePropAsString(node.properties.style) ?? "") + (attributesStyle ? `; ${attributesStyle}` : "");
|
|
46
51
|
node.properties.class = classValue.replace(/shiki/g, "astro-code");
|
|
47
52
|
if (wrap === false) {
|
|
48
53
|
node.properties.style = styleValue + "; overflow-x: auto;";
|
|
@@ -74,7 +79,7 @@ async function createShikiHighlighter({
|
|
|
74
79
|
}
|
|
75
80
|
},
|
|
76
81
|
root(node) {
|
|
77
|
-
if (Object.values(
|
|
82
|
+
if (Object.values(themes).length) {
|
|
78
83
|
return;
|
|
79
84
|
}
|
|
80
85
|
const themeName = typeof theme === "string" ? theme : theme.name;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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,
|
|
4
|
+
import type { BuiltinTheme, LanguageRegistration, ShikiTransformer, ThemeRegistration, ThemeRegistrationRaw } from 'shiki';
|
|
5
5
|
import type * as unified from 'unified';
|
|
6
6
|
import type { VFile } from 'vfile';
|
|
7
7
|
export type { Node } from 'unist';
|
|
@@ -17,9 +17,9 @@ export type ThemePresets = BuiltinTheme | 'css-variables';
|
|
|
17
17
|
export interface ShikiConfig {
|
|
18
18
|
langs?: LanguageRegistration[];
|
|
19
19
|
theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
|
|
20
|
-
|
|
20
|
+
themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
|
|
21
21
|
wrap?: boolean | null;
|
|
22
|
-
transformers?:
|
|
22
|
+
transformers?: ShikiTransformer[];
|
|
23
23
|
}
|
|
24
24
|
export interface AstroMarkdownOptions {
|
|
25
25
|
syntaxHighlight?: 'shiki' | 'prism' | false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/markdown-remark",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "withastro",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@astrojs/prism": "^3.0.0",
|
|
30
30
|
"github-slugger": "^2.0.0",
|
|
31
|
+
"hast-util-from-html": "^2.0.0",
|
|
32
|
+
"hast-util-to-text": "^4.0.0",
|
|
31
33
|
"import-meta-resolve": "^4.0.0",
|
|
32
34
|
"mdast-util-definitions": "^6.0.0",
|
|
33
35
|
"rehype-raw": "^7.0.0",
|
|
@@ -36,9 +38,11 @@
|
|
|
36
38
|
"remark-parse": "^11.0.0",
|
|
37
39
|
"remark-rehype": "^11.0.0",
|
|
38
40
|
"remark-smartypants": "^2.0.0",
|
|
39
|
-
"
|
|
41
|
+
"shiki": "^1.1.2",
|
|
40
42
|
"unified": "^11.0.4",
|
|
43
|
+
"unist-util-remove-position": "^5.0.0",
|
|
41
44
|
"unist-util-visit": "^5.0.0",
|
|
45
|
+
"unist-util-visit-parents": "^6.0.0",
|
|
42
46
|
"vfile": "^6.0.1"
|
|
43
47
|
},
|
|
44
48
|
"devDependencies": {
|
|
@@ -48,10 +52,8 @@
|
|
|
48
52
|
"@types/mdast": "^4.0.3",
|
|
49
53
|
"@types/mocha": "^10.0.4",
|
|
50
54
|
"@types/unist": "^3.0.2",
|
|
51
|
-
"chai": "^4.3.7",
|
|
52
55
|
"esbuild": "^0.19.6",
|
|
53
56
|
"mdast-util-mdx-expression": "^2.0.0",
|
|
54
|
-
"mocha": "^10.2.0",
|
|
55
57
|
"astro-scripts": "0.0.14"
|
|
56
58
|
},
|
|
57
59
|
"publishConfig": {
|
|
@@ -63,6 +65,6 @@
|
|
|
63
65
|
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
|
64
66
|
"postbuild": "astro-scripts copy \"src/**/*.js\"",
|
|
65
67
|
"dev": "astro-scripts dev \"src/**/*.ts\"",
|
|
66
|
-
"test": "
|
|
68
|
+
"test": "astro-scripts test \"test/**/*.test.js\""
|
|
67
69
|
}
|
|
68
70
|
}
|