vuepress-plugin-md-power 1.0.0-rc.134 → 1.0.0-rc.136
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/lib/client/components/CodeRepl.vue +2 -2
- package/lib/client/styles/demo.css +2 -2
- package/lib/node/index.d.ts +7 -1
- package/lib/node/index.js +385 -368
- package/lib/shared/index.d.ts +4 -0
- package/package.json +20 -20
|
@@ -134,7 +134,7 @@ function runCode() {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
.code-repl-title h4 {
|
|
137
|
-
flex: 1;
|
|
137
|
+
flex: 1 2;
|
|
138
138
|
padding: 0 12px;
|
|
139
139
|
margin: 0;
|
|
140
140
|
font-size: 14px;
|
|
@@ -175,7 +175,7 @@ function runCode() {
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
.output-head .title {
|
|
178
|
-
flex: 1;
|
|
178
|
+
flex: 1 2;
|
|
179
179
|
margin-left: 10px;
|
|
180
180
|
font-size: 14px;
|
|
181
181
|
font-weight: 500;
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
.vp-demo-wrapper .demo-info .title::after {
|
|
39
39
|
display: inline-block;
|
|
40
|
-
flex: 1;
|
|
40
|
+
flex: 1 2;
|
|
41
41
|
height: 0;
|
|
42
42
|
margin-left: 8px;
|
|
43
43
|
content: "";
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
|
|
66
66
|
.vp-demo-wrapper .demo-ctrl .extra {
|
|
67
67
|
display: flex;
|
|
68
|
-
flex: 1;
|
|
68
|
+
flex: 1 2;
|
|
69
69
|
gap: 16px;
|
|
70
70
|
align-items: center;
|
|
71
71
|
justify-content: flex-start;
|
package/lib/node/index.d.ts
CHANGED
|
@@ -181,6 +181,10 @@ interface MarkdownPowerPluginOptions {
|
|
|
181
181
|
* @default false
|
|
182
182
|
*/
|
|
183
183
|
annotation?: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* 是否启用 abbr 语法
|
|
186
|
+
* @default false
|
|
187
|
+
*/
|
|
184
188
|
abbr?: boolean;
|
|
185
189
|
/**
|
|
186
190
|
* 配置代码块分组
|
|
@@ -352,6 +356,8 @@ interface ArtPlayerTokenMeta extends SizeOptions {
|
|
|
352
356
|
type?: string;
|
|
353
357
|
}
|
|
354
358
|
|
|
359
|
+
declare function createCodeTabIconGetter(options?: CodeTabsOptions): (filename: string) => string | void;
|
|
360
|
+
|
|
355
361
|
interface ImgSize {
|
|
356
362
|
width: number;
|
|
357
363
|
height: number;
|
|
@@ -360,4 +366,4 @@ declare function resolveImageSize(app: App, url: string, remote?: boolean): Prom
|
|
|
360
366
|
|
|
361
367
|
declare function markdownPowerPlugin(options?: MarkdownPowerPluginOptions): Plugin;
|
|
362
368
|
|
|
363
|
-
export { type ArtPlayerTokenMeta, type BilibiliTokenMeta, type CanIUseMode, type CanIUseOptions, type CanIUseTokenMeta, type CodeSandboxTokenMeta, type CodeTabsOptions, type CodepenTokenMeta, type DemoContainerRender, type DemoFile, type DemoMeta, type FileTreeIconMode, type FileTreeOptions, type IconsOptions, type JSFiddleTokenMeta, type MarkdownDemoEnv, type MarkdownPowerPluginOptions, type NpmToOptions, type NpmToPackageManager, type PDFEmbedType, type PDFOptions, type PDFTokenMeta, type PlotOptions, type ReplEditorData, type ReplOptions, type ReplitTokenMeta, type SizeOptions, type ThemeOptions, type VideoOptions, type YoutubeTokenMeta, markdownPowerPlugin, resolveImageSize };
|
|
369
|
+
export { type ArtPlayerTokenMeta, type BilibiliTokenMeta, type CanIUseMode, type CanIUseOptions, type CanIUseTokenMeta, type CodeSandboxTokenMeta, type CodeTabsOptions, type CodepenTokenMeta, type DemoContainerRender, type DemoFile, type DemoMeta, type FileTreeIconMode, type FileTreeOptions, type IconsOptions, type JSFiddleTokenMeta, type MarkdownDemoEnv, type MarkdownPowerPluginOptions, type NpmToOptions, type NpmToPackageManager, type PDFEmbedType, type PDFOptions, type PDFTokenMeta, type PlotOptions, type ReplEditorData, type ReplOptions, type ReplitTokenMeta, type SizeOptions, type ThemeOptions, type VideoOptions, type YoutubeTokenMeta, createCodeTabIconGetter, markdownPowerPlugin, resolveImageSize };
|
package/lib/node/index.js
CHANGED
|
@@ -1,275 +1,3 @@
|
|
|
1
|
-
// src/node/enhance/imageSize.ts
|
|
2
|
-
import { Buffer } from "node:buffer";
|
|
3
|
-
import http from "node:https";
|
|
4
|
-
import { URL } from "node:url";
|
|
5
|
-
import { isLinkExternal, isLinkHttp } from "@vuepress/helper";
|
|
6
|
-
import imageSize from "image-size";
|
|
7
|
-
import { fs, logger, path } from "vuepress/utils";
|
|
8
|
-
|
|
9
|
-
// src/node/utils/resolveAttrs.ts
|
|
10
|
-
var RE_ATTR_VALUE = /(?:^|\s+)(?<attr>[\w-]+)(?:=\s*(?<quote>['"])(?<value>.+?)\k<quote>)?(?:\s+|$)/;
|
|
11
|
-
function resolveAttrs(info) {
|
|
12
|
-
info = info.trim();
|
|
13
|
-
if (!info)
|
|
14
|
-
return { rawAttrs: "", attrs: {} };
|
|
15
|
-
const attrs2 = {};
|
|
16
|
-
const rawAttrs = info;
|
|
17
|
-
let matched;
|
|
18
|
-
while (matched = info.match(RE_ATTR_VALUE)) {
|
|
19
|
-
const { attr, value } = matched.groups;
|
|
20
|
-
attrs2[attr] = value ?? true;
|
|
21
|
-
info = info.slice(matched[0].length);
|
|
22
|
-
}
|
|
23
|
-
Object.keys(attrs2).forEach((key) => {
|
|
24
|
-
let value = attrs2[key];
|
|
25
|
-
value = typeof value === "string" ? value.trim() : value;
|
|
26
|
-
if (value === "true")
|
|
27
|
-
value = true;
|
|
28
|
-
else if (value === "false")
|
|
29
|
-
value = false;
|
|
30
|
-
attrs2[key] = value;
|
|
31
|
-
if (key.includes("-")) {
|
|
32
|
-
const _key = key.replace(/-(\w)/g, (_, c) => c.toUpperCase());
|
|
33
|
-
attrs2[_key] = value;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
return { attrs: attrs2, rawAttrs };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// src/node/enhance/imageSize.ts
|
|
40
|
-
var REG_IMG = /!\[.*?\]\(.*?\)/g;
|
|
41
|
-
var REG_IMG_TAG = /<img(.*?)>/g;
|
|
42
|
-
var REG_IMG_TAG_SRC = /src(?:set)?=(['"])(.+?)\1/g;
|
|
43
|
-
var BADGE_LIST = [
|
|
44
|
-
"https://img.shields.io",
|
|
45
|
-
"https://badge.fury.io",
|
|
46
|
-
"https://badgen.net",
|
|
47
|
-
"https://forthebadge.com",
|
|
48
|
-
"https://vercel.com/button"
|
|
49
|
-
];
|
|
50
|
-
var cache = /* @__PURE__ */ new Map();
|
|
51
|
-
async function imageSizePlugin(app, md, type2 = false) {
|
|
52
|
-
if (!app.env.isBuild || !type2)
|
|
53
|
-
return;
|
|
54
|
-
if (type2 === "all") {
|
|
55
|
-
const start = performance.now();
|
|
56
|
-
try {
|
|
57
|
-
await scanRemoteImageSize(app);
|
|
58
|
-
} catch {
|
|
59
|
-
}
|
|
60
|
-
if (app.env.isDebug) {
|
|
61
|
-
logger.info(`[vuepress-plugin-md-power] imageSizePlugin: scan all images time spent: ${performance.now() - start}ms`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const imageRule = md.renderer.rules.image;
|
|
65
|
-
md.renderer.rules.image = (tokens, idx, options, env, self) => {
|
|
66
|
-
if (!env.filePathRelative || !env.filePath)
|
|
67
|
-
return imageRule(tokens, idx, options, env, self);
|
|
68
|
-
const token = tokens[idx];
|
|
69
|
-
const src = token.attrGet("src");
|
|
70
|
-
const width = token.attrGet("width");
|
|
71
|
-
const height = token.attrGet("height");
|
|
72
|
-
const size = resolveSize(src, width, height, env);
|
|
73
|
-
if (size) {
|
|
74
|
-
token.attrSet("width", `${size.width}`);
|
|
75
|
-
token.attrSet("height", `${size.height}`);
|
|
76
|
-
}
|
|
77
|
-
return imageRule(tokens, idx, options, env, self);
|
|
78
|
-
};
|
|
79
|
-
const rawHtmlBlockRule = md.renderer.rules.html_block;
|
|
80
|
-
const rawHtmlInlineRule = md.renderer.rules.html_inline;
|
|
81
|
-
md.renderer.rules.html_block = createHtmlRule(rawHtmlBlockRule);
|
|
82
|
-
md.renderer.rules.html_inline = createHtmlRule(rawHtmlInlineRule);
|
|
83
|
-
function createHtmlRule(rawHtmlRule) {
|
|
84
|
-
return (tokens, idx, options, env, self) => {
|
|
85
|
-
const token = tokens[idx];
|
|
86
|
-
token.content = token.content.replace(REG_IMG_TAG, (raw, info) => {
|
|
87
|
-
const { attrs: attrs2 } = resolveAttrs(info);
|
|
88
|
-
const src = attrs2.src || attrs2.srcset;
|
|
89
|
-
const size = resolveSize(src, attrs2.width, attrs2.height, env);
|
|
90
|
-
if (!size)
|
|
91
|
-
return raw;
|
|
92
|
-
attrs2.width = size.width;
|
|
93
|
-
attrs2.height = size.height;
|
|
94
|
-
const imgAttrs = Object.entries(attrs2).map(([key, value]) => typeof value === "boolean" ? key : `${key}="${value}"`).join(" ");
|
|
95
|
-
return `<img ${imgAttrs}>`;
|
|
96
|
-
});
|
|
97
|
-
return rawHtmlRule(tokens, idx, options, env, self);
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function resolveSize(src, width, height, env) {
|
|
101
|
-
if (!src || src.startsWith("data:"))
|
|
102
|
-
return false;
|
|
103
|
-
if (width && height)
|
|
104
|
-
return false;
|
|
105
|
-
const isExternal = isLinkExternal(src, env.base);
|
|
106
|
-
const filepath2 = isExternal ? src : resolveImageUrl(src, env, app);
|
|
107
|
-
if (isExternal) {
|
|
108
|
-
if (!cache.has(filepath2))
|
|
109
|
-
return false;
|
|
110
|
-
} else {
|
|
111
|
-
if (!cache.has(filepath2)) {
|
|
112
|
-
if (!fs.existsSync(filepath2))
|
|
113
|
-
return false;
|
|
114
|
-
const { width: w, height: h } = imageSize(fs.readFileSync(filepath2));
|
|
115
|
-
if (!w || !h)
|
|
116
|
-
return false;
|
|
117
|
-
cache.set(filepath2, { width: w, height: h });
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
const { width: originalWidth, height: originalHeight } = cache.get(filepath2);
|
|
121
|
-
const ratio = originalWidth / originalHeight;
|
|
122
|
-
if (width && !height) {
|
|
123
|
-
const w = Number.parseInt(width, 10);
|
|
124
|
-
return { width: w, height: Math.round(w / ratio) };
|
|
125
|
-
} else if (height && !width) {
|
|
126
|
-
const h = Number.parseInt(height, 10);
|
|
127
|
-
return { width: Math.round(h * ratio), height: h };
|
|
128
|
-
} else {
|
|
129
|
-
return { width: originalWidth, height: originalHeight };
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
function resolveImageUrl(src, env, app) {
|
|
134
|
-
if (src[0] === "/")
|
|
135
|
-
return app.dir.public(src.slice(1));
|
|
136
|
-
if (env.filePathRelative && src[0] === ".")
|
|
137
|
-
return app.dir.source(path.join(path.dirname(env.filePathRelative), src));
|
|
138
|
-
if (env.filePath && (src[0] === "." || src[0] === "/"))
|
|
139
|
-
return path.resolve(env.filePath, src);
|
|
140
|
-
return path.resolve(src);
|
|
141
|
-
}
|
|
142
|
-
async function scanRemoteImageSize(app) {
|
|
143
|
-
if (!app.env.isBuild)
|
|
144
|
-
return;
|
|
145
|
-
const cwd = app.dir.source();
|
|
146
|
-
const files = await fs.readdir(cwd, { recursive: true });
|
|
147
|
-
const imgList = [];
|
|
148
|
-
for (const file of files) {
|
|
149
|
-
const filepath2 = path.join(cwd, file);
|
|
150
|
-
if ((await fs.stat(filepath2)).isFile() && !filepath2.includes(".vuepress") && !filepath2.includes("node_modules") && filepath2.endsWith(".md")) {
|
|
151
|
-
const content = await fs.readFile(filepath2, "utf-8");
|
|
152
|
-
const syntaxMatched = content.match(REG_IMG) ?? [];
|
|
153
|
-
for (const img of syntaxMatched) {
|
|
154
|
-
const src = img.slice(img.indexOf("](") + 2, -1);
|
|
155
|
-
addList(src.split(/\s+/)[0]);
|
|
156
|
-
}
|
|
157
|
-
const tagMatched = content.match(REG_IMG_TAG) ?? [];
|
|
158
|
-
for (const img of tagMatched) {
|
|
159
|
-
const src = img.match(REG_IMG_TAG_SRC)?.[2] ?? "";
|
|
160
|
-
addList(src);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
function addList(src) {
|
|
165
|
-
if (src && isLinkHttp(src) && !imgList.includes(src) && !BADGE_LIST.some((badge) => src.startsWith(badge))) {
|
|
166
|
-
imgList.push(src);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
await Promise.all(imgList.map(async (src) => {
|
|
170
|
-
if (!cache.has(src)) {
|
|
171
|
-
const { width, height } = await fetchImageSize(src);
|
|
172
|
-
if (width && height)
|
|
173
|
-
cache.set(src, { width, height });
|
|
174
|
-
}
|
|
175
|
-
}));
|
|
176
|
-
}
|
|
177
|
-
function fetchImageSize(src) {
|
|
178
|
-
const link = new URL(src);
|
|
179
|
-
return new Promise((resolve) => {
|
|
180
|
-
http.get(link, async (stream) => {
|
|
181
|
-
const chunks = [];
|
|
182
|
-
for await (const chunk of stream) {
|
|
183
|
-
chunks.push(chunk);
|
|
184
|
-
try {
|
|
185
|
-
const { width: width2, height: height2 } = imageSize(Buffer.concat(chunks));
|
|
186
|
-
if (width2 && height2) {
|
|
187
|
-
return resolve({ width: width2, height: height2 });
|
|
188
|
-
}
|
|
189
|
-
} catch {
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
const { width, height } = imageSize(Buffer.concat(chunks));
|
|
193
|
-
resolve({ width, height });
|
|
194
|
-
}).on("error", () => resolve({ width: 0, height: 0 }));
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
async function resolveImageSize(app, url, remote = false) {
|
|
198
|
-
if (cache.has(url))
|
|
199
|
-
return cache.get(url);
|
|
200
|
-
if (isLinkHttp(url) && remote) {
|
|
201
|
-
return await fetchImageSize(url);
|
|
202
|
-
}
|
|
203
|
-
if (url[0] === "/") {
|
|
204
|
-
const filepath2 = app.dir.public(url.slice(1));
|
|
205
|
-
if (fs.existsSync(filepath2)) {
|
|
206
|
-
const { width, height } = imageSize(fs.readFileSync(filepath2));
|
|
207
|
-
return { width, height };
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return { width: 0, height: 0 };
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// src/node/plugin.ts
|
|
214
|
-
import { addViteOptimizeDepsInclude } from "@vuepress/helper";
|
|
215
|
-
import { isPackageExists as isPackageExists3 } from "local-pkg";
|
|
216
|
-
|
|
217
|
-
// src/node/container/index.ts
|
|
218
|
-
import { isPlainObject as isPlainObject2 } from "@vuepress/helper";
|
|
219
|
-
|
|
220
|
-
// src/node/container/createContainer.ts
|
|
221
|
-
import container from "markdown-it-container";
|
|
222
|
-
function createContainerPlugin(md, type2, options = {}) {
|
|
223
|
-
const render = (tokens, index) => {
|
|
224
|
-
const token = tokens[index];
|
|
225
|
-
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
226
|
-
if (token.nesting === 1) {
|
|
227
|
-
return options.before?.(info, tokens, index) || `<div class="custom-container ${type2}">`;
|
|
228
|
-
} else {
|
|
229
|
-
return options.after?.(info, tokens, index) || "</div>";
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
md.use(container, type2, { render });
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// src/node/container/align.ts
|
|
236
|
-
var alignList = ["left", "center", "right", "justify"];
|
|
237
|
-
function alignPlugin(md) {
|
|
238
|
-
for (const name of alignList) {
|
|
239
|
-
createContainerPlugin(md, name, {
|
|
240
|
-
before: () => `<div style="text-align:${name}">`
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// src/node/container/card.ts
|
|
246
|
-
function cardPlugin(md) {
|
|
247
|
-
createContainerPlugin(md, "card", {
|
|
248
|
-
before(info) {
|
|
249
|
-
const { attrs: attrs2 } = resolveAttrs(info);
|
|
250
|
-
const { title, icon } = attrs2;
|
|
251
|
-
return `<VPCard${title ? ` title="${title}"` : ""}${icon ? ` icon="${icon}"` : ""}>`;
|
|
252
|
-
},
|
|
253
|
-
after: () => "</VPCard>"
|
|
254
|
-
});
|
|
255
|
-
createContainerPlugin(md, "card-grid", {
|
|
256
|
-
before: () => "<VPCardGrid>",
|
|
257
|
-
after: () => "</VPCardGrid>"
|
|
258
|
-
});
|
|
259
|
-
createContainerPlugin(md, "card-masonry", {
|
|
260
|
-
before: (info) => {
|
|
261
|
-
const { attrs: attrs2 } = resolveAttrs(info);
|
|
262
|
-
let cols;
|
|
263
|
-
if (attrs2.cols) {
|
|
264
|
-
cols = attrs2.cols[0] === "{" ? attrs2.cols : Number.parseInt(`${attrs2.cols}`);
|
|
265
|
-
}
|
|
266
|
-
const gap = Number.parseInt(`${attrs2.gap}`);
|
|
267
|
-
return `<VPCardMasonry${cols ? ` :cols="${cols}"` : ""}${gap >= 0 ? ` :gap="${gap}"` : ""}>`;
|
|
268
|
-
},
|
|
269
|
-
after: () => "</VPCardMasonry>"
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
|
|
273
1
|
// src/node/container/codeTabs.ts
|
|
274
2
|
import { tab } from "@mdit/plugin-tab";
|
|
275
3
|
import { isPlainObject } from "@vuepress/helper";
|
|
@@ -1085,113 +813,401 @@ var definitions = {
|
|
|
1085
813
|
"TODO.txt": "vscode-icons:file-type-light-todo",
|
|
1086
814
|
"TODO.md": "vscode-icons:file-type-light-todo"
|
|
1087
815
|
}
|
|
1088
|
-
};
|
|
1089
|
-
|
|
1090
|
-
// src/node/fileIcons/findIcon.ts
|
|
1091
|
-
function getFileIcon(fileName, type2) {
|
|
1092
|
-
const name = getFileIconName(fileName, type2);
|
|
1093
|
-
if (!name)
|
|
1094
|
-
return type2 !== "folder" ? defaultFile : defaultFolder;
|
|
1095
|
-
return name;
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
// src/node/fileIcons/findIcon.ts
|
|
819
|
+
function getFileIcon(fileName, type2) {
|
|
820
|
+
const name = getFileIconName(fileName, type2);
|
|
821
|
+
if (!name)
|
|
822
|
+
return type2 !== "folder" ? defaultFile : defaultFolder;
|
|
823
|
+
return name;
|
|
824
|
+
}
|
|
825
|
+
function getFileIconName(fileName, type2 = "file") {
|
|
826
|
+
if (type2 === "folder") {
|
|
827
|
+
const icon2 = definitions.folders[fileName];
|
|
828
|
+
if (icon2)
|
|
829
|
+
return icon2;
|
|
830
|
+
if (fileName.includes("/"))
|
|
831
|
+
return definitions.folders[fileName.slice(fileName.lastIndexOf("/") + 1)];
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
let icon = definitions.named[fileName] || definitions.files[fileName];
|
|
835
|
+
if (icon)
|
|
836
|
+
return icon;
|
|
837
|
+
icon = getFileIconTypeFromExtension(fileName) || void 0;
|
|
838
|
+
if (icon)
|
|
839
|
+
return icon;
|
|
840
|
+
for (const [partial, partialIcon] of Object.entries(definitions.partials)) {
|
|
841
|
+
if (fileName.includes(partial))
|
|
842
|
+
return partialIcon;
|
|
843
|
+
}
|
|
844
|
+
return icon;
|
|
845
|
+
}
|
|
846
|
+
function getFileIconTypeFromExtension(fileName) {
|
|
847
|
+
const firstDotIndex = fileName.indexOf(".");
|
|
848
|
+
if (firstDotIndex === -1)
|
|
849
|
+
return;
|
|
850
|
+
let extension = fileName.slice(firstDotIndex);
|
|
851
|
+
while (extension !== "") {
|
|
852
|
+
const icon = definitions.extensions[extension];
|
|
853
|
+
if (icon)
|
|
854
|
+
return icon;
|
|
855
|
+
const nextDotIndex = extension.indexOf(".", 1);
|
|
856
|
+
if (nextDotIndex === -1)
|
|
857
|
+
return;
|
|
858
|
+
extension = extension.slice(nextDotIndex);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// src/node/utils/cleanMarkdownEnv.ts
|
|
863
|
+
function cleanMarkdownEnv(env) {
|
|
864
|
+
return {
|
|
865
|
+
base: env.base,
|
|
866
|
+
filePath: env.filePath,
|
|
867
|
+
filePathRelative: env.filePathRelative,
|
|
868
|
+
references: env.references,
|
|
869
|
+
abbreviations: env.abbreviations,
|
|
870
|
+
annotations: env.annotations
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// src/node/utils/stringifyProp.ts
|
|
875
|
+
function stringifyProp(data) {
|
|
876
|
+
return JSON.stringify(data).replace(/'/g, "'");
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// src/node/container/codeTabs.ts
|
|
880
|
+
function createCodeTabIconGetter(options = {}) {
|
|
881
|
+
const noop = () => void 0;
|
|
882
|
+
if (options.icon === false)
|
|
883
|
+
return noop;
|
|
884
|
+
const { named, extensions } = isPlainObject(options.icon) ? options.icon : {};
|
|
885
|
+
return function getIcon(filename) {
|
|
886
|
+
if (named === false && definitions.named[filename])
|
|
887
|
+
return void 0;
|
|
888
|
+
if (extensions === false && getFileIconTypeFromExtension(filename)) {
|
|
889
|
+
return void 0;
|
|
890
|
+
}
|
|
891
|
+
const hasNamed = named && named.length;
|
|
892
|
+
const hasExt = extensions && extensions.length;
|
|
893
|
+
if (hasNamed || hasExt) {
|
|
894
|
+
if (hasNamed && named.includes(filename))
|
|
895
|
+
return definitions.named[filename];
|
|
896
|
+
if (hasExt && extensions.some((ext) => filename.endsWith(ext)))
|
|
897
|
+
return getFileIconTypeFromExtension(filename);
|
|
898
|
+
return void 0;
|
|
899
|
+
}
|
|
900
|
+
return getFileIconName(filename);
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
var codeTabs = (md, options = {}) => {
|
|
904
|
+
const getIcon = createCodeTabIconGetter(options);
|
|
905
|
+
tab(md, {
|
|
906
|
+
name: "code-tabs",
|
|
907
|
+
tabsOpenRenderer: ({ active, data }, tokens, index, _, env) => {
|
|
908
|
+
const { meta } = tokens[index];
|
|
909
|
+
const titles = data.map(({ title }) => md.renderInline(title, cleanMarkdownEnv(env)));
|
|
910
|
+
const tabsData = data.map((item, dataIndex) => {
|
|
911
|
+
const { id = titles[dataIndex] } = item;
|
|
912
|
+
return { id };
|
|
913
|
+
});
|
|
914
|
+
const titlesContent = titles.map((title, index2) => {
|
|
915
|
+
const icon = getIcon(title);
|
|
916
|
+
return `<template #title${index2}="{ value, isActive }">${icon ? `<VPIcon name="${icon}"/>` : ""}<span>${title}</span></template>`;
|
|
917
|
+
}).join("");
|
|
918
|
+
return `<CodeTabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? "" : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id}"` : ""}>${titlesContent}`;
|
|
919
|
+
},
|
|
920
|
+
tabsCloseRenderer: () => `</CodeTabs>`,
|
|
921
|
+
tabOpenRenderer: ({ index }, tokens, tokenIndex) => {
|
|
922
|
+
let foundFence = false;
|
|
923
|
+
for (let i = tokenIndex; i < tokens.length; i++) {
|
|
924
|
+
const { type: type2 } = tokens[i];
|
|
925
|
+
if (type2 === "code-tabs_tab_close")
|
|
926
|
+
break;
|
|
927
|
+
if ((type2 === "fence" || type2 === "import_code") && !foundFence) {
|
|
928
|
+
foundFence = true;
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
tokens[i].type = "code_tab_empty";
|
|
932
|
+
tokens[i].hidden = true;
|
|
933
|
+
}
|
|
934
|
+
return `<template #tab${index}="{ value, isActive }">`;
|
|
935
|
+
},
|
|
936
|
+
tabCloseRenderer: () => `</template>`
|
|
937
|
+
});
|
|
938
|
+
};
|
|
939
|
+
|
|
940
|
+
// src/node/enhance/imageSize.ts
|
|
941
|
+
import { Buffer } from "node:buffer";
|
|
942
|
+
import http from "node:https";
|
|
943
|
+
import { URL } from "node:url";
|
|
944
|
+
import { isLinkExternal, isLinkHttp } from "@vuepress/helper";
|
|
945
|
+
import imageSize from "image-size";
|
|
946
|
+
import { fs, logger, path } from "vuepress/utils";
|
|
947
|
+
|
|
948
|
+
// src/node/utils/resolveAttrs.ts
|
|
949
|
+
var RE_ATTR_VALUE = /(?:^|\s+)(?<attr>[\w-]+)(?:=\s*(?<quote>['"])(?<value>.+?)\k<quote>)?(?:\s+|$)/;
|
|
950
|
+
function resolveAttrs(info) {
|
|
951
|
+
info = info.trim();
|
|
952
|
+
if (!info)
|
|
953
|
+
return { rawAttrs: "", attrs: {} };
|
|
954
|
+
const attrs2 = {};
|
|
955
|
+
const rawAttrs = info;
|
|
956
|
+
let matched;
|
|
957
|
+
while (matched = info.match(RE_ATTR_VALUE)) {
|
|
958
|
+
const { attr, value } = matched.groups;
|
|
959
|
+
attrs2[attr] = value ?? true;
|
|
960
|
+
info = info.slice(matched[0].length);
|
|
961
|
+
}
|
|
962
|
+
Object.keys(attrs2).forEach((key) => {
|
|
963
|
+
let value = attrs2[key];
|
|
964
|
+
value = typeof value === "string" ? value.trim() : value;
|
|
965
|
+
if (value === "true")
|
|
966
|
+
value = true;
|
|
967
|
+
else if (value === "false")
|
|
968
|
+
value = false;
|
|
969
|
+
attrs2[key] = value;
|
|
970
|
+
if (key.includes("-")) {
|
|
971
|
+
const _key = key.replace(/-(\w)/g, (_, c) => c.toUpperCase());
|
|
972
|
+
attrs2[_key] = value;
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
return { attrs: attrs2, rawAttrs };
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// src/node/enhance/imageSize.ts
|
|
979
|
+
var REG_IMG = /!\[.*?\]\(.*?\)/g;
|
|
980
|
+
var REG_IMG_TAG = /<img(.*?)>/g;
|
|
981
|
+
var REG_IMG_TAG_SRC = /src(?:set)?=(['"])(.+?)\1/g;
|
|
982
|
+
var BADGE_LIST = [
|
|
983
|
+
"https://img.shields.io",
|
|
984
|
+
"https://badge.fury.io",
|
|
985
|
+
"https://badgen.net",
|
|
986
|
+
"https://forthebadge.com",
|
|
987
|
+
"https://vercel.com/button"
|
|
988
|
+
];
|
|
989
|
+
var cache = /* @__PURE__ */ new Map();
|
|
990
|
+
async function imageSizePlugin(app, md, type2 = false) {
|
|
991
|
+
if (!app.env.isBuild || !type2)
|
|
992
|
+
return;
|
|
993
|
+
if (type2 === "all") {
|
|
994
|
+
const start = performance.now();
|
|
995
|
+
try {
|
|
996
|
+
await scanRemoteImageSize(app);
|
|
997
|
+
} catch {
|
|
998
|
+
}
|
|
999
|
+
if (app.env.isDebug) {
|
|
1000
|
+
logger.info(`[vuepress-plugin-md-power] imageSizePlugin: scan all images time spent: ${performance.now() - start}ms`);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
const imageRule = md.renderer.rules.image;
|
|
1004
|
+
md.renderer.rules.image = (tokens, idx, options, env, self) => {
|
|
1005
|
+
if (!env.filePathRelative || !env.filePath)
|
|
1006
|
+
return imageRule(tokens, idx, options, env, self);
|
|
1007
|
+
const token = tokens[idx];
|
|
1008
|
+
const src = token.attrGet("src");
|
|
1009
|
+
const width = token.attrGet("width");
|
|
1010
|
+
const height = token.attrGet("height");
|
|
1011
|
+
const size = resolveSize(src, width, height, env);
|
|
1012
|
+
if (size) {
|
|
1013
|
+
token.attrSet("width", `${size.width}`);
|
|
1014
|
+
token.attrSet("height", `${size.height}`);
|
|
1015
|
+
}
|
|
1016
|
+
return imageRule(tokens, idx, options, env, self);
|
|
1017
|
+
};
|
|
1018
|
+
const rawHtmlBlockRule = md.renderer.rules.html_block;
|
|
1019
|
+
const rawHtmlInlineRule = md.renderer.rules.html_inline;
|
|
1020
|
+
md.renderer.rules.html_block = createHtmlRule(rawHtmlBlockRule);
|
|
1021
|
+
md.renderer.rules.html_inline = createHtmlRule(rawHtmlInlineRule);
|
|
1022
|
+
function createHtmlRule(rawHtmlRule) {
|
|
1023
|
+
return (tokens, idx, options, env, self) => {
|
|
1024
|
+
const token = tokens[idx];
|
|
1025
|
+
token.content = token.content.replace(REG_IMG_TAG, (raw, info) => {
|
|
1026
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1027
|
+
const src = attrs2.src || attrs2.srcset;
|
|
1028
|
+
const size = resolveSize(src, attrs2.width, attrs2.height, env);
|
|
1029
|
+
if (!size)
|
|
1030
|
+
return raw;
|
|
1031
|
+
attrs2.width = size.width;
|
|
1032
|
+
attrs2.height = size.height;
|
|
1033
|
+
const imgAttrs = Object.entries(attrs2).map(([key, value]) => typeof value === "boolean" ? key : `${key}="${value}"`).join(" ");
|
|
1034
|
+
return `<img ${imgAttrs}>`;
|
|
1035
|
+
});
|
|
1036
|
+
return rawHtmlRule(tokens, idx, options, env, self);
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
function resolveSize(src, width, height, env) {
|
|
1040
|
+
if (!src || src.startsWith("data:"))
|
|
1041
|
+
return false;
|
|
1042
|
+
if (width && height)
|
|
1043
|
+
return false;
|
|
1044
|
+
const isExternal = isLinkExternal(src, env.base);
|
|
1045
|
+
const filepath2 = isExternal ? src : resolveImageUrl(src, env, app);
|
|
1046
|
+
if (isExternal) {
|
|
1047
|
+
if (!cache.has(filepath2))
|
|
1048
|
+
return false;
|
|
1049
|
+
} else {
|
|
1050
|
+
if (!cache.has(filepath2)) {
|
|
1051
|
+
if (!fs.existsSync(filepath2))
|
|
1052
|
+
return false;
|
|
1053
|
+
const { width: w, height: h } = imageSize(fs.readFileSync(filepath2));
|
|
1054
|
+
if (!w || !h)
|
|
1055
|
+
return false;
|
|
1056
|
+
cache.set(filepath2, { width: w, height: h });
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
const { width: originalWidth, height: originalHeight } = cache.get(filepath2);
|
|
1060
|
+
const ratio = originalWidth / originalHeight;
|
|
1061
|
+
if (width && !height) {
|
|
1062
|
+
const w = Number.parseInt(width, 10);
|
|
1063
|
+
return { width: w, height: Math.round(w / ratio) };
|
|
1064
|
+
} else if (height && !width) {
|
|
1065
|
+
const h = Number.parseInt(height, 10);
|
|
1066
|
+
return { width: Math.round(h * ratio), height: h };
|
|
1067
|
+
} else {
|
|
1068
|
+
return { width: originalWidth, height: originalHeight };
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1096
1071
|
}
|
|
1097
|
-
function
|
|
1098
|
-
if (
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1072
|
+
function resolveImageUrl(src, env, app) {
|
|
1073
|
+
if (src[0] === "/")
|
|
1074
|
+
return app.dir.public(src.slice(1));
|
|
1075
|
+
if (env.filePathRelative && src[0] === ".")
|
|
1076
|
+
return app.dir.source(path.join(path.dirname(env.filePathRelative), src));
|
|
1077
|
+
if (env.filePath && (src[0] === "." || src[0] === "/"))
|
|
1078
|
+
return path.resolve(env.filePath, src);
|
|
1079
|
+
return path.resolve(src);
|
|
1080
|
+
}
|
|
1081
|
+
async function scanRemoteImageSize(app) {
|
|
1082
|
+
if (!app.env.isBuild)
|
|
1104
1083
|
return;
|
|
1084
|
+
const cwd = app.dir.source();
|
|
1085
|
+
const files = await fs.readdir(cwd, { recursive: true });
|
|
1086
|
+
const imgList = [];
|
|
1087
|
+
for (const file of files) {
|
|
1088
|
+
const filepath2 = path.join(cwd, file);
|
|
1089
|
+
if ((await fs.stat(filepath2)).isFile() && !filepath2.includes(".vuepress") && !filepath2.includes("node_modules") && filepath2.endsWith(".md")) {
|
|
1090
|
+
const content = await fs.readFile(filepath2, "utf-8");
|
|
1091
|
+
const syntaxMatched = content.match(REG_IMG) ?? [];
|
|
1092
|
+
for (const img of syntaxMatched) {
|
|
1093
|
+
const src = img.slice(img.indexOf("](") + 2, -1);
|
|
1094
|
+
addList(src.split(/\s+/)[0]);
|
|
1095
|
+
}
|
|
1096
|
+
const tagMatched = content.match(REG_IMG_TAG) ?? [];
|
|
1097
|
+
for (const img of tagMatched) {
|
|
1098
|
+
const src = img.match(REG_IMG_TAG_SRC)?.[2] ?? "";
|
|
1099
|
+
addList(src);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1105
1102
|
}
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
if (icon)
|
|
1111
|
-
return icon;
|
|
1112
|
-
for (const [partial, partialIcon] of Object.entries(definitions.partials)) {
|
|
1113
|
-
if (fileName.includes(partial))
|
|
1114
|
-
return partialIcon;
|
|
1103
|
+
function addList(src) {
|
|
1104
|
+
if (src && isLinkHttp(src) && !imgList.includes(src) && !BADGE_LIST.some((badge) => src.startsWith(badge))) {
|
|
1105
|
+
imgList.push(src);
|
|
1106
|
+
}
|
|
1115
1107
|
}
|
|
1116
|
-
|
|
1108
|
+
await Promise.all(imgList.map(async (src) => {
|
|
1109
|
+
if (!cache.has(src)) {
|
|
1110
|
+
const { width, height } = await fetchImageSize(src);
|
|
1111
|
+
if (width && height)
|
|
1112
|
+
cache.set(src, { width, height });
|
|
1113
|
+
}
|
|
1114
|
+
}));
|
|
1117
1115
|
}
|
|
1118
|
-
function
|
|
1119
|
-
const
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1116
|
+
function fetchImageSize(src) {
|
|
1117
|
+
const link = new URL(src);
|
|
1118
|
+
return new Promise((resolve) => {
|
|
1119
|
+
http.get(link, async (stream) => {
|
|
1120
|
+
const chunks = [];
|
|
1121
|
+
for await (const chunk of stream) {
|
|
1122
|
+
chunks.push(chunk);
|
|
1123
|
+
try {
|
|
1124
|
+
const { width: width2, height: height2 } = imageSize(Buffer.concat(chunks));
|
|
1125
|
+
if (width2 && height2) {
|
|
1126
|
+
return resolve({ width: width2, height: height2 });
|
|
1127
|
+
}
|
|
1128
|
+
} catch {
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
const { width, height } = imageSize(Buffer.concat(chunks));
|
|
1132
|
+
resolve({ width, height });
|
|
1133
|
+
}).on("error", () => resolve({ width: 0, height: 0 }));
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
async function resolveImageSize(app, url, remote = false) {
|
|
1137
|
+
if (cache.has(url))
|
|
1138
|
+
return cache.get(url);
|
|
1139
|
+
if (isLinkHttp(url) && remote) {
|
|
1140
|
+
return await fetchImageSize(url);
|
|
1141
|
+
}
|
|
1142
|
+
if (url[0] === "/") {
|
|
1143
|
+
const filepath2 = app.dir.public(url.slice(1));
|
|
1144
|
+
if (fs.existsSync(filepath2)) {
|
|
1145
|
+
const { width, height } = imageSize(fs.readFileSync(filepath2));
|
|
1146
|
+
return { width, height };
|
|
1147
|
+
}
|
|
1131
1148
|
}
|
|
1149
|
+
return { width: 0, height: 0 };
|
|
1132
1150
|
}
|
|
1133
1151
|
|
|
1134
|
-
// src/node/
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
}
|
|
1152
|
+
// src/node/plugin.ts
|
|
1153
|
+
import { addViteOptimizeDepsInclude } from "@vuepress/helper";
|
|
1154
|
+
import { isPackageExists as isPackageExists3 } from "local-pkg";
|
|
1138
1155
|
|
|
1139
|
-
// src/node/container/
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
if (hasNamed || hasExt) {
|
|
1153
|
-
if (hasNamed && named.includes(filename))
|
|
1154
|
-
return definitions.named[filename];
|
|
1155
|
-
if (hasExt && extensions.some((ext) => filename.endsWith(ext)))
|
|
1156
|
-
return getFileIconTypeFromExtension(filename);
|
|
1157
|
-
return void 0;
|
|
1156
|
+
// src/node/container/index.ts
|
|
1157
|
+
import { isPlainObject as isPlainObject2 } from "@vuepress/helper";
|
|
1158
|
+
|
|
1159
|
+
// src/node/container/createContainer.ts
|
|
1160
|
+
import container from "markdown-it-container";
|
|
1161
|
+
function createContainerPlugin(md, type2, options = {}) {
|
|
1162
|
+
const render = (tokens, index) => {
|
|
1163
|
+
const token = tokens[index];
|
|
1164
|
+
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
1165
|
+
if (token.nesting === 1) {
|
|
1166
|
+
return options.before?.(info, tokens, index) || `<div class="custom-container ${type2}">`;
|
|
1167
|
+
} else {
|
|
1168
|
+
return options.after?.(info, tokens, index) || "</div>";
|
|
1158
1169
|
}
|
|
1159
|
-
return getFileIconName(filename);
|
|
1160
1170
|
};
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1171
|
+
md.use(container, type2, { render });
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// src/node/container/align.ts
|
|
1175
|
+
var alignList = ["left", "center", "right", "justify"];
|
|
1176
|
+
function alignPlugin(md) {
|
|
1177
|
+
for (const name of alignList) {
|
|
1178
|
+
createContainerPlugin(md, name, {
|
|
1179
|
+
before: () => `<div style="text-align:${name}">`
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
// src/node/container/card.ts
|
|
1185
|
+
function cardPlugin(md) {
|
|
1186
|
+
createContainerPlugin(md, "card", {
|
|
1187
|
+
before(info) {
|
|
1188
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1189
|
+
const { title, icon } = attrs2;
|
|
1190
|
+
return `<VPCard${title ? ` title="${title}"` : ""}${icon ? ` icon="${icon}"` : ""}>`;
|
|
1175
1191
|
},
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
tokens[i].hidden = true;
|
|
1192
|
+
after: () => "</VPCard>"
|
|
1193
|
+
});
|
|
1194
|
+
createContainerPlugin(md, "card-grid", {
|
|
1195
|
+
before: () => "<VPCardGrid>",
|
|
1196
|
+
after: () => "</VPCardGrid>"
|
|
1197
|
+
});
|
|
1198
|
+
createContainerPlugin(md, "card-masonry", {
|
|
1199
|
+
before: (info) => {
|
|
1200
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1201
|
+
let cols;
|
|
1202
|
+
if (attrs2.cols) {
|
|
1203
|
+
cols = attrs2.cols[0] === "{" ? attrs2.cols : Number.parseInt(`${attrs2.cols}`);
|
|
1189
1204
|
}
|
|
1190
|
-
|
|
1205
|
+
const gap = Number.parseInt(`${attrs2.gap}`);
|
|
1206
|
+
return `<VPCardMasonry${cols ? ` :cols="${cols}"` : ""}${gap >= 0 ? ` :gap="${gap}"` : ""}>`;
|
|
1191
1207
|
},
|
|
1192
|
-
|
|
1208
|
+
after: () => "</VPCardMasonry>"
|
|
1193
1209
|
});
|
|
1194
|
-
}
|
|
1210
|
+
}
|
|
1195
1211
|
|
|
1196
1212
|
// src/node/container/demoWrapper.ts
|
|
1197
1213
|
function demoWrapperPlugin(md) {
|
|
@@ -1760,7 +1776,7 @@ function parseArgs(line) {
|
|
|
1760
1776
|
isNextValue = !isBool;
|
|
1761
1777
|
}
|
|
1762
1778
|
if (!isKey && !isNextValue) {
|
|
1763
|
-
cmd +=
|
|
1779
|
+
cmd += ` ${value}`;
|
|
1764
1780
|
} else {
|
|
1765
1781
|
newLine += `${value}${i !== npmArgs.length - 1 ? v : ""}`;
|
|
1766
1782
|
if (!isKey && isNextValue) {
|
|
@@ -1791,7 +1807,7 @@ var tabs = (md) => {
|
|
|
1791
1807
|
name: "tabs",
|
|
1792
1808
|
tabsOpenRenderer: ({ active, data }, tokens, index, _, env) => {
|
|
1793
1809
|
const { meta } = tokens[index];
|
|
1794
|
-
const titles = data.map(({ title }) => md.renderInline(title, env));
|
|
1810
|
+
const titles = data.map(({ title }) => md.renderInline(title, cleanMarkdownEnv(env)));
|
|
1795
1811
|
const tabsData = data.map((item, dataIndex) => {
|
|
1796
1812
|
const { id = titles[dataIndex] } = item;
|
|
1797
1813
|
return { id };
|
|
@@ -3116,7 +3132,7 @@ var abbrPlugin = (md) => {
|
|
|
3116
3132
|
md.core.ruler.after("linkify", "abbr_replace", abbrReplace);
|
|
3117
3133
|
md.renderer.rules.abbreviation = (tokens, idx, _, env) => {
|
|
3118
3134
|
const { content, info } = tokens[idx];
|
|
3119
|
-
return `<Abbreviation>${content}${info ? `<template #tooltip>${md.renderInline(info, env)}</template>` : ""}</Abbreviation>`;
|
|
3135
|
+
return `<Abbreviation>${content}${info ? `<template #tooltip>${md.renderInline(info, cleanMarkdownEnv(env))}</template>` : ""}</Abbreviation>`;
|
|
3120
3136
|
};
|
|
3121
3137
|
};
|
|
3122
3138
|
|
|
@@ -3363,7 +3379,7 @@ async function prepareConfigFile(app, options) {
|
|
|
3363
3379
|
enhances.add(`app.component('CodePenViewer', CodePen)`);
|
|
3364
3380
|
}
|
|
3365
3381
|
if (options.jsfiddle) {
|
|
3366
|
-
imports.add(`import JSFiddle from '${CLIENT_FOLDER}components/
|
|
3382
|
+
imports.add(`import JSFiddle from '${CLIENT_FOLDER}components/JsFiddle.vue'`);
|
|
3367
3383
|
enhances.add(`app.component('JSFiddleViewer', JSFiddle)`);
|
|
3368
3384
|
}
|
|
3369
3385
|
if (options.replit) {
|
|
@@ -3480,6 +3496,7 @@ function markdownPowerPlugin(options = {}) {
|
|
|
3480
3496
|
};
|
|
3481
3497
|
}
|
|
3482
3498
|
export {
|
|
3499
|
+
createCodeTabIconGetter,
|
|
3483
3500
|
markdownPowerPlugin,
|
|
3484
3501
|
resolveImageSize
|
|
3485
3502
|
};
|
package/lib/shared/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vuepress-plugin-md-power",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.136",
|
|
5
5
|
"description": "The Plugin for VuePress 2 - markdown power",
|
|
6
6
|
"author": "pengzhanbo <volodymyr@foxmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,16 +31,16 @@
|
|
|
31
31
|
"lib"
|
|
32
32
|
],
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"artplayer": "^5.2.
|
|
34
|
+
"artplayer": "^5.2.2",
|
|
35
35
|
"dashjs": "^5.0.0",
|
|
36
|
-
"esbuild": "
|
|
37
|
-
"hls.js": "^1.5.
|
|
38
|
-
"less": "^4.2.
|
|
39
|
-
"markdown-it": "^14.
|
|
40
|
-
"mpegts.js": "^1.
|
|
41
|
-
"sass": "^1.
|
|
42
|
-
"sass-embedded": "^1.
|
|
43
|
-
"stylus": "
|
|
36
|
+
"esbuild": "^0.25.1",
|
|
37
|
+
"hls.js": "^1.5.20",
|
|
38
|
+
"less": "^4.2.2",
|
|
39
|
+
"markdown-it": "^14.1.0",
|
|
40
|
+
"mpegts.js": "^1.7.3",
|
|
41
|
+
"sass": "^1.85.1",
|
|
42
|
+
"sass-embedded": "^1.85.1",
|
|
43
|
+
"stylus": "^0.64.0",
|
|
44
44
|
"vuepress": "2.0.0-rc.20"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
@@ -62,23 +62,23 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@mdit/plugin-attrs": "^0.16.7",
|
|
65
|
-
"@mdit/plugin-footnote": "^0.16.
|
|
65
|
+
"@mdit/plugin-footnote": "^0.16.8",
|
|
66
66
|
"@mdit/plugin-mark": "^0.16.0",
|
|
67
67
|
"@mdit/plugin-sub": "^0.16.0",
|
|
68
68
|
"@mdit/plugin-sup": "^0.16.0",
|
|
69
69
|
"@mdit/plugin-tab": "^0.16.0",
|
|
70
70
|
"@mdit/plugin-tasklist": "^0.16.0",
|
|
71
|
-
"@vuepress/helper": "2.0.0-rc.
|
|
72
|
-
"@vueuse/core": "^
|
|
71
|
+
"@vuepress/helper": "2.0.0-rc.82",
|
|
72
|
+
"@vueuse/core": "^13.0.0",
|
|
73
73
|
"chokidar": "3.6.0",
|
|
74
|
-
"image-size": "^2.0.
|
|
75
|
-
"local-pkg": "^1.1.
|
|
74
|
+
"image-size": "^2.0.1",
|
|
75
|
+
"local-pkg": "^1.1.1",
|
|
76
76
|
"lru-cache": "^11.0.2",
|
|
77
77
|
"markdown-it-container": "^4.0.0",
|
|
78
|
-
"nanoid": "^5.1.
|
|
79
|
-
"shiki": "^3.1
|
|
80
|
-
"tm-grammars": "^1.
|
|
81
|
-
"tm-themes": "^1.
|
|
78
|
+
"nanoid": "^5.1.3",
|
|
79
|
+
"shiki": "^3.2.1",
|
|
80
|
+
"tm-grammars": "^1.23.3",
|
|
81
|
+
"tm-themes": "^1.10.1",
|
|
82
82
|
"vue": "^3.5.13"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"artplayer": "^5.2.2",
|
|
87
87
|
"dashjs": "^5.0.0",
|
|
88
88
|
"hls.js": "^1.5.20",
|
|
89
|
-
"mpegts.js": "
|
|
89
|
+
"mpegts.js": "1.7.3"
|
|
90
90
|
},
|
|
91
91
|
"publishConfig": {
|
|
92
92
|
"access": "public"
|