vuepress-plugin-md-power 1.0.0-rc.101 → 1.0.0-rc.103
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/CanIUse.vue +2 -6
- package/lib/client/components/CodeEditor.vue +3 -3
- package/lib/client/components/CodeRepl.vue +13 -13
- package/lib/client/components/CodeSandbox.vue +5 -7
- package/lib/client/components/CodeTabs.vue +245 -0
- package/lib/client/components/FileTreeItem.vue +8 -8
- package/lib/client/components/PDFViewer.vue +1 -1
- package/lib/client/components/Plot.vue +4 -4
- package/lib/client/components/Replit.vue +2 -2
- package/lib/client/components/Tabs.vue +277 -0
- package/lib/client/components/{Loading.vue → icons/Loading.vue} +1 -1
- package/lib/node/index.d.ts +18 -7
- package/lib/node/index.js +771 -577
- package/lib/shared/index.d.ts +18 -7
- package/package.json +12 -5
- /package/lib/client/components/{IconClose.vue → icons/IconClose.vue} +0 -0
- /package/lib/client/components/{IconConsole.vue → icons/IconConsole.vue} +0 -0
- /package/lib/client/components/{IconRun.vue → icons/IconRun.vue} +0 -0
package/lib/node/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/node/
|
|
1
|
+
// src/node/enhance/imageSize.ts
|
|
2
2
|
import { Buffer } from "node:buffer";
|
|
3
3
|
import http from "node:https";
|
|
4
4
|
import { URL } from "node:url";
|
|
@@ -12,31 +12,31 @@ function resolveAttrs(info) {
|
|
|
12
12
|
info = info.trim();
|
|
13
13
|
if (!info)
|
|
14
14
|
return { rawAttrs: "", attrs: {} };
|
|
15
|
-
const
|
|
15
|
+
const attrs2 = {};
|
|
16
16
|
const rawAttrs = info;
|
|
17
17
|
let matched;
|
|
18
18
|
while (matched = info.match(RE_ATTR_VALUE)) {
|
|
19
19
|
const { attr, value } = matched.groups || {};
|
|
20
|
-
|
|
20
|
+
attrs2[attr] = value ?? true;
|
|
21
21
|
info = info.slice(matched[0].length);
|
|
22
22
|
}
|
|
23
|
-
Object.keys(
|
|
24
|
-
let value =
|
|
23
|
+
Object.keys(attrs2).forEach((key) => {
|
|
24
|
+
let value = attrs2[key];
|
|
25
25
|
value = typeof value === "string" ? value.trim() : value;
|
|
26
26
|
if (value === "true")
|
|
27
27
|
value = true;
|
|
28
28
|
else if (value === "false")
|
|
29
29
|
value = false;
|
|
30
|
-
|
|
30
|
+
attrs2[key] = value;
|
|
31
31
|
if (key.includes("-")) {
|
|
32
32
|
const _key = key.replace(/-(\w)/g, (_, c) => c.toUpperCase());
|
|
33
|
-
|
|
33
|
+
attrs2[_key] = value;
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
-
return { attrs, rawAttrs };
|
|
36
|
+
return { attrs: attrs2, rawAttrs };
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
// src/node/
|
|
39
|
+
// src/node/enhance/imageSize.ts
|
|
40
40
|
var REG_IMG = /!\[.*?\]\(.*?\)/g;
|
|
41
41
|
var REG_IMG_TAG = /<img(.*?)>/g;
|
|
42
42
|
var REG_IMG_TAG_SRC = /src(?:set)?=(['"])(.+?)\1/g;
|
|
@@ -80,14 +80,14 @@ async function imageSizePlugin(app, md, type2 = false) {
|
|
|
80
80
|
return (tokens, idx, options, env, self) => {
|
|
81
81
|
const token = tokens[idx];
|
|
82
82
|
token.content = token.content.replace(REG_IMG_TAG, (raw, info) => {
|
|
83
|
-
const { attrs } = resolveAttrs(info);
|
|
84
|
-
const src =
|
|
85
|
-
const size = resolveSize(src,
|
|
83
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
84
|
+
const src = attrs2.src || attrs2.srcset;
|
|
85
|
+
const size = resolveSize(src, attrs2.width, attrs2.height, env);
|
|
86
86
|
if (!size)
|
|
87
87
|
return raw;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const imgAttrs = Object.entries(
|
|
88
|
+
attrs2.width = size.width;
|
|
89
|
+
attrs2.height = size.height;
|
|
90
|
+
const imgAttrs = Object.entries(attrs2).map(([key, value]) => typeof value === "boolean" ? key : `${key}="${value}"`).join(" ");
|
|
91
91
|
return `<img ${imgAttrs}>`;
|
|
92
92
|
});
|
|
93
93
|
return rawHtmlRule(tokens, idx, options, env, self);
|
|
@@ -209,307 +209,176 @@ async function resolveImageSize(app, url, remote = false) {
|
|
|
209
209
|
// src/node/plugin.ts
|
|
210
210
|
import { addViteOptimizeDepsInclude } from "@vuepress/helper";
|
|
211
211
|
|
|
212
|
-
// src/node/
|
|
213
|
-
import
|
|
214
|
-
import { customAlphabet } from "nanoid";
|
|
212
|
+
// src/node/container/index.ts
|
|
213
|
+
import { isPlainObject as isPlainObject2 } from "@vuepress/helper";
|
|
215
214
|
|
|
216
|
-
// src/node/
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
beforeName,
|
|
230
|
-
name,
|
|
231
|
-
(state, startLine, endLine, silent) => {
|
|
232
|
-
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
233
|
-
const max = state.eMarks[startLine];
|
|
234
|
-
if (pos + MIN_LENGTH > max)
|
|
235
|
-
return false;
|
|
236
|
-
for (let i = 0; i < START_CODES.length; i += 1) {
|
|
237
|
-
if (state.src.charCodeAt(pos + i) !== START_CODES[i])
|
|
238
|
-
return false;
|
|
215
|
+
// src/node/container/align.ts
|
|
216
|
+
import container from "markdown-it-container";
|
|
217
|
+
var alignList = ["left", "center", "right", "justify"];
|
|
218
|
+
function alignPlugin(md) {
|
|
219
|
+
for (const name of alignList) {
|
|
220
|
+
md.use(container, name, {
|
|
221
|
+
validate: (info) => info.trim() === name,
|
|
222
|
+
render: (tokens, idx) => {
|
|
223
|
+
if (tokens[idx].nesting === 1) {
|
|
224
|
+
return `<div style="text-align:${name}">`;
|
|
225
|
+
} else {
|
|
226
|
+
return "</div>";
|
|
227
|
+
}
|
|
239
228
|
}
|
|
240
|
-
|
|
241
|
-
if (!match)
|
|
242
|
-
return false;
|
|
243
|
-
if (silent)
|
|
244
|
-
return true;
|
|
245
|
-
const token = state.push(name, "", 0);
|
|
246
|
-
token.meta = meta(match);
|
|
247
|
-
token.map = [startLine, startLine + 1];
|
|
248
|
-
state.line = startLine + 1;
|
|
249
|
-
return true;
|
|
250
|
-
},
|
|
251
|
-
ruleOptions
|
|
252
|
-
);
|
|
253
|
-
md.renderer.rules[name] = (tokens, index) => {
|
|
254
|
-
const token = tokens[index];
|
|
255
|
-
token.content = content(token.meta);
|
|
256
|
-
return token.content;
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// src/node/features/caniuse.ts
|
|
261
|
-
var nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 5);
|
|
262
|
-
var UNDERLINE_RE = /_+/g;
|
|
263
|
-
var caniusePlugin = (md, { mode: defaultMode = "embed" } = {}) => {
|
|
264
|
-
createRuleBlock(md, {
|
|
265
|
-
type: "caniuse",
|
|
266
|
-
syntaxPattern: /^@\[caniuse\s*(embed|image)?(?:\{([0-9,\-]*)\})?\]\(([^)]*)\)/,
|
|
267
|
-
meta: ([, mode, versions = "", feature]) => ({
|
|
268
|
-
feature,
|
|
269
|
-
mode: mode || defaultMode,
|
|
270
|
-
versions
|
|
271
|
-
}),
|
|
272
|
-
content: (meta) => resolveCanIUse(meta)
|
|
273
|
-
});
|
|
274
|
-
};
|
|
275
|
-
function legacyCaniuse(md, { mode = "embed" } = {}) {
|
|
276
|
-
const modeMap = ["image", "embed"];
|
|
277
|
-
const isMode = (mode2) => modeMap.includes(mode2);
|
|
278
|
-
mode = isMode(mode) ? mode : modeMap[0];
|
|
279
|
-
const type2 = "caniuse";
|
|
280
|
-
const validateReg = new RegExp(`^${type2}`);
|
|
281
|
-
const validate = (info) => {
|
|
282
|
-
return validateReg.test(info.trim());
|
|
283
|
-
};
|
|
284
|
-
const render = (tokens, index) => {
|
|
285
|
-
const token = tokens[index];
|
|
286
|
-
if (token.nesting === 1) {
|
|
287
|
-
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
288
|
-
const feature = info.split(/\s+/)[0];
|
|
289
|
-
const versions = info.match(/\{(.*)\}/)?.[1] || "";
|
|
290
|
-
return feature ? resolveCanIUse({ feature, mode, versions }) : "";
|
|
291
|
-
} else {
|
|
292
|
-
return "";
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
md.use(container, type2, { validate, render });
|
|
296
|
-
}
|
|
297
|
-
function resolveCanIUse({ feature, mode, versions }) {
|
|
298
|
-
if (!feature)
|
|
299
|
-
return "";
|
|
300
|
-
if (mode === "image") {
|
|
301
|
-
const link = "https://caniuse.bitsofco.de/image/";
|
|
302
|
-
const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`;
|
|
303
|
-
return `<ClientOnly><p><picture>
|
|
304
|
-
<source type="image/webp" srcset="${link}${feature}.webp">
|
|
305
|
-
<source type="image/png" srcset="${link}${feature}.png">
|
|
306
|
-
<img src="${link}${feature}.jpg" alt="${alt}" width="100%">
|
|
307
|
-
</picture></p></ClientOnly>`;
|
|
229
|
+
});
|
|
308
230
|
}
|
|
309
|
-
feature = feature.replace(UNDERLINE_RE, "_");
|
|
310
|
-
const { past, future } = resolveVersions(versions);
|
|
311
|
-
const meta = nanoid();
|
|
312
|
-
return `<CanIUseViewer feature="${feature}" meta="${meta}" past="${past}" future="${future}" />`;
|
|
313
|
-
}
|
|
314
|
-
function resolveVersions(versions) {
|
|
315
|
-
if (!versions)
|
|
316
|
-
return { past: 2, future: 1 };
|
|
317
|
-
const list = versions.split(",").map((v) => Number(v.trim())).filter((v) => !Number.isNaN(v) && v >= -5 && v <= 3);
|
|
318
|
-
list.push(0);
|
|
319
|
-
const uniq = [...new Set(list)].sort((a, b) => b - a);
|
|
320
|
-
return {
|
|
321
|
-
future: uniq[0],
|
|
322
|
-
past: Math.abs(uniq[uniq.length - 1])
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// src/node/utils/parseRect.ts
|
|
327
|
-
function parseRect(str, unit = "px") {
|
|
328
|
-
if (Number.parseFloat(str) === Number(str))
|
|
329
|
-
return `${str}${unit}`;
|
|
330
|
-
return str;
|
|
331
231
|
}
|
|
332
232
|
|
|
333
|
-
// src/node/
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
createRuleBlock(md, {
|
|
337
|
-
type: "codepen",
|
|
338
|
-
syntaxPattern: /^@\[codepen([^\]]*)\]\(([^)]*)\)/,
|
|
339
|
-
meta: ([, info = "", source = ""]) => {
|
|
340
|
-
const { attrs } = resolveAttrs(info);
|
|
341
|
-
const [user, slash] = source.split("/");
|
|
342
|
-
return {
|
|
343
|
-
width: attrs.width ? parseRect(attrs.width) : "100%",
|
|
344
|
-
height: attrs.height ? parseRect(attrs.height) : "400px",
|
|
345
|
-
user,
|
|
346
|
-
slash,
|
|
347
|
-
title: attrs.title,
|
|
348
|
-
preview: attrs.preview,
|
|
349
|
-
editable: attrs.editable,
|
|
350
|
-
tab: attrs.tab ?? "result",
|
|
351
|
-
theme: attrs.theme
|
|
352
|
-
};
|
|
353
|
-
},
|
|
354
|
-
content: (meta) => {
|
|
355
|
-
const { title = "Codepen", height, width } = meta;
|
|
356
|
-
const params = new URLSearchParams();
|
|
357
|
-
if (meta.editable) {
|
|
358
|
-
params.set("editable", "true");
|
|
359
|
-
}
|
|
360
|
-
if (meta.tab) {
|
|
361
|
-
params.set("default-tab", meta.tab);
|
|
362
|
-
}
|
|
363
|
-
if (meta.theme) {
|
|
364
|
-
params.set("theme-id", meta.theme);
|
|
365
|
-
}
|
|
366
|
-
const middle = meta.preview ? "/embed/preview/" : "/embed/";
|
|
367
|
-
const link = `${CODEPEN_LINK}${meta.user}${middle}${meta.slash}?${params.toString()}`;
|
|
368
|
-
const style = `width:${width};height:${height};margin:16px auto;border-radius:5px;`;
|
|
369
|
-
return `<iframe class="code-pen-iframe-wrapper" src="${link}" title="${title}" style="${style}" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">See the Pen <a href="${CODEPEN_LINK}${meta.user}/pen/${meta.slash}">${title}</a> by ${meta.user} (<a href="${CODEPEN_LINK}${meta.user}">@${meta.user}</a>) on <a href="${CODEPEN_LINK}">CodePen</a>.</iframe>`;
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
// src/node/features/codeSandbox.ts
|
|
375
|
-
var codeSandboxPlugin = (md) => {
|
|
376
|
-
createRuleBlock(md, {
|
|
377
|
-
type: "codesandbox",
|
|
378
|
-
syntaxPattern: /^@\[codesandbox(?:\s+(embed|button))?([^\]]*)\]\(([^)]*)\)/,
|
|
379
|
-
meta([, type2, info = "", source = ""]) {
|
|
380
|
-
const { attrs } = resolveAttrs(info);
|
|
381
|
-
const [profile, filepath2 = ""] = source.split("#");
|
|
382
|
-
const [user, id] = profile.includes("/") ? profile.split("/") : ["", profile];
|
|
383
|
-
return {
|
|
384
|
-
width: attrs.width ? parseRect(attrs.width) : "100%",
|
|
385
|
-
height: attrs.height ? parseRect(attrs.height) : "500px",
|
|
386
|
-
user,
|
|
387
|
-
id,
|
|
388
|
-
title: attrs.title ?? "",
|
|
389
|
-
console: attrs.console ?? false,
|
|
390
|
-
navbar: attrs.navbar ?? true,
|
|
391
|
-
layout: attrs.layout ?? "",
|
|
392
|
-
type: type2 || "embed",
|
|
393
|
-
filepath: filepath2
|
|
394
|
-
};
|
|
395
|
-
},
|
|
396
|
-
content({ title, height, width, user, id, type: type2, filepath: filepath2, console, navbar, layout }) {
|
|
397
|
-
return `<CodeSandboxViewer title="${title}" height="${height}" width="${width}" user="${user}" id="${id}" type="${type2}" filepath="${filepath2}" :console=${console} :navbar=${navbar} layout="${layout}" />`;
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
|
-
};
|
|
401
|
-
|
|
402
|
-
// src/node/features/fileTree/index.ts
|
|
403
|
-
import container2 from "markdown-it-container";
|
|
233
|
+
// src/node/container/codeTabs.ts
|
|
234
|
+
import { tab } from "@mdit/plugin-tab";
|
|
235
|
+
import { isPlainObject } from "@vuepress/helper";
|
|
404
236
|
|
|
405
|
-
// src/node/
|
|
237
|
+
// src/node/fileIcons/definitions.ts
|
|
406
238
|
var defaultFolder = "vscode-icons:default-folder";
|
|
407
239
|
var defaultFile = "vscode-icons:default-file";
|
|
408
240
|
var definitions = {
|
|
409
241
|
named: {
|
|
410
242
|
// package manager
|
|
411
|
-
pnpm: "vscode-icons:file-type-light-pnpm",
|
|
412
|
-
PNPM: "vscode-icons:file-type-light-pnpm",
|
|
413
|
-
npm: "
|
|
414
|
-
NPM: "
|
|
415
|
-
yarn: "vscode-icons:file-type-yarn",
|
|
416
|
-
Yarn: "vscode-icons:file-type-yarn",
|
|
417
|
-
bun: "vscode-icons:file-type-bun",
|
|
418
|
-
Bun: "vscode-icons:file-type-bun",
|
|
419
|
-
deno: "vscode-icons:file-type-light-deno",
|
|
420
|
-
Deno: "vscode-icons:file-type-light-deno",
|
|
243
|
+
"pnpm": "vscode-icons:file-type-light-pnpm",
|
|
244
|
+
"PNPM": "vscode-icons:file-type-light-pnpm",
|
|
245
|
+
"npm": "logos:npm-icon",
|
|
246
|
+
"NPM": "logos:npm-icon",
|
|
247
|
+
"yarn": "vscode-icons:file-type-yarn",
|
|
248
|
+
"Yarn": "vscode-icons:file-type-yarn",
|
|
249
|
+
"bun": "vscode-icons:file-type-bun",
|
|
250
|
+
"Bun": "vscode-icons:file-type-bun",
|
|
251
|
+
"deno": "vscode-icons:file-type-light-deno",
|
|
252
|
+
"Deno": "vscode-icons:file-type-light-deno",
|
|
421
253
|
// bundlers
|
|
422
|
-
rollup: "vscode-icons:file-type-rollup",
|
|
423
|
-
Rollup: "vscode-icons:file-type-rollup",
|
|
424
|
-
webpack: "vscode-icons:file-type-webpack",
|
|
425
|
-
Webpack: "vscode-icons:file-type-webpack",
|
|
426
|
-
vite: "vscode-icons:file-type-vite",
|
|
427
|
-
Vite: "vscode-icons:file-type-vite",
|
|
428
|
-
esbuild: "vscode-icons:file-type-esbuild",
|
|
429
|
-
Esbuild: "vscode-icons:file-type-esbuild",
|
|
254
|
+
"rollup": "vscode-icons:file-type-rollup",
|
|
255
|
+
"Rollup": "vscode-icons:file-type-rollup",
|
|
256
|
+
"webpack": "vscode-icons:file-type-webpack",
|
|
257
|
+
"Webpack": "vscode-icons:file-type-webpack",
|
|
258
|
+
"vite": "vscode-icons:file-type-vite",
|
|
259
|
+
"Vite": "vscode-icons:file-type-vite",
|
|
260
|
+
"esbuild": "vscode-icons:file-type-esbuild",
|
|
261
|
+
"Esbuild": "vscode-icons:file-type-esbuild",
|
|
430
262
|
// frameworks
|
|
431
|
-
vue: "vscode-icons:file-type-vue",
|
|
432
|
-
Vue: "vscode-icons:file-type-vue",
|
|
433
|
-
svelte: "vscode-icons:file-type-svelte",
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
263
|
+
"vue": "vscode-icons:file-type-vue",
|
|
264
|
+
"Vue": "vscode-icons:file-type-vue",
|
|
265
|
+
"svelte": "vscode-icons:file-type-svelte",
|
|
266
|
+
"Svelte": "vscode-icons:file-type-svelte",
|
|
267
|
+
"sveltekit": "vscode-icons:file-type-svelte",
|
|
268
|
+
"SvelteKit": "vscode-icons:file-type-svelte",
|
|
269
|
+
"angular": "vscode-icons:file-type-angular",
|
|
270
|
+
"Angular": "vscode-icons:file-type-angular",
|
|
271
|
+
"react": "vscode-icons:file-type-reactjs",
|
|
272
|
+
"React": "vscode-icons:file-type-reactjs",
|
|
273
|
+
"next": "vscode-icons:file-type-light-next",
|
|
274
|
+
"Next": "vscode-icons:file-type-light-next",
|
|
275
|
+
"Nextjs": "vscode-icons:file-type-light-next",
|
|
276
|
+
"NextJS": "vscode-icons:file-type-light-next",
|
|
277
|
+
"nuxt": "vscode-icons:file-type-nuxt",
|
|
278
|
+
"Nuxt": "vscode-icons:file-type-nuxt",
|
|
279
|
+
"Nuxtjs": "vscode-icons:file-type-nuxt",
|
|
280
|
+
"NuxtJS": "vscode-icons:file-type-nuxt",
|
|
281
|
+
"solid": "logos:solidjs-icon",
|
|
282
|
+
"Solid": "logos:solidjs-icon",
|
|
283
|
+
"solidjs": "logos:solidjs-icon",
|
|
284
|
+
"astro": "vscode-icons:file-type-light-astro",
|
|
285
|
+
"Astro": "vscode-icons:file-type-light-astro",
|
|
286
|
+
"vitest": "vscode-icons:file-type-vitest",
|
|
287
|
+
"Vitest": "vscode-icons:file-type-vitest",
|
|
288
|
+
"playwright": "vscode-icons:file-type-playwright",
|
|
289
|
+
"Playwright": "vscode-icons:file-type-playwright",
|
|
290
|
+
"jest": "vscode-icons:file-type-jest",
|
|
291
|
+
"Jest": "vscode-icons:file-type-jest",
|
|
292
|
+
"cypress": "vscode-icons:file-type-cypress",
|
|
293
|
+
"Cypress": "vscode-icons:file-type-cypress",
|
|
294
|
+
"docker": "vscode-icons:file-type-docker",
|
|
295
|
+
"Docker": "vscode-icons:file-type-docker",
|
|
462
296
|
// TODO: code group title icons
|
|
463
297
|
// programming languages
|
|
464
|
-
html: "vscode-icons:file-type-html",
|
|
465
|
-
Html: "vscode-icons:file-type-html",
|
|
466
|
-
HTML: "vscode-icons:file-type-html",
|
|
467
|
-
javascript: "vscode-icons:file-type-js-official",
|
|
468
|
-
Javascript: "vscode-icons:file-type-js-official",
|
|
469
|
-
JavaScript: "vscode-icons:file-type-js-official",
|
|
470
|
-
js: "vscode-icons:file-type-js-official",
|
|
471
|
-
JS: "vscode-icons:file-type-js-official",
|
|
472
|
-
typescript: "vscode-icons:file-type-typescript-official",
|
|
473
|
-
Typescript: "vscode-icons:file-type-typescript-official",
|
|
474
|
-
TypeScript: "vscode-icons:file-type-typescript-official",
|
|
475
|
-
ts: "vscode-icons:file-type-typescript-official",
|
|
476
|
-
TS: "vscode-icons:file-type-typescript-official",
|
|
477
|
-
css: "vscode-icons:file-type-css",
|
|
478
|
-
CSS: "vscode-icons:file-type-css",
|
|
479
|
-
less: "vscode-icons:file-type-less",
|
|
480
|
-
Less: "vscode-icons:file-type-less",
|
|
481
|
-
scss: "vscode-icons:file-type-scss",
|
|
482
|
-
Scss: "vscode-icons:file-type-scss",
|
|
483
|
-
SCSS: "vscode-icons:file-type-scss",
|
|
484
|
-
sass: "vscode-icons:file-type-sass",
|
|
485
|
-
Sass: "vscode-icons:file-type-sass",
|
|
486
|
-
SASS: "vscode-icons:file-type-sass",
|
|
487
|
-
stylus: "vscode-icons:file-type-light-stylus",
|
|
488
|
-
Stylus: "vscode-icons:file-type-light-stylus",
|
|
489
|
-
postcss: "vscode-icons:file-type-postcss",
|
|
490
|
-
Postcss: "vscode-icons:file-type-postcss",
|
|
491
|
-
PostCSS: "vscode-icons:file-type-postcss",
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
298
|
+
"html": "vscode-icons:file-type-html",
|
|
299
|
+
"Html": "vscode-icons:file-type-html",
|
|
300
|
+
"HTML": "vscode-icons:file-type-html",
|
|
301
|
+
"javascript": "vscode-icons:file-type-js-official",
|
|
302
|
+
"Javascript": "vscode-icons:file-type-js-official",
|
|
303
|
+
"JavaScript": "vscode-icons:file-type-js-official",
|
|
304
|
+
"js": "vscode-icons:file-type-js-official",
|
|
305
|
+
"JS": "vscode-icons:file-type-js-official",
|
|
306
|
+
"typescript": "vscode-icons:file-type-typescript-official",
|
|
307
|
+
"Typescript": "vscode-icons:file-type-typescript-official",
|
|
308
|
+
"TypeScript": "vscode-icons:file-type-typescript-official",
|
|
309
|
+
"ts": "vscode-icons:file-type-typescript-official",
|
|
310
|
+
"TS": "vscode-icons:file-type-typescript-official",
|
|
311
|
+
"css": "vscode-icons:file-type-css",
|
|
312
|
+
"CSS": "vscode-icons:file-type-css",
|
|
313
|
+
"less": "vscode-icons:file-type-less",
|
|
314
|
+
"Less": "vscode-icons:file-type-less",
|
|
315
|
+
"scss": "vscode-icons:file-type-scss",
|
|
316
|
+
"Scss": "vscode-icons:file-type-scss",
|
|
317
|
+
"SCSS": "vscode-icons:file-type-scss",
|
|
318
|
+
"sass": "vscode-icons:file-type-sass",
|
|
319
|
+
"Sass": "vscode-icons:file-type-sass",
|
|
320
|
+
"SASS": "vscode-icons:file-type-sass",
|
|
321
|
+
"stylus": "vscode-icons:file-type-light-stylus",
|
|
322
|
+
"Stylus": "vscode-icons:file-type-light-stylus",
|
|
323
|
+
"postcss": "vscode-icons:file-type-postcss",
|
|
324
|
+
"Postcss": "vscode-icons:file-type-postcss",
|
|
325
|
+
"PostCSS": "vscode-icons:file-type-postcss",
|
|
326
|
+
"sh": "vscode-icons:file-type-shell",
|
|
327
|
+
"shell": "vscode-icons:file-type-shell",
|
|
328
|
+
"Shell": "vscode-icons:file-type-shell",
|
|
329
|
+
"bash": "vscode-icons:file-type-shell",
|
|
330
|
+
"Bash": "vscode-icons:file-type-shell",
|
|
331
|
+
"java": "vscode-icons:file-type-java",
|
|
332
|
+
"Java": "vscode-icons:file-type-java",
|
|
333
|
+
"JAVA": "vscode-icons:file-type-java",
|
|
334
|
+
"php": "vscode-icons:file-type-php3",
|
|
335
|
+
"PHP": "vscode-icons:file-type-php3",
|
|
336
|
+
"c": "vscode-icons:file-type-c",
|
|
337
|
+
"C": "vscode-icons:file-type-c",
|
|
338
|
+
"python": "vscode-icons:file-type-python",
|
|
339
|
+
"Python": "vscode-icons:file-type-python",
|
|
340
|
+
"kotlin": "vscode-icons:file-type-kotlin",
|
|
341
|
+
"Kotlin": "vscode-icons:file-type-kotlin",
|
|
342
|
+
"go": "vscode-icons:file-type-go-gopher",
|
|
343
|
+
"golang": "vscode-icons:file-type-go-gopher",
|
|
344
|
+
"Go": "vscode-icons:file-type-go-gopher",
|
|
345
|
+
"GoLang": "vscode-icons:file-type-go-gopher",
|
|
346
|
+
"rust": "vscode-icons:file-type-rust",
|
|
347
|
+
"Rust": "vscode-icons:file-type-rust",
|
|
348
|
+
"zig": "vscode-icons:file-type-zig",
|
|
349
|
+
"Zig": "vscode-icons:file-type-zig",
|
|
350
|
+
"swift": "vscode-icons:file-type-swift",
|
|
351
|
+
"Swift": "vscode-icons:file-type-swift",
|
|
352
|
+
"c#": "vscode-icons:file-type-csharp",
|
|
353
|
+
"CSharp": "vscode-icons:file-type-csharp",
|
|
354
|
+
"c++": "vscode-icons:file-type-cpp",
|
|
355
|
+
"C++": "vscode-icons:file-type-cpp",
|
|
356
|
+
"ruby": "vscode-icons:file-type-ruby",
|
|
357
|
+
"Ruby": "vscode-icons:file-type-ruby",
|
|
358
|
+
"makefile": "vscode-icons:file-type-makefile",
|
|
359
|
+
"Makefile": "vscode-icons:file-type-makefile",
|
|
360
|
+
"Object-C": "vscode-icons:file-type-objectivec",
|
|
361
|
+
"object-c": "vscode-icons:file-type-objectivec",
|
|
362
|
+
"SQL": "vscode-icons:file-type-sql",
|
|
363
|
+
"sql": "vscode-icons:file-type-sql",
|
|
364
|
+
"mysql": "vscode-icons:file-type-mysql",
|
|
365
|
+
"MySQL": "vscode-icons:file-type-mysql",
|
|
366
|
+
"MySql": "vscode-icons:file-type-mysql",
|
|
367
|
+
"pgsql": "vscode-icons:file-type-pgsql",
|
|
368
|
+
"PostgreSQL": "vscode-icons:file-type-pgsql",
|
|
369
|
+
"PGSQL": "vscode-icons:file-type-pgsql",
|
|
370
|
+
"xml": "vscode-icons:file-type-xml",
|
|
371
|
+
"XML": "vscode-icons:file-type-xml",
|
|
372
|
+
"wasm": "vscode-icons:file-type-wasm",
|
|
373
|
+
"webassembly": "vscode-icons:file-type-wasm",
|
|
374
|
+
"WebAssembly": "vscode-icons:file-type-wasm",
|
|
375
|
+
"WASM": "vscode-icons:file-type-wasm",
|
|
376
|
+
"toml": "vscode-icons:file-type-light-toml",
|
|
377
|
+
"Toml": "vscode-icons:file-type-light-toml",
|
|
378
|
+
"TOML": "vscode-icons:file-type-light-toml",
|
|
379
|
+
"yaml": "vscode-icons:file-type-light-yaml",
|
|
380
|
+
"Yaml": "vscode-icons:file-type-light-yaml",
|
|
381
|
+
"YAML": "vscode-icons:file-type-light-yaml"
|
|
513
382
|
},
|
|
514
383
|
folders: {
|
|
515
384
|
"default": "vscode-icons:default-folder",
|
|
@@ -1177,7 +1046,7 @@ var definitions = {
|
|
|
1177
1046
|
}
|
|
1178
1047
|
};
|
|
1179
1048
|
|
|
1180
|
-
// src/node/
|
|
1049
|
+
// src/node/fileIcons/findIcon.ts
|
|
1181
1050
|
function getFileIcon(fileName, type2 = "file") {
|
|
1182
1051
|
const name = getFileIconName(fileName, type2);
|
|
1183
1052
|
if (!name)
|
|
@@ -1222,9 +1091,138 @@ function getFileIconTypeFromExtension(fileName) {
|
|
|
1222
1091
|
return void 0;
|
|
1223
1092
|
}
|
|
1224
1093
|
|
|
1225
|
-
// src/node/
|
|
1094
|
+
// src/node/utils/stringifyProp.ts
|
|
1095
|
+
function stringifyProp(data) {
|
|
1096
|
+
return JSON.stringify(data).replace(/'/g, "'");
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
// src/node/container/codeTabs.ts
|
|
1100
|
+
var codeTabs = (md, options = {}) => {
|
|
1101
|
+
const getIcon = (filename) => {
|
|
1102
|
+
if (options.icon === false)
|
|
1103
|
+
return void 0;
|
|
1104
|
+
const { named, extensions } = isPlainObject(options.icon) ? options.icon : {};
|
|
1105
|
+
if (named === false && definitions.named[filename])
|
|
1106
|
+
return void 0;
|
|
1107
|
+
if (extensions === false && getFileIconTypeFromExtension(filename)) {
|
|
1108
|
+
return void 0;
|
|
1109
|
+
}
|
|
1110
|
+
const hasNamed = named && named.length;
|
|
1111
|
+
const hasExt = extensions && extensions.length;
|
|
1112
|
+
if (hasNamed || hasExt) {
|
|
1113
|
+
if (hasNamed && named.includes(filename))
|
|
1114
|
+
return definitions.named[filename];
|
|
1115
|
+
if (hasExt && extensions.some((ext) => filename.endsWith(ext)))
|
|
1116
|
+
return getFileIconTypeFromExtension(filename);
|
|
1117
|
+
return void 0;
|
|
1118
|
+
}
|
|
1119
|
+
return getFileIconName(filename);
|
|
1120
|
+
};
|
|
1121
|
+
tab(md, {
|
|
1122
|
+
name: "code-tabs",
|
|
1123
|
+
tabsOpenRenderer: ({ active, data }, tokens, index) => {
|
|
1124
|
+
const { meta } = tokens[index];
|
|
1125
|
+
const titles = data.map(({ title }) => md.renderInline(title));
|
|
1126
|
+
const tabsData = data.map((item, dataIndex) => {
|
|
1127
|
+
const { id = titles[dataIndex] } = item;
|
|
1128
|
+
return { id };
|
|
1129
|
+
});
|
|
1130
|
+
const titlesContent = titles.map((title, index2) => {
|
|
1131
|
+
const icon = getIcon(title);
|
|
1132
|
+
return `<template #title${index2}="{ value, isActive }">${icon ? `<VPIcon name="${icon}"/>` : ""}<span>${title}</span></template>`;
|
|
1133
|
+
}).join("");
|
|
1134
|
+
return `<CodeTabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? "" : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id}"` : ""}>${titlesContent}`;
|
|
1135
|
+
},
|
|
1136
|
+
tabsCloseRenderer: () => `</CodeTabs>`,
|
|
1137
|
+
tabOpenRenderer: ({ index }, tokens, tokenIndex) => {
|
|
1138
|
+
let foundFence = false;
|
|
1139
|
+
for (let i = tokenIndex; i < tokens.length; i++) {
|
|
1140
|
+
const { block, type: type2 } = tokens[i];
|
|
1141
|
+
if (block) {
|
|
1142
|
+
if (type2 === "code-tabs_tab_close")
|
|
1143
|
+
break;
|
|
1144
|
+
if ((type2 === "fence" || type2 === "import_code") && !foundFence) {
|
|
1145
|
+
foundFence = true;
|
|
1146
|
+
continue;
|
|
1147
|
+
}
|
|
1148
|
+
tokens[i].type = "code_tab_empty";
|
|
1149
|
+
tokens[i].hidden = true;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
return `<template #tab${index}="{ value, isActive }">`;
|
|
1153
|
+
},
|
|
1154
|
+
tabCloseRenderer: () => `</template>`
|
|
1155
|
+
});
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1158
|
+
// src/node/container/fileTree.ts
|
|
1226
1159
|
import Token from "markdown-it/lib/token.mjs";
|
|
1160
|
+
import container2 from "markdown-it-container";
|
|
1227
1161
|
import { removeEndingSlash, removeLeadingSlash } from "vuepress/shared";
|
|
1162
|
+
var type = "file-tree";
|
|
1163
|
+
var closeType = `container_${type}_close`;
|
|
1164
|
+
var componentName = "FileTreeItem";
|
|
1165
|
+
var itemOpen = "file_tree_item_open";
|
|
1166
|
+
var itemClose = "file_tree_item_close";
|
|
1167
|
+
var RE_SIMPLE_ICON = /:simple-icon\b/;
|
|
1168
|
+
var RE_COLORED_ICON = /:colored-icon\b/;
|
|
1169
|
+
function fileTreePlugin(md, options = {}) {
|
|
1170
|
+
const getIcon = (filename, type2, mode) => {
|
|
1171
|
+
mode ||= options.icon || "colored";
|
|
1172
|
+
if (mode === "simple")
|
|
1173
|
+
return type2 === "folder" ? defaultFolder : defaultFile;
|
|
1174
|
+
return getFileIcon(filename, type2);
|
|
1175
|
+
};
|
|
1176
|
+
const validate = (info) => info.trim().startsWith(type);
|
|
1177
|
+
const render = (tokens, idx) => {
|
|
1178
|
+
const mode = getFileIconMode(tokens[idx].info);
|
|
1179
|
+
if (tokens[idx].nesting === 1) {
|
|
1180
|
+
const hasRes = [];
|
|
1181
|
+
for (let i = idx + 1; !(tokens[i].nesting === -1 && tokens[i].type === closeType); ++i) {
|
|
1182
|
+
const token = tokens[i];
|
|
1183
|
+
if (token.type === "list_item_open") {
|
|
1184
|
+
const result = resolveTreeNodeInfo(tokens, token, i);
|
|
1185
|
+
if (result) {
|
|
1186
|
+
hasRes.push(token.level);
|
|
1187
|
+
const [info, inline] = result;
|
|
1188
|
+
const { filename, type: type2, expanded, empty } = info;
|
|
1189
|
+
const icon = getIcon(filename, type2, mode);
|
|
1190
|
+
token.type = itemOpen;
|
|
1191
|
+
token.tag = componentName;
|
|
1192
|
+
token.attrSet("type", type2);
|
|
1193
|
+
token.attrSet(":expanded", expanded ? "true" : "false");
|
|
1194
|
+
token.attrSet(":empty", empty ? "true" : "false");
|
|
1195
|
+
updateInlineToken(inline, info, icon);
|
|
1196
|
+
} else {
|
|
1197
|
+
hasRes.push(-1);
|
|
1198
|
+
}
|
|
1199
|
+
} else if (token.type === "list_item_close") {
|
|
1200
|
+
if (token.level === hasRes.pop()) {
|
|
1201
|
+
token.type = itemClose;
|
|
1202
|
+
token.tag = componentName;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
const title = resolveTitle(tokens[idx].info);
|
|
1207
|
+
return `<div class="vp-file-tree">${title ? `<p class="vp-file-tree-title">${title}</p>` : ""}`;
|
|
1208
|
+
} else {
|
|
1209
|
+
return "</div>";
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
md.use(container2, type, { validate, render });
|
|
1213
|
+
}
|
|
1214
|
+
function getFileIconMode(info) {
|
|
1215
|
+
if (RE_SIMPLE_ICON.test(info))
|
|
1216
|
+
return "simple";
|
|
1217
|
+
if (RE_COLORED_ICON.test(info))
|
|
1218
|
+
return "colored";
|
|
1219
|
+
return void 0;
|
|
1220
|
+
}
|
|
1221
|
+
function resolveTitle(info) {
|
|
1222
|
+
info = info.trim().slice(type.length).trim();
|
|
1223
|
+
info = info.replace(RE_SIMPLE_ICON, "").replace(RE_COLORED_ICON, "");
|
|
1224
|
+
return info.trim();
|
|
1225
|
+
}
|
|
1228
1226
|
function resolveTreeNodeInfo(tokens, current, idx) {
|
|
1229
1227
|
let hasInline = false;
|
|
1230
1228
|
let hasChildren = false;
|
|
@@ -1279,17 +1277,19 @@ function updateInlineToken(inline, info, icon) {
|
|
|
1279
1277
|
if (token.content.includes(" ")) {
|
|
1280
1278
|
const [first, ...other] = token.content.split(" ");
|
|
1281
1279
|
const text = new Token("text", "", 0);
|
|
1282
|
-
text.content = first;
|
|
1280
|
+
text.content = removeEndingSlash(first);
|
|
1283
1281
|
tokens.push(text);
|
|
1284
1282
|
const comment = new Token("text", "", 0);
|
|
1285
1283
|
comment.content = other.join(" ");
|
|
1286
1284
|
children.unshift(comment);
|
|
1287
1285
|
} else {
|
|
1286
|
+
token.content = removeEndingSlash(token.content);
|
|
1288
1287
|
tokens.push(token);
|
|
1289
1288
|
}
|
|
1290
1289
|
if (!isStrongTag)
|
|
1291
1290
|
break;
|
|
1292
1291
|
} else if (token.tag === "strong") {
|
|
1292
|
+
token.content = removeEndingSlash(token.content);
|
|
1293
1293
|
tokens.push(token);
|
|
1294
1294
|
if (token.nesting === 1) {
|
|
1295
1295
|
isStrongTag = true;
|
|
@@ -1312,133 +1312,7 @@ function updateInlineToken(inline, info, icon) {
|
|
|
1312
1312
|
inline.children = tokens;
|
|
1313
1313
|
}
|
|
1314
1314
|
|
|
1315
|
-
// src/node/
|
|
1316
|
-
var type = "file-tree";
|
|
1317
|
-
var closeType = `container_${type}_close`;
|
|
1318
|
-
var componentName = "FileTreeItem";
|
|
1319
|
-
var itemOpen = "file_tree_item_open";
|
|
1320
|
-
var itemClose = "file_tree_item_close";
|
|
1321
|
-
function fileTreePlugin(md) {
|
|
1322
|
-
const validate = (info) => info.trim().startsWith(type);
|
|
1323
|
-
const render = (tokens, idx) => {
|
|
1324
|
-
if (tokens[idx].nesting === 1) {
|
|
1325
|
-
const hasRes = [];
|
|
1326
|
-
for (let i = idx + 1; !(tokens[i].nesting === -1 && tokens[i].type === closeType); ++i) {
|
|
1327
|
-
const token = tokens[i];
|
|
1328
|
-
if (token.type === "list_item_open") {
|
|
1329
|
-
const result = resolveTreeNodeInfo(tokens, token, i);
|
|
1330
|
-
if (result) {
|
|
1331
|
-
hasRes.push(token.level);
|
|
1332
|
-
const [info2, inline] = result;
|
|
1333
|
-
const { filename, type: type2, expanded, empty } = info2;
|
|
1334
|
-
const icon = getFileIcon(filename, type2);
|
|
1335
|
-
token.type = itemOpen;
|
|
1336
|
-
token.tag = componentName;
|
|
1337
|
-
token.attrSet("type", type2);
|
|
1338
|
-
token.attrSet(":expanded", expanded ? "true" : "false");
|
|
1339
|
-
token.attrSet(":empty", empty ? "true" : "false");
|
|
1340
|
-
updateInlineToken(inline, info2, icon);
|
|
1341
|
-
} else {
|
|
1342
|
-
hasRes.push(-1);
|
|
1343
|
-
}
|
|
1344
|
-
} else if (token.type === "list_item_close") {
|
|
1345
|
-
if (token.level === hasRes.pop()) {
|
|
1346
|
-
token.type = itemClose;
|
|
1347
|
-
token.tag = componentName;
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
}
|
|
1351
|
-
const info = tokens[idx].info.trim();
|
|
1352
|
-
const title = info.slice(type.length).trim();
|
|
1353
|
-
return `<div class="vp-file-tree">${title ? `<p class="vp-file-tree-title">${title}</p>` : ""}`;
|
|
1354
|
-
} else {
|
|
1355
|
-
return "</div>";
|
|
1356
|
-
}
|
|
1357
|
-
};
|
|
1358
|
-
md.use(container2, type, { validate, render });
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
|
-
// src/node/features/icons.ts
|
|
1362
|
-
var [openTag, endTag] = [":[", "]:"];
|
|
1363
|
-
function createTokenizer() {
|
|
1364
|
-
return (state, silent) => {
|
|
1365
|
-
let found = false;
|
|
1366
|
-
const max = state.posMax;
|
|
1367
|
-
const start = state.pos;
|
|
1368
|
-
if (state.src.slice(start, start + 2) !== openTag)
|
|
1369
|
-
return false;
|
|
1370
|
-
if (silent)
|
|
1371
|
-
return false;
|
|
1372
|
-
if (max - start < 5)
|
|
1373
|
-
return false;
|
|
1374
|
-
state.pos = start + 2;
|
|
1375
|
-
while (state.pos < max) {
|
|
1376
|
-
if (state.src.slice(state.pos, state.pos + 2) === endTag) {
|
|
1377
|
-
found = true;
|
|
1378
|
-
break;
|
|
1379
|
-
}
|
|
1380
|
-
state.md.inline.skipToken(state);
|
|
1381
|
-
}
|
|
1382
|
-
if (!found || start + 2 === state.pos) {
|
|
1383
|
-
state.pos = start;
|
|
1384
|
-
return false;
|
|
1385
|
-
}
|
|
1386
|
-
const content = state.src.slice(start + 2, state.pos);
|
|
1387
|
-
if (/^\s|\s$/.test(content)) {
|
|
1388
|
-
state.pos = start;
|
|
1389
|
-
return false;
|
|
1390
|
-
}
|
|
1391
|
-
state.posMax = state.pos;
|
|
1392
|
-
state.pos = start + 2;
|
|
1393
|
-
const [name, options = ""] = content.split(/\s+/);
|
|
1394
|
-
const [size, color] = options.split("/");
|
|
1395
|
-
const icon = state.push("vp_iconify_open", "VPIcon", 1);
|
|
1396
|
-
icon.markup = openTag;
|
|
1397
|
-
if (name)
|
|
1398
|
-
icon.attrSet("name", name);
|
|
1399
|
-
if (size)
|
|
1400
|
-
icon.attrSet("size", size);
|
|
1401
|
-
if (color)
|
|
1402
|
-
icon.attrSet("color", color);
|
|
1403
|
-
const close = state.push("vp_iconify_close", "VPIcon", -1);
|
|
1404
|
-
close.markup = endTag;
|
|
1405
|
-
state.pos = state.posMax + 2;
|
|
1406
|
-
state.posMax = max;
|
|
1407
|
-
return true;
|
|
1408
|
-
};
|
|
1409
|
-
}
|
|
1410
|
-
var iconsPlugin = (md) => {
|
|
1411
|
-
md.inline.ruler.before("emphasis", "iconify", createTokenizer());
|
|
1412
|
-
};
|
|
1413
|
-
|
|
1414
|
-
// src/node/features/jsfiddle.ts
|
|
1415
|
-
var jsfiddlePlugin = (md) => {
|
|
1416
|
-
createRuleBlock(md, {
|
|
1417
|
-
type: "jsfiddle",
|
|
1418
|
-
syntaxPattern: /^@\[jsfiddle([^\]]*)\]\(([^)]*)\)/,
|
|
1419
|
-
meta([, info = "", source]) {
|
|
1420
|
-
const { attrs } = resolveAttrs(info);
|
|
1421
|
-
const [user, id] = source.split("/");
|
|
1422
|
-
return {
|
|
1423
|
-
width: attrs.width ? parseRect(attrs.width) : "100%",
|
|
1424
|
-
height: attrs.height ? parseRect(attrs.height) : "400px",
|
|
1425
|
-
user,
|
|
1426
|
-
id,
|
|
1427
|
-
title: attrs.title || "JS Fiddle",
|
|
1428
|
-
tab: attrs.tab?.replace(/\s+/g, "") || "js,css,html,result",
|
|
1429
|
-
theme: attrs.theme || "dark"
|
|
1430
|
-
};
|
|
1431
|
-
},
|
|
1432
|
-
content: ({ title = "JS Fiddle", height, width, user, id, tab, theme }) => {
|
|
1433
|
-
theme = theme === "dark" ? "/dark/" : "";
|
|
1434
|
-
const link = `https://jsfiddle.net/${user}/${id}/embedded/${tab}${theme}`;
|
|
1435
|
-
const style = `width:${width};height:${height};margin:16px auto;border:none;border-radius:5px;`;
|
|
1436
|
-
return `<iframe class="js-fiddle-iframe-wrapper" style="${style}" title="${title}" src="${link}" allowfullscreen="true" allowpaymentrequest="true"></iframe>`;
|
|
1437
|
-
}
|
|
1438
|
-
});
|
|
1439
|
-
};
|
|
1440
|
-
|
|
1441
|
-
// src/node/features/langRepl.ts
|
|
1315
|
+
// src/node/container/langRepl.ts
|
|
1442
1316
|
import container3 from "markdown-it-container";
|
|
1443
1317
|
import { fs as fs2, getDirname, path as path2 } from "vuepress/utils";
|
|
1444
1318
|
var RE_INFO = /^(#editable)?(.*)$/;
|
|
@@ -1505,92 +1379,271 @@ async function read(file) {
|
|
|
1505
1379
|
return void 0;
|
|
1506
1380
|
}
|
|
1507
1381
|
|
|
1508
|
-
// src/node/
|
|
1509
|
-
import {
|
|
1510
|
-
var
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
const
|
|
1382
|
+
// src/node/container/tabs.ts
|
|
1383
|
+
import { tab as tab2 } from "@mdit/plugin-tab";
|
|
1384
|
+
var tabs = (md) => {
|
|
1385
|
+
tab2(md, {
|
|
1386
|
+
name: "tabs",
|
|
1387
|
+
tabsOpenRenderer: ({ active, data }, tokens, index) => {
|
|
1388
|
+
const { meta } = tokens[index];
|
|
1389
|
+
const titles = data.map(({ title }) => md.renderInline(title));
|
|
1390
|
+
const tabsData = data.map((item, dataIndex) => {
|
|
1391
|
+
const { id = titles[dataIndex] } = item;
|
|
1392
|
+
return { id };
|
|
1393
|
+
});
|
|
1394
|
+
return `<Tabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? "" : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id}"` : ""}>
|
|
1395
|
+
${titles.map(
|
|
1396
|
+
(title, titleIndex) => `<template #title${titleIndex}="{ value, isActive }">${title}</template>`
|
|
1397
|
+
).join("")}`;
|
|
1398
|
+
},
|
|
1399
|
+
tabsCloseRenderer: () => `</Tabs>`,
|
|
1400
|
+
tabOpenRenderer: ({ index }) => `<template #tab${index}="{ value, isActive }">`,
|
|
1401
|
+
tabCloseRenderer: () => `</template>`
|
|
1402
|
+
});
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
// src/node/container/index.ts
|
|
1406
|
+
async function containerPlugin(app, md, options) {
|
|
1407
|
+
alignPlugin(md);
|
|
1408
|
+
tabs(md);
|
|
1409
|
+
codeTabs(md, options.codeTabs);
|
|
1410
|
+
if (options.repl)
|
|
1411
|
+
await langReplPlugin(app, md, options.repl);
|
|
1412
|
+
if (options.fileTree) {
|
|
1413
|
+
fileTreePlugin(md, isPlainObject2(options.fileTree) ? options.fileTree : {});
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
// src/node/embed/caniuse.ts
|
|
1418
|
+
import container4 from "markdown-it-container";
|
|
1419
|
+
import { customAlphabet } from "nanoid";
|
|
1420
|
+
|
|
1421
|
+
// src/node/embed/createEmbedRuleBlock.ts
|
|
1422
|
+
function createEmbedRuleBlock(md, {
|
|
1423
|
+
type: type2,
|
|
1424
|
+
name = type2,
|
|
1425
|
+
syntaxPattern,
|
|
1426
|
+
beforeName = "import_code",
|
|
1427
|
+
ruleOptions = { alt: ["paragraph", "reference", "blockquote", "list"] },
|
|
1428
|
+
meta,
|
|
1429
|
+
content
|
|
1430
|
+
}) {
|
|
1431
|
+
const MIN_LENGTH = type2.length + 5;
|
|
1432
|
+
const START_CODES = [64, 91, ...type2.split("").map((c) => c.charCodeAt(0))];
|
|
1433
|
+
md.block.ruler.before(
|
|
1434
|
+
beforeName,
|
|
1435
|
+
name,
|
|
1436
|
+
(state, startLine, endLine, silent) => {
|
|
1437
|
+
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1438
|
+
const max = state.eMarks[startLine];
|
|
1439
|
+
if (pos + MIN_LENGTH > max)
|
|
1440
|
+
return false;
|
|
1441
|
+
for (let i = 0; i < START_CODES.length; i += 1) {
|
|
1442
|
+
if (state.src.charCodeAt(pos + i) !== START_CODES[i])
|
|
1443
|
+
return false;
|
|
1444
|
+
}
|
|
1445
|
+
const match = state.src.slice(pos, max).match(syntaxPattern);
|
|
1446
|
+
if (!match)
|
|
1447
|
+
return false;
|
|
1448
|
+
if (silent)
|
|
1449
|
+
return true;
|
|
1450
|
+
const token = state.push(name, "", 0);
|
|
1451
|
+
token.meta = meta(match);
|
|
1452
|
+
token.map = [startLine, startLine + 1];
|
|
1453
|
+
state.line = startLine + 1;
|
|
1454
|
+
return true;
|
|
1455
|
+
},
|
|
1456
|
+
ruleOptions
|
|
1457
|
+
);
|
|
1458
|
+
md.renderer.rules[name] = (tokens, index) => {
|
|
1459
|
+
const token = tokens[index];
|
|
1460
|
+
token.content = content(token.meta);
|
|
1461
|
+
return token.content;
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
// src/node/embed/caniuse.ts
|
|
1466
|
+
var nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 5);
|
|
1467
|
+
var UNDERLINE_RE = /_+/g;
|
|
1468
|
+
var caniusePlugin = (md, { mode: defaultMode = "embed" } = {}) => {
|
|
1469
|
+
createEmbedRuleBlock(md, {
|
|
1470
|
+
type: "caniuse",
|
|
1471
|
+
syntaxPattern: /^@\[caniuse\s*(embed|image)?(?:\{([0-9,\-]*)\})?\]\(([^)]*)\)/,
|
|
1472
|
+
meta: ([, mode, versions = "", feature]) => ({
|
|
1473
|
+
feature,
|
|
1474
|
+
mode: mode || defaultMode,
|
|
1475
|
+
versions
|
|
1476
|
+
}),
|
|
1477
|
+
content: (meta) => resolveCanIUse(meta)
|
|
1478
|
+
});
|
|
1479
|
+
};
|
|
1480
|
+
function legacyCaniuse(md, { mode = "embed" } = {}) {
|
|
1481
|
+
const modeMap = ["image", "embed"];
|
|
1482
|
+
const isMode = (mode2) => modeMap.includes(mode2);
|
|
1483
|
+
mode = isMode(mode) ? mode : modeMap[0];
|
|
1484
|
+
const type2 = "caniuse";
|
|
1485
|
+
const validateReg = new RegExp(`^${type2}`);
|
|
1486
|
+
const validate = (info) => {
|
|
1487
|
+
return validateReg.test(info.trim());
|
|
1488
|
+
};
|
|
1489
|
+
const render = (tokens, index) => {
|
|
1490
|
+
const token = tokens[index];
|
|
1491
|
+
if (token.nesting === 1) {
|
|
1492
|
+
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
1493
|
+
const feature = info.split(/\s+/)[0];
|
|
1494
|
+
const versions = info.match(/\{(.*)\}/)?.[1] || "";
|
|
1495
|
+
return feature ? resolveCanIUse({ feature, mode, versions }) : "";
|
|
1496
|
+
} else {
|
|
1497
|
+
return "";
|
|
1498
|
+
}
|
|
1499
|
+
};
|
|
1500
|
+
md.use(container4, type2, { validate, render });
|
|
1501
|
+
}
|
|
1502
|
+
function resolveCanIUse({ feature, mode, versions }) {
|
|
1503
|
+
if (!feature)
|
|
1504
|
+
return "";
|
|
1505
|
+
if (mode === "image") {
|
|
1506
|
+
const link = "https://caniuse.bitsofco.de/image/";
|
|
1507
|
+
const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`;
|
|
1508
|
+
return `<ClientOnly><p><picture>
|
|
1509
|
+
<source type="image/webp" srcset="${link}${feature}.webp">
|
|
1510
|
+
<source type="image/png" srcset="${link}${feature}.png">
|
|
1511
|
+
<img src="${link}${feature}.jpg" alt="${alt}" width="100%">
|
|
1512
|
+
</picture></p></ClientOnly>`;
|
|
1513
|
+
}
|
|
1514
|
+
feature = feature.replace(UNDERLINE_RE, "_");
|
|
1515
|
+
const { past, future } = resolveVersions(versions);
|
|
1516
|
+
const meta = nanoid();
|
|
1517
|
+
return `<CanIUseViewer feature="${feature}" meta="${meta}" past="${past}" future="${future}" />`;
|
|
1518
|
+
}
|
|
1519
|
+
function resolveVersions(versions) {
|
|
1520
|
+
if (!versions)
|
|
1521
|
+
return { past: 2, future: 1 };
|
|
1522
|
+
const list = versions.split(",").map((v) => Number(v.trim())).filter((v) => !Number.isNaN(v) && v >= -5 && v <= 3);
|
|
1523
|
+
list.push(0);
|
|
1524
|
+
const uniq = [...new Set(list)].sort((a, b) => b - a);
|
|
1525
|
+
return {
|
|
1526
|
+
future: uniq[0],
|
|
1527
|
+
past: Math.abs(uniq[uniq.length - 1])
|
|
1528
|
+
};
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
// src/node/utils/parseRect.ts
|
|
1532
|
+
function parseRect(str, unit = "px") {
|
|
1533
|
+
if (Number.parseFloat(str) === Number(str))
|
|
1534
|
+
return `${str}${unit}`;
|
|
1535
|
+
return str;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
// src/node/embed/code/codepen.ts
|
|
1539
|
+
var CODEPEN_LINK = "https://codepen.io/";
|
|
1540
|
+
var codepenPlugin = (md) => {
|
|
1541
|
+
createEmbedRuleBlock(md, {
|
|
1542
|
+
type: "codepen",
|
|
1543
|
+
syntaxPattern: /^@\[codepen([^\]]*)\]\(([^)]*)\)/,
|
|
1544
|
+
meta: ([, info = "", source = ""]) => {
|
|
1545
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1546
|
+
const [user, slash] = source.split("/");
|
|
1517
1547
|
return {
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1548
|
+
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
1549
|
+
height: attrs2.height ? parseRect(attrs2.height) : "400px",
|
|
1550
|
+
user,
|
|
1551
|
+
slash,
|
|
1552
|
+
title: attrs2.title,
|
|
1553
|
+
preview: attrs2.preview,
|
|
1554
|
+
editable: attrs2.editable,
|
|
1555
|
+
tab: attrs2.tab ?? "result",
|
|
1556
|
+
theme: attrs2.theme
|
|
1526
1557
|
};
|
|
1527
1558
|
},
|
|
1528
|
-
content(
|
|
1529
|
-
|
|
1559
|
+
content: (meta) => {
|
|
1560
|
+
const { title = "Codepen", height, width } = meta;
|
|
1561
|
+
const params = new URLSearchParams();
|
|
1562
|
+
if (meta.editable) {
|
|
1563
|
+
params.set("editable", "true");
|
|
1564
|
+
}
|
|
1565
|
+
if (meta.tab) {
|
|
1566
|
+
params.set("default-tab", meta.tab);
|
|
1567
|
+
}
|
|
1568
|
+
if (meta.theme) {
|
|
1569
|
+
params.set("theme-id", meta.theme);
|
|
1570
|
+
}
|
|
1571
|
+
const middle = meta.preview ? "/embed/preview/" : "/embed/";
|
|
1572
|
+
const link = `${CODEPEN_LINK}${meta.user}${middle}${meta.slash}?${params.toString()}`;
|
|
1573
|
+
const style = `width:${width};height:${height};margin:16px auto;border-radius:5px;`;
|
|
1574
|
+
return `<iframe class="code-pen-iframe-wrapper" src="${link}" title="${title}" style="${style}" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">See the Pen <a href="${CODEPEN_LINK}${meta.user}/pen/${meta.slash}">${title}</a> by ${meta.user} (<a href="${CODEPEN_LINK}${meta.user}">@${meta.user}</a>) on <a href="${CODEPEN_LINK}">CodePen</a>.</iframe>`;
|
|
1530
1575
|
}
|
|
1531
1576
|
});
|
|
1532
1577
|
};
|
|
1533
1578
|
|
|
1534
|
-
// src/node/
|
|
1535
|
-
var
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
return
|
|
1579
|
+
// src/node/embed/code/codeSandbox.ts
|
|
1580
|
+
var codeSandboxPlugin = (md) => {
|
|
1581
|
+
createEmbedRuleBlock(md, {
|
|
1582
|
+
type: "codesandbox",
|
|
1583
|
+
syntaxPattern: /^@\[codesandbox(?:\s+(embed|button))?([^\]]*)\]\(([^)]*)\)/,
|
|
1584
|
+
meta([, type2, info = "", source = ""]) {
|
|
1585
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1586
|
+
const [profile, filepath2 = ""] = source.split("#");
|
|
1587
|
+
const [user, id] = profile.includes("/") ? profile.split("/") : ["", profile];
|
|
1588
|
+
return {
|
|
1589
|
+
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
1590
|
+
height: attrs2.height ? parseRect(attrs2.height) : "500px",
|
|
1591
|
+
user,
|
|
1592
|
+
id,
|
|
1593
|
+
title: attrs2.title ?? "",
|
|
1594
|
+
console: attrs2.console ?? false,
|
|
1595
|
+
navbar: attrs2.navbar ?? true,
|
|
1596
|
+
layout: attrs2.layout ?? "",
|
|
1597
|
+
type: type2 || "embed",
|
|
1598
|
+
filepath: filepath2
|
|
1599
|
+
};
|
|
1600
|
+
},
|
|
1601
|
+
content({ title, height, width, user, id, type: type2, filepath: filepath2, console, navbar, layout }) {
|
|
1602
|
+
return `<CodeSandboxViewer title="${title}" height="${height}" width="${width}" user="${user}" id="${id}" type="${type2}" filepath="${filepath2}" :console=${console} :navbar=${navbar} layout="${layout}" />`;
|
|
1558
1603
|
}
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1604
|
+
});
|
|
1605
|
+
};
|
|
1606
|
+
|
|
1607
|
+
// src/node/embed/code/jsfiddle.ts
|
|
1608
|
+
var jsfiddlePlugin = (md) => {
|
|
1609
|
+
createEmbedRuleBlock(md, {
|
|
1610
|
+
type: "jsfiddle",
|
|
1611
|
+
syntaxPattern: /^@\[jsfiddle([^\]]*)\]\(([^)]*)\)/,
|
|
1612
|
+
meta([, info = "", source]) {
|
|
1613
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1614
|
+
const [user, id] = source.split("/");
|
|
1615
|
+
return {
|
|
1616
|
+
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
1617
|
+
height: attrs2.height ? parseRect(attrs2.height) : "400px",
|
|
1618
|
+
user,
|
|
1619
|
+
id,
|
|
1620
|
+
title: attrs2.title || "JS Fiddle",
|
|
1621
|
+
tab: attrs2.tab?.replace(/\s+/g, "") || "js,css,html,result",
|
|
1622
|
+
theme: attrs2.theme || "dark"
|
|
1623
|
+
};
|
|
1624
|
+
},
|
|
1625
|
+
content: ({ title = "JS Fiddle", height, width, user, id, tab: tab3, theme }) => {
|
|
1626
|
+
theme = theme === "dark" ? "/dark/" : "";
|
|
1627
|
+
const link = `https://jsfiddle.net/${user}/${id}/embedded/${tab3}${theme}`;
|
|
1628
|
+
const style = `width:${width};height:${height};margin:16px auto;border:none;border-radius:5px;`;
|
|
1629
|
+
return `<iframe class="js-fiddle-iframe-wrapper" style="${style}" title="${title}" src="${link}" allowfullscreen="true" allowpaymentrequest="true"></iframe>`;
|
|
1563
1630
|
}
|
|
1564
|
-
|
|
1565
|
-
state.pos = start + 2;
|
|
1566
|
-
const open = state.push("plot_open", "Plot", 1);
|
|
1567
|
-
open.markup = openTag2;
|
|
1568
|
-
const text = state.push("text", "", 0);
|
|
1569
|
-
text.content = content;
|
|
1570
|
-
const close = state.push("plot_close", "Plot", -1);
|
|
1571
|
-
close.markup = endTag2;
|
|
1572
|
-
state.pos = state.posMax + 2;
|
|
1573
|
-
state.posMax = max;
|
|
1574
|
-
return true;
|
|
1575
|
-
};
|
|
1576
|
-
}
|
|
1577
|
-
var plotPlugin = (md) => {
|
|
1578
|
-
md.inline.ruler.before("emphasis", "plot", createTokenizer2());
|
|
1631
|
+
});
|
|
1579
1632
|
};
|
|
1580
1633
|
|
|
1581
|
-
// src/node/
|
|
1634
|
+
// src/node/embed/code/replit.ts
|
|
1582
1635
|
var replitPlugin = (md) => {
|
|
1583
|
-
|
|
1636
|
+
createEmbedRuleBlock(md, {
|
|
1584
1637
|
type: "replit",
|
|
1585
1638
|
syntaxPattern: /^@\[replit([^\]]*)\]\(([^)]*)\)/,
|
|
1586
1639
|
meta: ([, info = "", source = ""]) => {
|
|
1587
|
-
const { attrs } = resolveAttrs(info);
|
|
1640
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1588
1641
|
return {
|
|
1589
|
-
width:
|
|
1590
|
-
height:
|
|
1642
|
+
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
1643
|
+
height: attrs2.height ? parseRect(attrs2.height) : "450px",
|
|
1591
1644
|
source: source.startsWith("@") ? source : `@${source}`,
|
|
1592
|
-
title:
|
|
1593
|
-
theme:
|
|
1645
|
+
title: attrs2.title,
|
|
1646
|
+
theme: attrs2.theme || ""
|
|
1594
1647
|
};
|
|
1595
1648
|
},
|
|
1596
1649
|
content({ title, height, width, source, theme }) {
|
|
@@ -1599,7 +1652,33 @@ var replitPlugin = (md) => {
|
|
|
1599
1652
|
});
|
|
1600
1653
|
};
|
|
1601
1654
|
|
|
1602
|
-
// src/node/
|
|
1655
|
+
// src/node/embed/pdf.ts
|
|
1656
|
+
import { path as path3 } from "vuepress/utils";
|
|
1657
|
+
var pdfPlugin = (md) => {
|
|
1658
|
+
createEmbedRuleBlock(md, {
|
|
1659
|
+
type: "pdf",
|
|
1660
|
+
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
1661
|
+
syntaxPattern: /^@\[pdf(?:\s+(\d+))?([^\]]*)\]\(([^)]*)\)/,
|
|
1662
|
+
meta([, page, info = "", src = ""]) {
|
|
1663
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1664
|
+
return {
|
|
1665
|
+
src,
|
|
1666
|
+
page: +page || 1,
|
|
1667
|
+
noToolbar: Boolean(attrs2.noToolbar ?? false),
|
|
1668
|
+
zoom: +attrs2.zoom || 50,
|
|
1669
|
+
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
1670
|
+
height: attrs2.height ? parseRect(attrs2.height) : "",
|
|
1671
|
+
ratio: attrs2.ratio ? parseRect(attrs2.ratio) : "",
|
|
1672
|
+
title: path3.basename(src || "")
|
|
1673
|
+
};
|
|
1674
|
+
},
|
|
1675
|
+
content({ title, src, page, noToolbar, width, height, ratio, zoom }) {
|
|
1676
|
+
return `<PDFViewer src="${src}" title="${title}" :page="${page}" :no-toolbar="${noToolbar}" width="${width}" height="${height}" ratio="${ratio}" :zoom="${zoom}" />`;
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1679
|
+
};
|
|
1680
|
+
|
|
1681
|
+
// src/node/embed/video/bilibili.ts
|
|
1603
1682
|
import { URLSearchParams as URLSearchParams2 } from "node:url";
|
|
1604
1683
|
|
|
1605
1684
|
// src/node/utils/timeToSeconds.ts
|
|
@@ -1612,16 +1691,16 @@ function timeToSeconds(time) {
|
|
|
1612
1691
|
return s + m * 60 + h * 3600;
|
|
1613
1692
|
}
|
|
1614
1693
|
|
|
1615
|
-
// src/node/
|
|
1694
|
+
// src/node/embed/video/bilibili.ts
|
|
1616
1695
|
var BILIBILI_LINK = "https://player.bilibili.com/player.html";
|
|
1617
1696
|
var bilibiliPlugin = (md) => {
|
|
1618
|
-
|
|
1697
|
+
createEmbedRuleBlock(md, {
|
|
1619
1698
|
type: "bilibili",
|
|
1620
1699
|
name: "video_bilibili",
|
|
1621
1700
|
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
1622
1701
|
syntaxPattern: /^@\[bilibili(?:\s+p(\d+))?([^\]]*)\]\(([^)]*)\)/,
|
|
1623
1702
|
meta([, page, info = "", source = ""]) {
|
|
1624
|
-
const { attrs } = resolveAttrs(info);
|
|
1703
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1625
1704
|
const ids = source.trim().split(/\s+/);
|
|
1626
1705
|
const bvid = ids.find((id) => id.startsWith("BV"));
|
|
1627
1706
|
const [aid, cid] = ids.filter((id) => !id.startsWith("BV"));
|
|
@@ -1630,12 +1709,12 @@ var bilibiliPlugin = (md) => {
|
|
|
1630
1709
|
bvid,
|
|
1631
1710
|
aid,
|
|
1632
1711
|
cid,
|
|
1633
|
-
autoplay:
|
|
1634
|
-
time: timeToSeconds(
|
|
1635
|
-
title:
|
|
1636
|
-
width:
|
|
1637
|
-
height:
|
|
1638
|
-
ratio:
|
|
1712
|
+
autoplay: attrs2.autoplay ?? false,
|
|
1713
|
+
time: timeToSeconds(attrs2.time),
|
|
1714
|
+
title: attrs2.title,
|
|
1715
|
+
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
1716
|
+
height: attrs2.height ? parseRect(attrs2.height) : "",
|
|
1717
|
+
ratio: attrs2.ratio ? parseRect(attrs2.ratio) : ""
|
|
1639
1718
|
};
|
|
1640
1719
|
},
|
|
1641
1720
|
content(meta) {
|
|
@@ -1662,26 +1741,26 @@ var bilibiliPlugin = (md) => {
|
|
|
1662
1741
|
});
|
|
1663
1742
|
};
|
|
1664
1743
|
|
|
1665
|
-
// src/node/
|
|
1744
|
+
// src/node/embed/video/youtube.ts
|
|
1666
1745
|
import { URLSearchParams as URLSearchParams3 } from "node:url";
|
|
1667
1746
|
var YOUTUBE_LINK = "https://www.youtube.com/embed/";
|
|
1668
1747
|
var youtubePlugin = (md) => {
|
|
1669
|
-
|
|
1748
|
+
createEmbedRuleBlock(md, {
|
|
1670
1749
|
type: "youtube",
|
|
1671
1750
|
name: "video_youtube",
|
|
1672
1751
|
syntaxPattern: /^@\[youtube([^\]]*)\]\(([^)]*)\)/,
|
|
1673
1752
|
meta([, info = "", id = ""]) {
|
|
1674
|
-
const { attrs } = resolveAttrs(info);
|
|
1753
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1675
1754
|
return {
|
|
1676
1755
|
id,
|
|
1677
|
-
autoplay:
|
|
1678
|
-
loop:
|
|
1679
|
-
start: timeToSeconds(
|
|
1680
|
-
end: timeToSeconds(
|
|
1681
|
-
title:
|
|
1682
|
-
width:
|
|
1683
|
-
height:
|
|
1684
|
-
ratio:
|
|
1756
|
+
autoplay: attrs2.autoplay ?? false,
|
|
1757
|
+
loop: attrs2.loop ?? false,
|
|
1758
|
+
start: timeToSeconds(attrs2.start),
|
|
1759
|
+
end: timeToSeconds(attrs2.end),
|
|
1760
|
+
title: attrs2.title,
|
|
1761
|
+
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
1762
|
+
height: attrs2.height ? parseRect(attrs2.height) : "",
|
|
1763
|
+
ratio: attrs2.ratio ? parseRect(attrs2.ratio) : ""
|
|
1685
1764
|
};
|
|
1686
1765
|
},
|
|
1687
1766
|
content(meta) {
|
|
@@ -1704,6 +1783,157 @@ var youtubePlugin = (md) => {
|
|
|
1704
1783
|
});
|
|
1705
1784
|
};
|
|
1706
1785
|
|
|
1786
|
+
// src/node/embed/index.ts
|
|
1787
|
+
function embedSyntaxPlugin(md, options) {
|
|
1788
|
+
if (options.caniuse) {
|
|
1789
|
+
const caniuse = options.caniuse === true ? {} : options.caniuse;
|
|
1790
|
+
md.use(caniusePlugin, caniuse);
|
|
1791
|
+
legacyCaniuse(md, caniuse);
|
|
1792
|
+
}
|
|
1793
|
+
if (options.pdf) {
|
|
1794
|
+
md.use(pdfPlugin);
|
|
1795
|
+
}
|
|
1796
|
+
if (options.bilibili) {
|
|
1797
|
+
md.use(bilibiliPlugin);
|
|
1798
|
+
}
|
|
1799
|
+
if (options.youtube) {
|
|
1800
|
+
md.use(youtubePlugin);
|
|
1801
|
+
}
|
|
1802
|
+
if (options.codepen) {
|
|
1803
|
+
md.use(codepenPlugin);
|
|
1804
|
+
}
|
|
1805
|
+
if (options.replit) {
|
|
1806
|
+
md.use(replitPlugin);
|
|
1807
|
+
}
|
|
1808
|
+
if (options.codeSandbox) {
|
|
1809
|
+
md.use(codeSandboxPlugin);
|
|
1810
|
+
}
|
|
1811
|
+
if (options.jsfiddle) {
|
|
1812
|
+
md.use(jsfiddlePlugin);
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
// src/node/inline/index.ts
|
|
1817
|
+
import { attrs } from "@mdit/plugin-attrs";
|
|
1818
|
+
import { footnote } from "@mdit/plugin-footnote";
|
|
1819
|
+
import { mark } from "@mdit/plugin-mark";
|
|
1820
|
+
import { sub } from "@mdit/plugin-sub";
|
|
1821
|
+
import { sup } from "@mdit/plugin-sup";
|
|
1822
|
+
import { tasklist } from "@mdit/plugin-tasklist";
|
|
1823
|
+
import { isPlainObject as isPlainObject3 } from "@vuepress/helper";
|
|
1824
|
+
|
|
1825
|
+
// src/node/inline/icons.ts
|
|
1826
|
+
var [openTag, endTag] = [":[", "]:"];
|
|
1827
|
+
var iconsPlugin = (md, options = {}) => md.inline.ruler.before("emphasis", "iconify", createTokenizer(options));
|
|
1828
|
+
function createTokenizer(options) {
|
|
1829
|
+
return (state, silent) => {
|
|
1830
|
+
let found = false;
|
|
1831
|
+
const max = state.posMax;
|
|
1832
|
+
const start = state.pos;
|
|
1833
|
+
if (state.src.slice(start, start + 2) !== openTag)
|
|
1834
|
+
return false;
|
|
1835
|
+
if (silent)
|
|
1836
|
+
return false;
|
|
1837
|
+
if (max - start < 5)
|
|
1838
|
+
return false;
|
|
1839
|
+
state.pos = start + 2;
|
|
1840
|
+
while (state.pos < max) {
|
|
1841
|
+
if (state.src.slice(state.pos, state.pos + 2) === endTag) {
|
|
1842
|
+
found = true;
|
|
1843
|
+
break;
|
|
1844
|
+
}
|
|
1845
|
+
state.md.inline.skipToken(state);
|
|
1846
|
+
}
|
|
1847
|
+
if (!found || start + 2 === state.pos) {
|
|
1848
|
+
state.pos = start;
|
|
1849
|
+
return false;
|
|
1850
|
+
}
|
|
1851
|
+
const content = state.src.slice(start + 2, state.pos);
|
|
1852
|
+
if (/^\s|\s$/.test(content)) {
|
|
1853
|
+
state.pos = start;
|
|
1854
|
+
return false;
|
|
1855
|
+
}
|
|
1856
|
+
state.posMax = state.pos;
|
|
1857
|
+
state.pos = start + 2;
|
|
1858
|
+
const [name, opt = ""] = content.split(/\s+/);
|
|
1859
|
+
const [size = options.size, color = options.color] = opt.split("/");
|
|
1860
|
+
const icon = state.push("vp_iconify_open", "VPIcon", 1);
|
|
1861
|
+
icon.markup = openTag;
|
|
1862
|
+
if (name)
|
|
1863
|
+
icon.attrSet("name", name);
|
|
1864
|
+
if (size)
|
|
1865
|
+
icon.attrSet("size", String(size));
|
|
1866
|
+
if (color)
|
|
1867
|
+
icon.attrSet("color", color);
|
|
1868
|
+
const close = state.push("vp_iconify_close", "VPIcon", -1);
|
|
1869
|
+
close.markup = endTag;
|
|
1870
|
+
state.pos = state.posMax + 2;
|
|
1871
|
+
state.posMax = max;
|
|
1872
|
+
return true;
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
// src/node/inline/plot.ts
|
|
1877
|
+
var [openTag2, endTag2] = ["!!", "!!"];
|
|
1878
|
+
var plotPlugin = (md) => md.inline.ruler.before("emphasis", "plot", createTokenizer2());
|
|
1879
|
+
function createTokenizer2() {
|
|
1880
|
+
return (state, silent) => {
|
|
1881
|
+
let found = false;
|
|
1882
|
+
const max = state.posMax;
|
|
1883
|
+
const start = state.pos;
|
|
1884
|
+
if (state.src.slice(start, start + 2) !== openTag2)
|
|
1885
|
+
return false;
|
|
1886
|
+
if (silent)
|
|
1887
|
+
return false;
|
|
1888
|
+
if (max - start < 5)
|
|
1889
|
+
return false;
|
|
1890
|
+
state.pos = start + 2;
|
|
1891
|
+
while (state.pos < max) {
|
|
1892
|
+
if (state.src.slice(state.pos - 1, state.pos + 1) === endTag2) {
|
|
1893
|
+
found = true;
|
|
1894
|
+
break;
|
|
1895
|
+
}
|
|
1896
|
+
state.md.inline.skipToken(state);
|
|
1897
|
+
}
|
|
1898
|
+
if (!found || start + 2 === state.pos) {
|
|
1899
|
+
state.pos = start;
|
|
1900
|
+
return false;
|
|
1901
|
+
}
|
|
1902
|
+
const content = state.src.slice(start + 2, state.pos - 1);
|
|
1903
|
+
if (/^\s|\s$/.test(content)) {
|
|
1904
|
+
state.pos = start;
|
|
1905
|
+
return false;
|
|
1906
|
+
}
|
|
1907
|
+
state.posMax = state.pos - 1;
|
|
1908
|
+
state.pos = start + 2;
|
|
1909
|
+
const open = state.push("plot_open", "Plot", 1);
|
|
1910
|
+
open.markup = openTag2;
|
|
1911
|
+
const text = state.push("text", "", 0);
|
|
1912
|
+
text.content = content;
|
|
1913
|
+
const close = state.push("plot_close", "Plot", -1);
|
|
1914
|
+
close.markup = endTag2;
|
|
1915
|
+
state.pos = state.posMax + 2;
|
|
1916
|
+
state.posMax = max;
|
|
1917
|
+
return true;
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
// src/node/inline/index.ts
|
|
1922
|
+
function inlineSyntaxPlugin(md, options) {
|
|
1923
|
+
md.use(attrs);
|
|
1924
|
+
md.use(mark);
|
|
1925
|
+
md.use(sub);
|
|
1926
|
+
md.use(sup);
|
|
1927
|
+
md.use(footnote);
|
|
1928
|
+
md.use(tasklist);
|
|
1929
|
+
if (options.icons) {
|
|
1930
|
+
md.use(iconsPlugin, isPlainObject3(options.icons) ? options.icons : {});
|
|
1931
|
+
}
|
|
1932
|
+
if (options.plot === true || isPlainObject3(options.plot) && options.plot.tag !== false) {
|
|
1933
|
+
md.use(plotPlugin);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1707
1937
|
// src/node/prepareConfigFile.ts
|
|
1708
1938
|
import { ensureEndingSlash } from "@vuepress/helper";
|
|
1709
1939
|
import { getDirname as getDirname2, path as path4 } from "vuepress/utils";
|
|
@@ -1715,6 +1945,10 @@ var CLIENT_FOLDER = ensureEndingSlash(
|
|
|
1715
1945
|
async function prepareConfigFile(app, options) {
|
|
1716
1946
|
const imports = /* @__PURE__ */ new Set();
|
|
1717
1947
|
const enhances = /* @__PURE__ */ new Set();
|
|
1948
|
+
imports.add(`import Tabs from '${CLIENT_FOLDER}components/Tabs.vue'`);
|
|
1949
|
+
enhances.add(`app.component('Tabs', Tabs)`);
|
|
1950
|
+
imports.add(`import CodeTabs from '${CLIENT_FOLDER}components/CodeTabs.vue'`);
|
|
1951
|
+
enhances.add(`app.component('CodeTabs', CodeTabs)`);
|
|
1718
1952
|
if (options.pdf) {
|
|
1719
1953
|
imports.add(`import PDFViewer from '${CLIENT_FOLDER}components/PDFViewer.vue'`);
|
|
1720
1954
|
enhances.add(`app.component('PDFViewer', PDFViewer)`);
|
|
@@ -1767,63 +2001,23 @@ ${Array.from(enhances.values()).map((item) => ` ${item}`).join("\n")}
|
|
|
1767
2001
|
|
|
1768
2002
|
// src/node/plugin.ts
|
|
1769
2003
|
function markdownPowerPlugin(options = {}) {
|
|
1770
|
-
return
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
addViteOptimizeDepsInclude(
|
|
1780
|
-
bundlerOptions,
|
|
1781
|
-
app,
|
|
1782
|
-
["shiki/core", "shiki/wasm"]
|
|
1783
|
-
);
|
|
1784
|
-
}
|
|
1785
|
-
},
|
|
1786
|
-
extendsMarkdown: async (md, app2) => {
|
|
1787
|
-
await imageSizePlugin(app2, md, options.imageSize);
|
|
1788
|
-
if (options.caniuse) {
|
|
1789
|
-
const caniuse = options.caniuse === true ? {} : options.caniuse;
|
|
1790
|
-
md.use(caniusePlugin, caniuse);
|
|
1791
|
-
legacyCaniuse(md, caniuse);
|
|
1792
|
-
}
|
|
1793
|
-
if (options.pdf) {
|
|
1794
|
-
md.use(pdfPlugin);
|
|
1795
|
-
}
|
|
1796
|
-
if (options.icons) {
|
|
1797
|
-
md.use(iconsPlugin);
|
|
1798
|
-
}
|
|
1799
|
-
if (options.bilibili) {
|
|
1800
|
-
md.use(bilibiliPlugin);
|
|
1801
|
-
}
|
|
1802
|
-
if (options.youtube) {
|
|
1803
|
-
md.use(youtubePlugin);
|
|
1804
|
-
}
|
|
1805
|
-
if (options.codepen) {
|
|
1806
|
-
md.use(codepenPlugin);
|
|
1807
|
-
}
|
|
1808
|
-
if (options.replit) {
|
|
1809
|
-
md.use(replitPlugin);
|
|
1810
|
-
}
|
|
1811
|
-
if (options.codeSandbox) {
|
|
1812
|
-
md.use(codeSandboxPlugin);
|
|
1813
|
-
}
|
|
1814
|
-
if (options.jsfiddle) {
|
|
1815
|
-
md.use(jsfiddlePlugin);
|
|
1816
|
-
}
|
|
1817
|
-
if (options.plot === true || typeof options.plot === "object" && options.plot.tag !== false) {
|
|
1818
|
-
md.use(plotPlugin);
|
|
1819
|
-
}
|
|
1820
|
-
if (options.repl)
|
|
1821
|
-
await langReplPlugin(app2, md, options.repl);
|
|
1822
|
-
if (options.fileTree) {
|
|
1823
|
-
fileTreePlugin(md);
|
|
1824
|
-
}
|
|
2004
|
+
return {
|
|
2005
|
+
name: "vuepress-plugin-md-power",
|
|
2006
|
+
clientConfigFile: (app) => prepareConfigFile(app, options),
|
|
2007
|
+
define: {
|
|
2008
|
+
__MD_POWER_INJECT_OPTIONS__: options
|
|
2009
|
+
},
|
|
2010
|
+
extendsBundlerOptions(bundlerOptions, app) {
|
|
2011
|
+
if (options.repl) {
|
|
2012
|
+
addViteOptimizeDepsInclude(bundlerOptions, app, ["shiki/core", "shiki/wasm"]);
|
|
1825
2013
|
}
|
|
1826
|
-
}
|
|
2014
|
+
},
|
|
2015
|
+
extendsMarkdown: async (md, app) => {
|
|
2016
|
+
embedSyntaxPlugin(md, options);
|
|
2017
|
+
inlineSyntaxPlugin(md, options);
|
|
2018
|
+
await containerPlugin(app, md, options);
|
|
2019
|
+
await imageSizePlugin(app, md, options.imageSize);
|
|
2020
|
+
}
|
|
1827
2021
|
};
|
|
1828
2022
|
}
|
|
1829
2023
|
export {
|