@astrojs/markdown-remark 6.1.0 → 6.2.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 +2 -2
- package/dist/index.js +4 -3
- package/dist/rehype-images.d.ts +2 -1
- package/dist/rehype-images.js +22 -14
- package/dist/remark-collect-images.d.ts +3 -1
- package/dist/remark-collect-images.js +21 -20
- package/dist/types.d.ts +17 -2
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AstroMarkdownOptions, MarkdownProcessor } from './types.js';
|
|
1
|
+
import type { AstroMarkdownOptions, AstroMarkdownProcessorOptions, MarkdownProcessor } from './types.js';
|
|
2
2
|
export { rehypeHeadingIds } from './rehype-collect-headings.js';
|
|
3
3
|
export { remarkCollectImages } from './remark-collect-images.js';
|
|
4
4
|
export { rehypePrism } from './rehype-prism.js';
|
|
@@ -10,4 +10,4 @@ export declare const markdownConfigDefaults: Required<AstroMarkdownOptions>;
|
|
|
10
10
|
/**
|
|
11
11
|
* Create a markdown preprocessor to render multiple markdown files
|
|
12
12
|
*/
|
|
13
|
-
export declare function createMarkdownProcessor(opts?:
|
|
13
|
+
export declare function createMarkdownProcessor(opts?: AstroMarkdownProcessorOptions): Promise<MarkdownProcessor>;
|
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ async function createMarkdownProcessor(opts) {
|
|
|
67
67
|
parser.use(plugin, pluginOpts);
|
|
68
68
|
}
|
|
69
69
|
if (!isPerformanceBenchmark) {
|
|
70
|
-
parser.use(remarkCollectImages);
|
|
70
|
+
parser.use(remarkCollectImages, opts?.image);
|
|
71
71
|
}
|
|
72
72
|
parser.use(remarkRehype, {
|
|
73
73
|
allowDangerousHtml: true,
|
|
@@ -84,7 +84,7 @@ async function createMarkdownProcessor(opts) {
|
|
|
84
84
|
for (const [plugin, pluginOpts] of loadedRehypePlugins) {
|
|
85
85
|
parser.use(plugin, pluginOpts);
|
|
86
86
|
}
|
|
87
|
-
parser.use(rehypeImages
|
|
87
|
+
parser.use(rehypeImages);
|
|
88
88
|
if (!isPerformanceBenchmark) {
|
|
89
89
|
parser.use(rehypeHeadingIds);
|
|
90
90
|
}
|
|
@@ -109,7 +109,8 @@ async function createMarkdownProcessor(opts) {
|
|
|
109
109
|
code: String(result.value),
|
|
110
110
|
metadata: {
|
|
111
111
|
headings: result.data.astro?.headings ?? [],
|
|
112
|
-
|
|
112
|
+
localImagePaths: result.data.astro?.localImagePaths ?? [],
|
|
113
|
+
remoteImagePaths: result.data.astro?.remoteImagePaths ?? [],
|
|
113
114
|
frontmatter: result.data.astro?.frontmatter ?? {}
|
|
114
115
|
}
|
|
115
116
|
};
|
package/dist/rehype-images.d.ts
CHANGED
package/dist/rehype-images.js
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import { visit } from "unist-util-visit";
|
|
2
2
|
function rehypeImages() {
|
|
3
|
-
return
|
|
3
|
+
return function(tree, file) {
|
|
4
|
+
if (!file.data.astro?.localImagePaths?.length && !file.data.astro?.remoteImagePaths?.length) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
4
7
|
const imageOccurrenceMap = /* @__PURE__ */ new Map();
|
|
5
|
-
visit(tree, (node) => {
|
|
6
|
-
if (node.type !== "element") return;
|
|
8
|
+
visit(tree, "element", (node) => {
|
|
7
9
|
if (node.tagName !== "img") return;
|
|
8
|
-
if (node.properties?.src)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
if (typeof node.properties?.src !== "string") return;
|
|
11
|
+
const src = decodeURI(node.properties.src);
|
|
12
|
+
let newProperties;
|
|
13
|
+
if (file.data.astro?.localImagePaths?.includes(src)) {
|
|
14
|
+
newProperties = { ...node.properties, src };
|
|
15
|
+
} else if (file.data.astro?.remoteImagePaths?.includes(src)) {
|
|
16
|
+
newProperties = {
|
|
17
|
+
// By default, markdown images won't have width and height set. However, just in case another user plugin does set these, we should respect them.
|
|
18
|
+
inferSize: "width" in node.properties && "height" in node.properties ? void 0 : true,
|
|
19
|
+
...node.properties,
|
|
20
|
+
src
|
|
21
|
+
};
|
|
22
|
+
} else {
|
|
23
|
+
return;
|
|
19
24
|
}
|
|
25
|
+
const index = imageOccurrenceMap.get(node.properties.src) || 0;
|
|
26
|
+
imageOccurrenceMap.set(node.properties.src, index + 1);
|
|
27
|
+
node.properties = { __ASTRO_IMAGE_: JSON.stringify({ ...newProperties, index }) };
|
|
20
28
|
});
|
|
21
29
|
};
|
|
22
30
|
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
import type { Root } from 'mdast';
|
|
1
2
|
import type { VFile } from 'vfile';
|
|
2
|
-
|
|
3
|
+
import type { AstroMarkdownProcessorOptions } from './types.js';
|
|
4
|
+
export declare function remarkCollectImages(opts: AstroMarkdownProcessorOptions['image']): (tree: Root, vfile: VFile) => void;
|
|
@@ -1,37 +1,38 @@
|
|
|
1
|
+
import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
|
|
1
2
|
import { definitions } from "mdast-util-definitions";
|
|
2
3
|
import { visit } from "unist-util-visit";
|
|
3
|
-
function remarkCollectImages() {
|
|
4
|
+
function remarkCollectImages(opts) {
|
|
5
|
+
const domains = opts?.domains ?? [];
|
|
6
|
+
const remotePatterns = opts?.remotePatterns ?? [];
|
|
4
7
|
return function(tree, vfile) {
|
|
5
8
|
if (typeof vfile?.path !== "string") return;
|
|
6
9
|
const definition = definitions(tree);
|
|
7
|
-
const
|
|
8
|
-
|
|
10
|
+
const localImagePaths = /* @__PURE__ */ new Set();
|
|
11
|
+
const remoteImagePaths = /* @__PURE__ */ new Set();
|
|
12
|
+
visit(tree, (node) => {
|
|
13
|
+
let url;
|
|
9
14
|
if (node.type === "image") {
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
if (node.type === "imageReference") {
|
|
15
|
+
url = decodeURI(node.url);
|
|
16
|
+
} else if (node.type === "imageReference") {
|
|
13
17
|
const imageDefinition = definition(node.identifier);
|
|
14
18
|
if (imageDefinition) {
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
url = decodeURI(imageDefinition.url);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (!url) return;
|
|
23
|
+
if (URL.canParse(url)) {
|
|
24
|
+
if (isRemoteAllowed(url, { domains, remotePatterns })) {
|
|
25
|
+
remoteImagePaths.add(url);
|
|
17
26
|
}
|
|
27
|
+
} else if (!url.startsWith("/")) {
|
|
28
|
+
localImagePaths.add(url);
|
|
18
29
|
}
|
|
19
30
|
});
|
|
20
31
|
vfile.data.astro ??= {};
|
|
21
|
-
vfile.data.astro.
|
|
32
|
+
vfile.data.astro.localImagePaths = Array.from(localImagePaths);
|
|
33
|
+
vfile.data.astro.remoteImagePaths = Array.from(remoteImagePaths);
|
|
22
34
|
};
|
|
23
35
|
}
|
|
24
|
-
function shouldOptimizeImage(src) {
|
|
25
|
-
return !isValidUrl(src) && !src.startsWith("/");
|
|
26
|
-
}
|
|
27
|
-
function isValidUrl(str) {
|
|
28
|
-
try {
|
|
29
|
-
new URL(str);
|
|
30
|
-
return true;
|
|
31
|
-
} catch {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
36
|
export {
|
|
36
37
|
remarkCollectImages
|
|
37
38
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RemotePattern } from '@astrojs/internal-helpers/remote';
|
|
1
2
|
import type * as hast from 'hast';
|
|
2
3
|
import type * as mdast from 'mdast';
|
|
3
4
|
import type { Options as RemarkRehypeOptions } from 'remark-rehype';
|
|
@@ -9,7 +10,8 @@ declare module 'vfile' {
|
|
|
9
10
|
interface DataMap {
|
|
10
11
|
astro: {
|
|
11
12
|
headings?: MarkdownHeading[];
|
|
12
|
-
|
|
13
|
+
localImagePaths?: string[];
|
|
14
|
+
remoteImagePaths?: string[];
|
|
13
15
|
frontmatter?: Record<string, any>;
|
|
14
16
|
};
|
|
15
17
|
}
|
|
@@ -22,6 +24,9 @@ export type RemarkRehype = RemarkRehypeOptions;
|
|
|
22
24
|
export type ThemePresets = BuiltinTheme | 'css-variables';
|
|
23
25
|
export interface ShikiConfig extends Pick<CreateShikiHighlighterOptions, 'langs' | 'theme' | 'themes' | 'langAlias'>, Pick<ShikiHighlighterHighlightOptions, 'defaultColor' | 'wrap' | 'transformers'> {
|
|
24
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Configuration options that end up in the markdown section of AstroConfig
|
|
29
|
+
*/
|
|
25
30
|
export interface AstroMarkdownOptions {
|
|
26
31
|
syntaxHighlight?: 'shiki' | 'prism' | false;
|
|
27
32
|
shikiConfig?: ShikiConfig;
|
|
@@ -31,6 +36,15 @@ export interface AstroMarkdownOptions {
|
|
|
31
36
|
gfm?: boolean;
|
|
32
37
|
smartypants?: boolean;
|
|
33
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Extra configuration options from other parts of AstroConfig that get injected into this plugin
|
|
41
|
+
*/
|
|
42
|
+
export interface AstroMarkdownProcessorOptions extends AstroMarkdownOptions {
|
|
43
|
+
image?: {
|
|
44
|
+
domains?: string[];
|
|
45
|
+
remotePatterns?: RemotePattern[];
|
|
46
|
+
};
|
|
47
|
+
}
|
|
34
48
|
export interface MarkdownProcessor {
|
|
35
49
|
render: (content: string, opts?: MarkdownProcessorRenderOptions) => Promise<MarkdownProcessorRenderResult>;
|
|
36
50
|
}
|
|
@@ -42,7 +56,8 @@ export interface MarkdownProcessorRenderResult {
|
|
|
42
56
|
code: string;
|
|
43
57
|
metadata: {
|
|
44
58
|
headings: MarkdownHeading[];
|
|
45
|
-
|
|
59
|
+
localImagePaths: string[];
|
|
60
|
+
remoteImagePaths: string[];
|
|
46
61
|
frontmatter: Record<string, any>;
|
|
47
62
|
};
|
|
48
63
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/markdown-remark",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "withastro",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,13 +37,14 @@
|
|
|
37
37
|
"remark-parse": "^11.0.0",
|
|
38
38
|
"remark-rehype": "^11.1.1",
|
|
39
39
|
"remark-smartypants": "^3.0.2",
|
|
40
|
-
"shiki": "^1.29.
|
|
40
|
+
"shiki": "^1.29.2",
|
|
41
41
|
"smol-toml": "^1.3.1",
|
|
42
42
|
"unified": "^11.0.5",
|
|
43
43
|
"unist-util-remove-position": "^5.0.0",
|
|
44
44
|
"unist-util-visit": "^5.0.0",
|
|
45
45
|
"unist-util-visit-parents": "^6.0.1",
|
|
46
46
|
"vfile": "^6.0.3",
|
|
47
|
+
"@astrojs/internal-helpers": "0.6.0",
|
|
47
48
|
"@astrojs/prism": "3.2.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|