@slidev/cli 52.14.2 → 52.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{build-DvtR2mFf.mjs → build-BiWc4dXo.mjs} +29 -21
- package/dist/cli.mjs +15 -9
- package/dist/{export-C4evmDwN.mjs → export-Dv3OTWhO.mjs} +3 -2
- package/dist/index.mjs +3 -3
- package/dist/{resolver-B4CxEjJF.mjs → resolver-XedCEhxI.mjs} +2 -1
- package/dist/{serve-D_ugeQhq.mjs → serve-BSv6omQ6.mjs} +1 -1
- package/dist/{shared-ZIXcnTKJ.mjs → shared-DDjOjYqG.mjs} +474 -449
- package/package.json +32 -31
- package/skills/slidev/references/api-slide-hooks.md +2 -2
- package/skills/slidev/references/core-global-context.md +2 -2
- /package/skills/slidev/references/{syntax-mdc.md → syntax-comark.md} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as resolveImportPath, c as toAtFS, i as resolveEntry, n as getRoots, o as resolveImportUrl, r as isInstalledGlobally, s as resolveSourceFiles, t as createResolver } from "./resolver-
|
|
1
|
+
import { a as resolveImportPath, c as toAtFS, i as resolveEntry, n as getRoots, o as resolveImportUrl, r as isInstalledGlobally, s as resolveSourceFiles, t as createResolver } from "./resolver-XedCEhxI.mjs";
|
|
2
2
|
import { builtinModules } from "node:module";
|
|
3
3
|
import path, { basename, dirname, join, relative, resolve } from "node:path";
|
|
4
4
|
import { loadConfigFromFile, mergeConfig } from "vite";
|
|
@@ -6,7 +6,7 @@ import MarkdownExit from "markdown-exit";
|
|
|
6
6
|
import fs, { existsSync } from "node:fs";
|
|
7
7
|
import fs$1, { readFile } from "node:fs/promises";
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
|
-
import { isString, isTruthy, notNullish, objectEntries, objectMap, range, slash, uniq } from "@antfu/utils";
|
|
9
|
+
import { ensureSuffix, isString, isTruthy, notNullish, objectEntries, objectMap, range, slash, uniq } from "@antfu/utils";
|
|
10
10
|
import { bold, gray, red, white, yellow } from "ansis";
|
|
11
11
|
import { createResolve } from "mlly";
|
|
12
12
|
import { findDepPkgJsonPath } from "vitefu";
|
|
@@ -21,7 +21,8 @@ import fg from "fast-glob";
|
|
|
21
21
|
import { createDebug } from "obug";
|
|
22
22
|
import pm from "picomatch";
|
|
23
23
|
import { satisfies } from "semver";
|
|
24
|
-
import {
|
|
24
|
+
import { parseHtmlForUnheadExtraction } from "unhead/parser";
|
|
25
|
+
import { createHead, transformHtmlTemplate } from "unhead/server";
|
|
25
26
|
import { createBundledHighlighter, createSingletonShorthands } from "shiki/core";
|
|
26
27
|
import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
|
27
28
|
import { bundledLanguages, bundledThemes } from "shiki";
|
|
@@ -30,18 +31,21 @@ import MagicString from "magic-string-stack";
|
|
|
30
31
|
import Markdown from "unplugin-vue-markdown/vite";
|
|
31
32
|
import MarkdownItComark from "@comark/markdown-it";
|
|
32
33
|
import MarkdownItFootnote from "markdown-it-footnote";
|
|
33
|
-
import
|
|
34
|
-
import {
|
|
34
|
+
import MarkdownItGitHubAlerts from "markdown-it-github-alerts";
|
|
35
|
+
import { defineCodeblockTransformer } from "@slidev/types";
|
|
35
36
|
import lz from "lz-string";
|
|
36
37
|
import { toKeyedTokens } from "shiki-magic-move/core";
|
|
37
38
|
import { encode } from "plantuml-encoder";
|
|
39
|
+
import { SourceMapConsumer } from "source-map-js";
|
|
40
|
+
import { fromAsyncCodeToHtml } from "@shikijs/markdown-it/async";
|
|
38
41
|
import ServerRef from "vite-plugin-vue-server-ref";
|
|
39
42
|
import UnoCSS from "unocss/vite";
|
|
40
43
|
import { mergeConfigs, presetIcons } from "unocss";
|
|
41
44
|
import Vue from "@vitejs/plugin-vue";
|
|
42
45
|
import VueJsx from "@vitejs/plugin-vue-jsx";
|
|
43
46
|
|
|
44
|
-
//#region node/syntax/
|
|
47
|
+
//#region node/syntax/link.ts
|
|
48
|
+
const RE_DIGITS_ONLY = /^\d+$/;
|
|
45
49
|
function MarkdownItLink(md) {
|
|
46
50
|
const defaultRender = md.renderer.rules.link_open ?? ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));
|
|
47
51
|
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
|
|
@@ -49,7 +53,7 @@ function MarkdownItLink(md) {
|
|
|
49
53
|
const hrefIndex = token.attrIndex("href");
|
|
50
54
|
const attr = token.attrs?.[hrefIndex];
|
|
51
55
|
const href = attr?.[1] ?? "";
|
|
52
|
-
if ("./#".includes(href[0]) ||
|
|
56
|
+
if ("./#".includes(href[0]) || RE_DIGITS_ONLY.test(href)) {
|
|
53
57
|
token.tag = "Link";
|
|
54
58
|
attr[0] = "to";
|
|
55
59
|
for (let i = idx + 1; i < tokens.length; i++) if (tokens[i].type === "link_close") {
|
|
@@ -63,17 +67,20 @@ function MarkdownItLink(md) {
|
|
|
63
67
|
|
|
64
68
|
//#endregion
|
|
65
69
|
//#region node/utils.ts
|
|
70
|
+
const RE_WHITESPACE_ONLY = /^\s*$/;
|
|
71
|
+
const RE_QUOTED_STRING = /^(['"])(.*)\1$/;
|
|
72
|
+
const RE_WHITESPACE = /\s+/g;
|
|
66
73
|
let jiti;
|
|
67
74
|
function loadModule(absolutePath) {
|
|
68
75
|
jiti ??= createJiti(fileURLToPath(import.meta.url), { moduleCache: false });
|
|
69
76
|
return jiti.import(absolutePath);
|
|
70
77
|
}
|
|
71
78
|
function stringifyMarkdownTokens(tokens) {
|
|
72
|
-
return tokens.map((token) => token.children?.filter((t) => ["text", "code_inline"].includes(t.type) && !t.content.match(
|
|
79
|
+
return tokens.map((token) => token.children?.filter((t) => ["text", "code_inline"].includes(t.type) && !t.content.match(RE_WHITESPACE_ONLY)).map((t) => t.content.trim()).join(" ")).filter(Boolean).join(" ");
|
|
73
80
|
}
|
|
74
81
|
function generateFontParams(options) {
|
|
75
82
|
const weights = options.weights.flatMap((i) => options.italic ? [`0,${i}`, `1,${i}`] : [`${i}`]).sort().join(";");
|
|
76
|
-
return options.webfonts.map((i) => `family=${i.replace(
|
|
83
|
+
return options.webfonts.map((i) => `family=${i.replace(RE_QUOTED_STRING, "$1").replace(RE_WHITESPACE, "+")}:${options.italic ? "ital," : ""}wght@${weights}`).join("&");
|
|
77
84
|
}
|
|
78
85
|
function generateGoogleFontsUrl(options) {
|
|
79
86
|
return `https://fonts.googleapis.com/css2?${generateFontParams(options)}&display=swap`;
|
|
@@ -124,12 +131,11 @@ function getBodyJson(req) {
|
|
|
124
131
|
});
|
|
125
132
|
});
|
|
126
133
|
}
|
|
127
|
-
function makeAbsoluteImportGlob(
|
|
128
|
-
const relativeGlobs = globs.map((glob) =>
|
|
134
|
+
function makeAbsoluteImportGlob(self, globs, options = {}) {
|
|
135
|
+
const relativeGlobs = globs.map((glob) => `${slash(relative(self, glob))}`);
|
|
129
136
|
const opts = {
|
|
130
137
|
eager: true,
|
|
131
138
|
exhaustive: true,
|
|
132
|
-
base: "/",
|
|
133
139
|
...options
|
|
134
140
|
};
|
|
135
141
|
return `import.meta.glob(${JSON.stringify(relativeGlobs)}, ${JSON.stringify(opts)})`;
|
|
@@ -155,6 +161,7 @@ async function setupVitePlugins(options) {
|
|
|
155
161
|
|
|
156
162
|
//#endregion
|
|
157
163
|
//#region node/vite/compilerFlagsVue.ts
|
|
164
|
+
const RE_VUE_FILE = /\.vue(?:$|\?)/;
|
|
158
165
|
/**
|
|
159
166
|
* Replace compiler flags like `__DEV__` in Vue SFC
|
|
160
167
|
*/
|
|
@@ -163,8 +170,8 @@ function createVueCompilerFlagsPlugin(options) {
|
|
|
163
170
|
return {
|
|
164
171
|
name: "slidev:flags",
|
|
165
172
|
enforce: "pre",
|
|
166
|
-
transform: { handler(code, id) {
|
|
167
|
-
if (!
|
|
173
|
+
transform: { handler(code, id$2) {
|
|
174
|
+
if (!RE_VUE_FILE.test(id$2) && !id$2.includes("?vue&")) return;
|
|
168
175
|
const original = code;
|
|
169
176
|
define.forEach(([from, to]) => {
|
|
170
177
|
code = code.replaceAll(from, to);
|
|
@@ -176,6 +183,11 @@ function createVueCompilerFlagsPlugin(options) {
|
|
|
176
183
|
|
|
177
184
|
//#endregion
|
|
178
185
|
//#region node/vite/components.ts
|
|
186
|
+
const RE_VUE_EXT$1 = /\.vue$/;
|
|
187
|
+
const RE_VUE_QUERY_VUE$1 = /\.vue\?vue/;
|
|
188
|
+
const RE_VUE_QUERY_V$1 = /\.vue\?v=/;
|
|
189
|
+
const RE_MD_EXT$2 = /\.md$/;
|
|
190
|
+
const RE_MD_QUERY_VUE$1 = /\.md\?vue/;
|
|
179
191
|
function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
|
|
180
192
|
return Components({
|
|
181
193
|
extensions: [
|
|
@@ -189,11 +201,11 @@ function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
|
|
|
189
201
|
dirs: [join(clientRoot, "builtin"), ...roots.map((i) => join(i, "components"))],
|
|
190
202
|
globsExclude: [],
|
|
191
203
|
include: [
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
204
|
+
RE_VUE_EXT$1,
|
|
205
|
+
RE_VUE_QUERY_VUE$1,
|
|
206
|
+
RE_VUE_QUERY_V$1,
|
|
207
|
+
RE_MD_EXT$2,
|
|
208
|
+
RE_MD_QUERY_VUE$1
|
|
197
209
|
],
|
|
198
210
|
exclude: [],
|
|
199
211
|
resolvers: [IconsResolver({
|
|
@@ -216,14 +228,16 @@ const templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $pa
|
|
|
216
228
|
|
|
217
229
|
//#endregion
|
|
218
230
|
//#region node/vite/contextInjection.ts
|
|
231
|
+
const RE_EXPORT_DEFAULT_OBJECT = /export\s+default\s+\{/;
|
|
232
|
+
const RE_INJECT_OPTION = /.*inject\s*:\s*([[{])/;
|
|
219
233
|
/**
|
|
220
234
|
* Inject `$slidev` into the script block of a Vue component
|
|
221
235
|
*/
|
|
222
236
|
function createContextInjectionPlugin() {
|
|
223
237
|
return {
|
|
224
238
|
name: "slidev:context-injection",
|
|
225
|
-
transform: { async handler(code, id) {
|
|
226
|
-
if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/")) return;
|
|
239
|
+
transform: { async handler(code, id$2) {
|
|
240
|
+
if (!id$2.endsWith(".vue") || id$2.includes("/@slidev/client/") || id$2.includes("/packages/client/")) return;
|
|
227
241
|
if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()")) return code;
|
|
228
242
|
const imports = [
|
|
229
243
|
templateImportContextUtils,
|
|
@@ -237,7 +251,7 @@ function createContextInjectionPlugin() {
|
|
|
237
251
|
const setupTagEnd = (setupScriptMatch.index || 0) + setupTag.length;
|
|
238
252
|
return `${code.slice(0, setupTagEnd)}\n${imports.join("\n")}\n${code.slice(setupTagEnd)}`;
|
|
239
253
|
} else if (!setupScriptMatch && matchScripts.length === 1) {
|
|
240
|
-
const matchExport = code.match(
|
|
254
|
+
const matchExport = code.match(RE_EXPORT_DEFAULT_OBJECT);
|
|
241
255
|
if (matchExport) {
|
|
242
256
|
const exportIndex = (matchExport.index || 0) + matchExport[0].length;
|
|
243
257
|
let component = code.slice(exportIndex);
|
|
@@ -248,7 +262,7 @@ import { injectionSlidevContext } from "@slidev/client/constants.ts"
|
|
|
248
262
|
${code.slice(scriptIndex)}`;
|
|
249
263
|
let injectIndex = exportIndex + 70;
|
|
250
264
|
let injectObject = "$slidev: { from: injectionSlidevContext },";
|
|
251
|
-
const matchInject = component.match(
|
|
265
|
+
const matchInject = component.match(RE_INJECT_OPTION);
|
|
252
266
|
if (matchInject) {
|
|
253
267
|
injectIndex += (matchInject.index || 0) + matchInject[0].length;
|
|
254
268
|
if (matchInject[1] === "[") {
|
|
@@ -269,6 +283,10 @@ ${code.slice(scriptIndex)}`;
|
|
|
269
283
|
|
|
270
284
|
//#endregion
|
|
271
285
|
//#region node/vite/extendConfig.ts
|
|
286
|
+
const RE_SLIDEV_CLIENT = /^@slidev\/client$/;
|
|
287
|
+
const RE_SLIDEV_CLIENT_SUBPATH = /^@slidev\/client\/(.*)/;
|
|
288
|
+
const RE_SLIDEV_VIRTUAL = /^#slidev\/(.*)/;
|
|
289
|
+
const RE_MONACO_EDITOR = /\/monaco-editor(?:-core)?\//;
|
|
272
290
|
const INCLUDE_GLOBAL = [
|
|
273
291
|
"@typescript/ata",
|
|
274
292
|
"file-saver",
|
|
@@ -335,15 +353,15 @@ function createConfigPlugin(options) {
|
|
|
335
353
|
resolve: {
|
|
336
354
|
alias: [
|
|
337
355
|
{
|
|
338
|
-
find:
|
|
356
|
+
find: RE_SLIDEV_CLIENT,
|
|
339
357
|
replacement: `${toAtFS(options.clientRoot)}/index.ts`
|
|
340
358
|
},
|
|
341
359
|
{
|
|
342
|
-
find:
|
|
360
|
+
find: RE_SLIDEV_CLIENT_SUBPATH,
|
|
343
361
|
replacement: `${toAtFS(options.clientRoot)}/$1`
|
|
344
362
|
},
|
|
345
363
|
{
|
|
346
|
-
find:
|
|
364
|
+
find: RE_SLIDEV_VIRTUAL,
|
|
347
365
|
replacement: "/@slidev/$1"
|
|
348
366
|
},
|
|
349
367
|
{
|
|
@@ -380,21 +398,21 @@ function createConfigPlugin(options) {
|
|
|
380
398
|
const DEFAULT = "assets/[name]-[hash].js";
|
|
381
399
|
if (chunkInfo.name.includes("/")) return DEFAULT;
|
|
382
400
|
if (chunkInfo.moduleIds.filter((i) => isSlidevClient(i)).length > chunkInfo.moduleIds.length * .6) return "assets/slidev/[name]-[hash].js";
|
|
383
|
-
if (chunkInfo.moduleIds.filter((i) => i.match(
|
|
401
|
+
if (chunkInfo.moduleIds.filter((i) => i.match(RE_MONACO_EDITOR)).length > chunkInfo.moduleIds.length * .6) return "assets/monaco/[name]-[hash].js";
|
|
384
402
|
return DEFAULT;
|
|
385
403
|
},
|
|
386
|
-
manualChunks(id) {
|
|
387
|
-
if (id.startsWith("/@slidev-monaco-types/") || id.includes("/@slidev/monaco-types") || id.endsWith("?monaco-types&raw")) return "monaco/bundled-types";
|
|
388
|
-
if (id.includes("/shiki/") || id.includes("/@shikijs/")) return `modules/shiki`;
|
|
389
|
-
if (id.startsWith("~icons/")) return "modules/unplugin-icons";
|
|
390
|
-
const matchedAsyncModule = ASYNC_MODULES.find((i) => id.includes(`/node_modules/${i}`));
|
|
404
|
+
manualChunks(id$2) {
|
|
405
|
+
if (id$2.startsWith("/@slidev-monaco-types/") || id$2.includes("/@slidev/monaco-types") || id$2.endsWith("?monaco-types&raw")) return "monaco/bundled-types";
|
|
406
|
+
if (id$2.includes("/shiki/") || id$2.includes("/@shikijs/")) return `modules/shiki`;
|
|
407
|
+
if (id$2.startsWith("~icons/")) return "modules/unplugin-icons";
|
|
408
|
+
const matchedAsyncModule = ASYNC_MODULES.find((i) => id$2.includes(`/node_modules/${i}`));
|
|
391
409
|
if (matchedAsyncModule) return `modules/${matchedAsyncModule.replace("@", "").replace("/", "-")}`;
|
|
392
410
|
}
|
|
393
411
|
} } },
|
|
394
412
|
cacheDir: isInstalledGlobally.value ? join(options.cliRoot, "node_modules/.vite") : void 0
|
|
395
413
|
};
|
|
396
|
-
function isSlidevClient(id) {
|
|
397
|
-
return id.includes("/@slidev/") || id.includes("/slidev/packages/client/") || id.includes("/@vueuse/");
|
|
414
|
+
function isSlidevClient(id$2) {
|
|
415
|
+
return id$2.includes("/@slidev/") || id$2.includes("/slidev/packages/client/") || id$2.includes("/@vueuse/");
|
|
398
416
|
}
|
|
399
417
|
return mergeConfig(injection, config);
|
|
400
418
|
},
|
|
@@ -426,8 +444,8 @@ function createHmrPatchPlugin() {
|
|
|
426
444
|
name: "slidev:hmr-patch",
|
|
427
445
|
transform: {
|
|
428
446
|
filter: { id: { include: regexSlideSourceId } },
|
|
429
|
-
handler(code, id) {
|
|
430
|
-
if (!id.match(regexSlideSourceId)) return;
|
|
447
|
+
handler(code, id$2) {
|
|
448
|
+
if (!id$2.match(regexSlideSourceId)) return;
|
|
431
449
|
return code.replace("if (_rerender_only)", "if (false)");
|
|
432
450
|
}
|
|
433
451
|
}
|
|
@@ -458,13 +476,14 @@ async function createInspectPlugin(options, pluginOptions) {
|
|
|
458
476
|
|
|
459
477
|
//#endregion
|
|
460
478
|
//#region node/vite/layoutWrapper.ts
|
|
479
|
+
const RE_SCRIPT_SETUP_TAG = /^<script setup.*>/m;
|
|
461
480
|
function createLayoutWrapperPlugin({ data, utils }) {
|
|
462
481
|
return {
|
|
463
482
|
name: "slidev:layout-wrapper",
|
|
464
483
|
transform: {
|
|
465
484
|
filter: { id: { include: regexSlideSourceId } },
|
|
466
|
-
async handler(code, id) {
|
|
467
|
-
const match = id.match(regexSlideSourceId);
|
|
485
|
+
async handler(code, id$2) {
|
|
486
|
+
const match = id$2.match(regexSlideSourceId);
|
|
468
487
|
if (!match) return;
|
|
469
488
|
const [, no, type] = match;
|
|
470
489
|
if (type !== "md") return;
|
|
@@ -476,7 +495,7 @@ function createLayoutWrapperPlugin({ data, utils }) {
|
|
|
476
495
|
console.error();
|
|
477
496
|
layoutName = "default";
|
|
478
497
|
}
|
|
479
|
-
const setupTag = code.match(
|
|
498
|
+
const setupTag = code.match(RE_SCRIPT_SETUP_TAG);
|
|
480
499
|
if (!setupTag) throw new Error(`[Slidev] Internal error: <script setup> block not found in slide ${index + 1}.`);
|
|
481
500
|
const templatePart = code.slice(0, setupTag.index);
|
|
482
501
|
const scriptPart = code.slice(setupTag.index);
|
|
@@ -503,7 +522,7 @@ function createLayoutWrapperPlugin({ data, utils }) {
|
|
|
503
522
|
|
|
504
523
|
//#endregion
|
|
505
524
|
//#region package.json
|
|
506
|
-
var version = "52.
|
|
525
|
+
var version = "52.15.0";
|
|
507
526
|
|
|
508
527
|
//#endregion
|
|
509
528
|
//#region node/integrations/addons.ts
|
|
@@ -545,6 +564,8 @@ async function getThemeMeta(name, root) {
|
|
|
545
564
|
|
|
546
565
|
//#endregion
|
|
547
566
|
//#region node/setups/indexHtml.ts
|
|
567
|
+
const RE_TRAILING_SLASH = /\/$/;
|
|
568
|
+
const RE_BODY_CONTENT = /<body>([\s\S]*?)<\/body>/i;
|
|
548
569
|
function escapeHtml(str) {
|
|
549
570
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
550
571
|
}
|
|
@@ -555,7 +576,7 @@ function collectPreloadImages(data, base) {
|
|
|
555
576
|
if (data.config.preloadImages === false) return [];
|
|
556
577
|
const seen = /* @__PURE__ */ new Set();
|
|
557
578
|
const links = [];
|
|
558
|
-
const basePrefix = base ? base.replace(
|
|
579
|
+
const basePrefix = base ? base.replace(RE_TRAILING_SLASH, "") : "";
|
|
559
580
|
for (const slide of data.slides) {
|
|
560
581
|
const images = slide.images || slide.source?.images;
|
|
561
582
|
if (!images?.length) continue;
|
|
@@ -585,10 +606,11 @@ async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data,
|
|
|
585
606
|
console.error(yellow("This file may be generated by Slidev, please remove it from your project."));
|
|
586
607
|
continue;
|
|
587
608
|
}
|
|
588
|
-
inputs.push(
|
|
589
|
-
body += `\n${(html.match(
|
|
609
|
+
inputs.push(parseHtmlForUnheadExtraction(html).input);
|
|
610
|
+
body += `\n${(html.match(RE_BODY_CONTENT)?.[1] || "").trim()}`;
|
|
590
611
|
}
|
|
591
612
|
if (data.features.tweet) body += "\n<script async src=\"https://platform.twitter.com/widgets.js\"><\/script>";
|
|
613
|
+
if (data.features.bluesky) body += "\n<script async src=\"https://embed.bsky.app/static/embed.js\" charset=\"utf-8\"><\/script>";
|
|
592
614
|
const webFontsLink = [];
|
|
593
615
|
if (data.config.fonts.webfonts.length) {
|
|
594
616
|
const { provider } = data.config.fonts;
|
|
@@ -799,6 +821,7 @@ async function setupShiki(roots) {
|
|
|
799
821
|
|
|
800
822
|
//#endregion
|
|
801
823
|
//#region node/options.ts
|
|
824
|
+
const RE_FILE_EXTENSION = /\.\w+$/;
|
|
802
825
|
const debug = createDebug("slidev:options");
|
|
803
826
|
async function resolveOptions(entryOptions, mode) {
|
|
804
827
|
const entry = await resolveEntry(entryOptions.entry);
|
|
@@ -817,6 +840,7 @@ async function resolveOptions(entryOptions, mode) {
|
|
|
817
840
|
rootsInfo.userRoot
|
|
818
841
|
]);
|
|
819
842
|
if (entryOptions.download) config.download ||= entryOptions.download;
|
|
843
|
+
if (entryOptions.routerMode) config.routerMode = entryOptions.routerMode;
|
|
820
844
|
debug({
|
|
821
845
|
...rootsInfo,
|
|
822
846
|
...entryOptions,
|
|
@@ -875,7 +899,7 @@ async function createDataUtils(resolved) {
|
|
|
875
899
|
suppressErrors: true
|
|
876
900
|
})));
|
|
877
901
|
for (const layoutPath of layoutPaths.flat(1)) {
|
|
878
|
-
const layoutName = path.basename(layoutPath).replace(
|
|
902
|
+
const layoutName = path.basename(layoutPath).replace(RE_FILE_EXTENSION, "");
|
|
879
903
|
layouts[layoutName] = layoutPath;
|
|
880
904
|
}
|
|
881
905
|
return layouts;
|
|
@@ -906,52 +930,10 @@ function getDefine(options) {
|
|
|
906
930
|
}
|
|
907
931
|
|
|
908
932
|
//#endregion
|
|
909
|
-
//#region node/syntax/
|
|
933
|
+
//#region node/syntax/utils.ts
|
|
910
934
|
function normalizeRangeStr(rangeStr = "") {
|
|
911
935
|
return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
912
936
|
}
|
|
913
|
-
function getCodeBlocks(md) {
|
|
914
|
-
const codeblocks = Array.from(md.matchAll(/^```[\s\S]*?^```/gm)).map((m) => {
|
|
915
|
-
const start = m.index;
|
|
916
|
-
const end = m.index + m[0].length;
|
|
917
|
-
return [
|
|
918
|
-
start,
|
|
919
|
-
end,
|
|
920
|
-
md.slice(0, start).match(/\n/g)?.length || 0,
|
|
921
|
-
md.slice(0, end).match(/\n/g)?.length || 0
|
|
922
|
-
];
|
|
923
|
-
});
|
|
924
|
-
return {
|
|
925
|
-
codeblocks,
|
|
926
|
-
isInsideCodeblocks(idx) {
|
|
927
|
-
return codeblocks.some(([s, e]) => s <= idx && idx <= e);
|
|
928
|
-
},
|
|
929
|
-
isLineInsideCodeblocks(line) {
|
|
930
|
-
return codeblocks.some(([, , s, e]) => s <= line && line <= e);
|
|
931
|
-
}
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
function getCommentBlocks(md) {
|
|
935
|
-
const commentBlocks = Array.from(md.matchAll(/<!--[\s\S]*?-->/g)).map((m) => {
|
|
936
|
-
const start = m.index;
|
|
937
|
-
const end = m.index + m[0].length;
|
|
938
|
-
return [
|
|
939
|
-
start,
|
|
940
|
-
end,
|
|
941
|
-
md.slice(0, start).match(/\n/g)?.length || 0,
|
|
942
|
-
md.slice(0, end).match(/\n/g)?.length || 0
|
|
943
|
-
];
|
|
944
|
-
});
|
|
945
|
-
return {
|
|
946
|
-
commentBlocks,
|
|
947
|
-
isInsideCommentBlocks(idx) {
|
|
948
|
-
return commentBlocks.some(([s, e]) => s <= idx && idx <= e);
|
|
949
|
-
},
|
|
950
|
-
isLineInsideCommentBlocks(line) {
|
|
951
|
-
return commentBlocks.some(([, , s, e]) => s <= line && line <= e);
|
|
952
|
-
}
|
|
953
|
-
};
|
|
954
|
-
}
|
|
955
937
|
/**
|
|
956
938
|
* Escape `{{` in code block to prevent Vue interpret it, #99, #1316
|
|
957
939
|
*/
|
|
@@ -960,7 +942,8 @@ function escapeVueInCode(md) {
|
|
|
960
942
|
}
|
|
961
943
|
|
|
962
944
|
//#endregion
|
|
963
|
-
//#region node/syntax/
|
|
945
|
+
//#region node/syntax/katex.ts
|
|
946
|
+
const RE_KATEX_BLOCK_INFO = /^\{([\w*,|-]+)\}\s*(\{[^}]*\})?/;
|
|
964
947
|
function isValidDelim(state, pos) {
|
|
965
948
|
const max = state.posMax;
|
|
966
949
|
let can_open = true;
|
|
@@ -1015,7 +998,7 @@ function math_inline(state, silent) {
|
|
|
1015
998
|
state.pos = match + 1;
|
|
1016
999
|
return true;
|
|
1017
1000
|
}
|
|
1018
|
-
|
|
1001
|
+
const math_block = function(state, start, end, silent) {
|
|
1019
1002
|
let firstLine;
|
|
1020
1003
|
let lastLine;
|
|
1021
1004
|
let next;
|
|
@@ -1026,11 +1009,13 @@ function math_block(state, start, end, silent) {
|
|
|
1026
1009
|
if (pos + 2 > max) return false;
|
|
1027
1010
|
if (state.src.slice(pos, pos + 2) !== "$$") return false;
|
|
1028
1011
|
pos += 2;
|
|
1029
|
-
firstLine = state.src.slice(pos, max);
|
|
1012
|
+
firstLine = state.src.slice(pos, max).trim();
|
|
1030
1013
|
if (silent) return true;
|
|
1031
|
-
|
|
1032
|
-
|
|
1014
|
+
let singleLine = false;
|
|
1015
|
+
if (firstLine.slice(-2) === "$$") {
|
|
1016
|
+
firstLine = firstLine.slice(0, -2).trim();
|
|
1033
1017
|
found = true;
|
|
1018
|
+
singleLine = true;
|
|
1034
1019
|
}
|
|
1035
1020
|
for (next = start; !found;) {
|
|
1036
1021
|
next++;
|
|
@@ -1047,11 +1032,15 @@ function math_block(state, start, end, silent) {
|
|
|
1047
1032
|
state.line = next + 1;
|
|
1048
1033
|
const token = state.push("math_block", "math", 0);
|
|
1049
1034
|
token.block = true;
|
|
1050
|
-
token.content =
|
|
1035
|
+
if (singleLine) token.content = firstLine;
|
|
1036
|
+
else {
|
|
1037
|
+
token.info = firstLine;
|
|
1038
|
+
token.content = state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : "");
|
|
1039
|
+
}
|
|
1051
1040
|
token.map = [start, state.line];
|
|
1052
1041
|
token.markup = "$$";
|
|
1053
1042
|
return true;
|
|
1054
|
-
}
|
|
1043
|
+
};
|
|
1055
1044
|
function MarkdownItKatex(md, options) {
|
|
1056
1045
|
const katexInline = function(latex) {
|
|
1057
1046
|
options.displayMode = false;
|
|
@@ -1075,7 +1064,10 @@ function MarkdownItKatex(md, options) {
|
|
|
1075
1064
|
}
|
|
1076
1065
|
};
|
|
1077
1066
|
const blockRenderer = function(tokens, idx) {
|
|
1078
|
-
|
|
1067
|
+
const token = tokens[idx];
|
|
1068
|
+
const [, rangeStr, options$1] = RE_KATEX_BLOCK_INFO.exec(token.info) || [];
|
|
1069
|
+
const ranges = normalizeRangeStr(rangeStr);
|
|
1070
|
+
return `<KaTexBlockWrapper ${options$1 ? `v-bind="${options$1}"` : ""} :ranges='${JSON.stringify(ranges)}'>${katexBlock(tokens[idx].content)}</KaTexBlockWrapper>\n`;
|
|
1079
1071
|
};
|
|
1080
1072
|
md.inline.ruler.after("escape", "math_inline", math_inline);
|
|
1081
1073
|
md.block.ruler.after("blockquote", "math_block", math_block, { alt: [
|
|
@@ -1088,6 +1080,23 @@ function MarkdownItKatex(md, options) {
|
|
|
1088
1080
|
md.renderer.rules.math_block = blockRenderer;
|
|
1089
1081
|
}
|
|
1090
1082
|
|
|
1083
|
+
//#endregion
|
|
1084
|
+
//#region node/virtual/conditional-styles.ts
|
|
1085
|
+
const id$1 = "/@slidev/conditional-styles";
|
|
1086
|
+
const templateConditionalStyles = {
|
|
1087
|
+
id: id$1,
|
|
1088
|
+
async getContent({ data, roots }) {
|
|
1089
|
+
const imports = [];
|
|
1090
|
+
for (const root of roots) imports.push(makeAbsoluteImportGlob(id$1, [
|
|
1091
|
+
join(root, "styles/index.{ts,js,css}"),
|
|
1092
|
+
join(root, "styles.{ts,js,css}"),
|
|
1093
|
+
join(root, "style.{ts,js,css}")
|
|
1094
|
+
]));
|
|
1095
|
+
if (data.features.katex) imports.push(`import "${await resolveImportUrl("katex/dist/katex.min.css")}"`);
|
|
1096
|
+
return imports.join("\n");
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
|
|
1091
1100
|
//#endregion
|
|
1092
1101
|
//#region node/virtual/configs.ts
|
|
1093
1102
|
const templateConfigs = {
|
|
@@ -1138,15 +1147,16 @@ console.warn('/@slidev/titles.md is deprecated, import from #slidev/title-render
|
|
|
1138
1147
|
|
|
1139
1148
|
//#endregion
|
|
1140
1149
|
//#region node/virtual/global-layers.ts
|
|
1150
|
+
const id = `/@slidev/global-layers`;
|
|
1141
1151
|
const templateGlobalLayers = {
|
|
1142
|
-
id
|
|
1143
|
-
getContent({
|
|
1152
|
+
id,
|
|
1153
|
+
getContent({ roots }) {
|
|
1144
1154
|
function* getComponent(name, names) {
|
|
1145
1155
|
yield `const ${name}Components = [\n`;
|
|
1146
1156
|
for (const root of roots) {
|
|
1147
1157
|
const globs = names.map((name$1) => join(root, `${name$1}.{ts,js,vue}`));
|
|
1148
1158
|
yield " Object.values(";
|
|
1149
|
-
yield makeAbsoluteImportGlob(
|
|
1159
|
+
yield makeAbsoluteImportGlob(id, globs, { import: "default" });
|
|
1150
1160
|
yield ")[0],\n";
|
|
1151
1161
|
}
|
|
1152
1162
|
yield `].filter(Boolean)\n`;
|
|
@@ -1262,11 +1272,12 @@ export default {
|
|
|
1262
1272
|
//#endregion
|
|
1263
1273
|
//#region node/virtual/setups.ts
|
|
1264
1274
|
function createSetupTemplate(name) {
|
|
1275
|
+
const id$2 = `/@slidev/setups/${name}`;
|
|
1265
1276
|
return {
|
|
1266
|
-
id:
|
|
1267
|
-
getContent({
|
|
1277
|
+
id: id$2,
|
|
1278
|
+
getContent({ roots }) {
|
|
1268
1279
|
return `export default [${roots.map((root) => {
|
|
1269
|
-
return `Object.values(${makeAbsoluteImportGlob(
|
|
1280
|
+
return `Object.values(${makeAbsoluteImportGlob(id$2, [join(root, `setup/${name}.{ts,js,mts,mjs}`)], { import: "default" })})[0]`;
|
|
1270
1281
|
}).join(", ")}].filter(Boolean)`;
|
|
1271
1282
|
}
|
|
1272
1283
|
};
|
|
@@ -1323,34 +1334,6 @@ const templateSlides = {
|
|
|
1323
1334
|
}
|
|
1324
1335
|
};
|
|
1325
1336
|
|
|
1326
|
-
//#endregion
|
|
1327
|
-
//#region node/virtual/styles.ts
|
|
1328
|
-
const templateStyle = {
|
|
1329
|
-
id: "/@slidev/styles",
|
|
1330
|
-
async getContent({ data, clientRoot, userRoot, roots }) {
|
|
1331
|
-
function resolveUrlOfClient(name) {
|
|
1332
|
-
return toAtFS(join(clientRoot, name));
|
|
1333
|
-
}
|
|
1334
|
-
const imports = [
|
|
1335
|
-
"styles/vars.css",
|
|
1336
|
-
"styles/index.css",
|
|
1337
|
-
"styles/code.css",
|
|
1338
|
-
"styles/katex.css",
|
|
1339
|
-
"styles/transitions.css"
|
|
1340
|
-
].map((path$1) => makeAbsoluteImportGlob(userRoot, [join(clientRoot, path$1)]));
|
|
1341
|
-
for (const root of roots) imports.push(makeAbsoluteImportGlob(userRoot, [
|
|
1342
|
-
join(root, "styles/index.{ts,js,css}"),
|
|
1343
|
-
join(root, "styles.{ts,js,css}"),
|
|
1344
|
-
join(root, "style.{ts,js,css}")
|
|
1345
|
-
]));
|
|
1346
|
-
if (data.features.katex) imports.push(`import "${await resolveImportUrl("katex/dist/katex.min.css")}"`);
|
|
1347
|
-
if (data.config.highlighter === "shiki") imports.push(`import "${await resolveImportUrl("@shikijs/vitepress-twoslash/style.css")}"`, `import "${resolveUrlOfClient("styles/shiki-twoslash.css")}"`, `import "${await resolveImportUrl("shiki-magic-move/style.css")}"`);
|
|
1348
|
-
imports.unshift(`import "${await resolveImportUrl("@unocss/reset/tailwind.css")}"`, "import \"uno:preflights.css\"", "import \"uno:typography.css\"", "import \"uno:shortcuts.css\"");
|
|
1349
|
-
imports.push("import \"uno.css\"");
|
|
1350
|
-
return imports.join("\n");
|
|
1351
|
-
}
|
|
1352
|
-
};
|
|
1353
|
-
|
|
1354
1337
|
//#endregion
|
|
1355
1338
|
//#region node/virtual/titles.ts
|
|
1356
1339
|
const templateTitleRendererMd = {
|
|
@@ -1374,7 +1357,7 @@ const templates = [
|
|
|
1374
1357
|
templateMonacoTypes,
|
|
1375
1358
|
templateMonacoRunDeps,
|
|
1376
1359
|
templateConfigs,
|
|
1377
|
-
|
|
1360
|
+
templateConditionalStyles,
|
|
1378
1361
|
templateGlobalLayers,
|
|
1379
1362
|
templateNavControls,
|
|
1380
1363
|
templateSlides,
|
|
@@ -1388,6 +1371,7 @@ const templates = [
|
|
|
1388
1371
|
|
|
1389
1372
|
//#endregion
|
|
1390
1373
|
//#region node/vite/loaders.ts
|
|
1374
|
+
const RE_WORD_CHARS_ONLY = /^[\w-]+$/;
|
|
1391
1375
|
function createSlidesLoader(options, serverOptions) {
|
|
1392
1376
|
const { data, mode, utils, withoutNotes } = options;
|
|
1393
1377
|
const notesMd = MarkdownExit({ html: true });
|
|
@@ -1528,32 +1512,32 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1528
1512
|
const moduleEntries = [
|
|
1529
1513
|
...ctx.modules.filter((i) => i.id === templateMonacoRunDeps.id || i.id === templateMonacoTypes.id),
|
|
1530
1514
|
...vueModules,
|
|
1531
|
-
...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
|
|
1515
|
+
...Array.from(moduleIds).map((id$2) => ctx.server.moduleGraph.getModuleById(id$2))
|
|
1532
1516
|
].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
|
|
1533
1517
|
updateServerWatcher();
|
|
1534
1518
|
return moduleEntries;
|
|
1535
1519
|
},
|
|
1536
1520
|
resolveId: {
|
|
1537
1521
|
order: "pre",
|
|
1538
|
-
handler(id) {
|
|
1539
|
-
if (id.startsWith("/@slidev/") || id.includes("__slidev_")) return id;
|
|
1522
|
+
handler(id$2) {
|
|
1523
|
+
if (id$2.startsWith("/@slidev/") || id$2.includes("__slidev_")) return id$2;
|
|
1540
1524
|
return null;
|
|
1541
1525
|
}
|
|
1542
1526
|
},
|
|
1543
|
-
async load(id) {
|
|
1544
|
-
const template = templates.find((i) => i.id === id);
|
|
1527
|
+
async load(id$2) {
|
|
1528
|
+
const template = templates.find((i) => i.id === id$2);
|
|
1545
1529
|
if (template) return {
|
|
1546
1530
|
code: await template.getContent.call(this, options),
|
|
1547
1531
|
map: { mappings: "" }
|
|
1548
1532
|
};
|
|
1549
|
-
const matchFacade = id.match(regexSlideFacadeId);
|
|
1533
|
+
const matchFacade = id$2.match(regexSlideFacadeId);
|
|
1550
1534
|
if (matchFacade) {
|
|
1551
1535
|
const [, no, type] = matchFacade;
|
|
1552
1536
|
const idx = +no - 1;
|
|
1553
1537
|
const sourceId = JSON.stringify(sourceIds[type][idx]);
|
|
1554
1538
|
return [`export * from ${sourceId}`, `export { default } from ${sourceId}`].join("\n");
|
|
1555
1539
|
}
|
|
1556
|
-
const matchSource = id.match(regexSlideSourceId);
|
|
1540
|
+
const matchSource = id$2.match(regexSlideSourceId);
|
|
1557
1541
|
if (matchSource) {
|
|
1558
1542
|
const [, no, type] = matchSource;
|
|
1559
1543
|
const idx = +no - 1;
|
|
@@ -1616,7 +1600,7 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1616
1600
|
};
|
|
1617
1601
|
}
|
|
1618
1602
|
}
|
|
1619
|
-
if (data.markdownFiles[id]) return "";
|
|
1603
|
+
if (data.markdownFiles[id$2]) return "";
|
|
1620
1604
|
}
|
|
1621
1605
|
};
|
|
1622
1606
|
function renderNote(text = "") {
|
|
@@ -1627,7 +1611,7 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1627
1611
|
clickCount += Number(count);
|
|
1628
1612
|
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
1629
1613
|
});
|
|
1630
|
-
const keys = Object.keys(notesAutoRuby).sort((b, a) => b.length - a.length).map((i) =>
|
|
1614
|
+
const keys = Object.keys(notesAutoRuby).sort((b, a) => b.length - a.length).map((i) => RE_WORD_CHARS_ONLY.test(i) ? `\\b${i}\\b` : i);
|
|
1631
1615
|
if (keys.length) {
|
|
1632
1616
|
const regex = new RegExp(`(${keys.join("|")})`, "g");
|
|
1633
1617
|
md = md.replace(regex, (match) => {
|
|
@@ -1646,6 +1630,29 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1646
1630
|
}
|
|
1647
1631
|
}
|
|
1648
1632
|
|
|
1633
|
+
//#endregion
|
|
1634
|
+
//#region node/setups/transformers.ts
|
|
1635
|
+
async function setupTransformers(roots) {
|
|
1636
|
+
const returns = await loadSetups(roots, "transformers.ts", []);
|
|
1637
|
+
const result = {
|
|
1638
|
+
pre: [],
|
|
1639
|
+
preCodeblock: [],
|
|
1640
|
+
postCodeblock: [],
|
|
1641
|
+
post: [],
|
|
1642
|
+
codeblocks: []
|
|
1643
|
+
};
|
|
1644
|
+
for (const r of [...returns].reverse()) {
|
|
1645
|
+
if (r.pre) result.pre.push(...r.pre);
|
|
1646
|
+
if (r.preCodeblock) result.preCodeblock.push(...r.preCodeblock);
|
|
1647
|
+
}
|
|
1648
|
+
for (const r of returns) {
|
|
1649
|
+
if (r.postCodeblock) result.postCodeblock.push(...r.postCodeblock);
|
|
1650
|
+
if (r.post) result.post.push(...r.post);
|
|
1651
|
+
if (r.codeblocks) result.codeblocks.push(...r.codeblocks);
|
|
1652
|
+
}
|
|
1653
|
+
return result;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1649
1656
|
//#endregion
|
|
1650
1657
|
//#region ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=49e14003b6caa0b7d164cbe71da573809d375bab_0dce998d26f79c06311f476731d22630/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
|
|
1651
1658
|
var SpecialCharacters;
|
|
@@ -1865,11 +1872,11 @@ function isTodoItem(tokens, index) {
|
|
|
1865
1872
|
}
|
|
1866
1873
|
function todoify(token, options) {
|
|
1867
1874
|
if (token.children == null) return;
|
|
1868
|
-
const id = generateIdForToken(token);
|
|
1869
|
-
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
1875
|
+
const id$2 = generateIdForToken(token);
|
|
1876
|
+
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id$2));
|
|
1870
1877
|
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
1871
1878
|
if (options.label) {
|
|
1872
|
-
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
1879
|
+
token.children.splice(1, 0, createLabelBeginToken(id$2));
|
|
1873
1880
|
token.children.push(createLabelEndToken());
|
|
1874
1881
|
}
|
|
1875
1882
|
}
|
|
@@ -1877,17 +1884,17 @@ function generateIdForToken(token) {
|
|
|
1877
1884
|
if (token.map) return `task-item-${token.map[0]}`;
|
|
1878
1885
|
else return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
|
|
1879
1886
|
}
|
|
1880
|
-
function createCheckboxToken(token, enabled, id) {
|
|
1887
|
+
function createCheckboxToken(token, enabled, id$2) {
|
|
1881
1888
|
const checkbox = new token_default("taskListItemCheckbox", "", 0);
|
|
1882
1889
|
if (!enabled) checkbox.attrSet("disabled", "true");
|
|
1883
1890
|
if (token.map) checkbox.attrSet("line", token.map[0].toString());
|
|
1884
|
-
checkbox.attrSet("id", id);
|
|
1891
|
+
checkbox.attrSet("id", id$2);
|
|
1885
1892
|
if (checkboxRegex.exec(token.content)?.[1].toLowerCase() === "x") checkbox.attrSet("checked", "true");
|
|
1886
1893
|
return checkbox;
|
|
1887
1894
|
}
|
|
1888
|
-
function createLabelBeginToken(id) {
|
|
1895
|
+
function createLabelBeginToken(id$2) {
|
|
1889
1896
|
const labelBeginToken = new token_default("taskListItemLabel_open", "", 1);
|
|
1890
|
-
labelBeginToken.attrSet("id", id);
|
|
1897
|
+
labelBeginToken.attrSet("id", id$2);
|
|
1891
1898
|
return labelBeginToken;
|
|
1892
1899
|
}
|
|
1893
1900
|
function createLabelEndToken() {
|
|
@@ -1907,62 +1914,139 @@ function startsWithTodoMarkdown(token) {
|
|
|
1907
1914
|
}
|
|
1908
1915
|
|
|
1909
1916
|
//#endregion
|
|
1910
|
-
//#region node/syntax/
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1917
|
+
//#region node/syntax/codeblock/magic-move.ts
|
|
1918
|
+
const RE_MAGIC_MOVE_INFO = /^(?:md|markdown) magic-move\s*(?:\[([^\]]*)\])?\s*(\{[^}]*\})?/;
|
|
1919
|
+
const RE_CODE_BLOCK = /^```([\w'-]+)?(?:[ \t]*|[ \t][ \w\t'-]*)(?:\[([^\]]*)\])?[ \t]*(?:\{([\w*,|-]+)\}[ \t]*(\{[^}]*\})?([^\r\n]*))?\r?\n((?:(?!^```)[\s\S])*?)^```$/gm;
|
|
1920
|
+
const RE_LINES_TRUE = /\blines: *true\b/;
|
|
1921
|
+
const RE_LINES_FALSE = /\blines: *false\b/;
|
|
1922
|
+
function parseLineNumbersOption(options) {
|
|
1923
|
+
return RE_LINES_TRUE.test(options) ? true : RE_LINES_FALSE.test(options) ? false : void 0;
|
|
1924
|
+
}
|
|
1925
|
+
var magic_move_default = defineCodeblockTransformer(async ({ info, fence, code, options: { data: { config }, utils: { shikiOptions, shiki } } }) => {
|
|
1926
|
+
if (fence !== 4) return;
|
|
1927
|
+
const match = info.match(RE_MAGIC_MOVE_INFO);
|
|
1928
|
+
if (!match) return;
|
|
1929
|
+
const [, title = "", options = "{}"] = match;
|
|
1930
|
+
const defaultLineNumbers = parseLineNumbersOption(options) ?? config.lineNumbers;
|
|
1931
|
+
const matches = Array.from(code.matchAll(RE_CODE_BLOCK));
|
|
1932
|
+
if (!matches.length) throw new Error("Magic Move block must contain at least one code block");
|
|
1933
|
+
const ranges = matches.map((i) => normalizeRangeStr(i[3]));
|
|
1934
|
+
const steps = await Promise.all(matches.map(async (i) => {
|
|
1935
|
+
const lang = i[1];
|
|
1936
|
+
const lineNumbers = parseLineNumbersOption(i[4]) ?? defaultLineNumbers;
|
|
1937
|
+
const code$1 = i[6].trimEnd();
|
|
1938
|
+
const options$1 = {
|
|
1939
|
+
...shikiOptions,
|
|
1940
|
+
lang
|
|
1941
|
+
};
|
|
1942
|
+
const { tokens, bg, fg: fg$1, rootStyle, themeName } = await shiki.codeToTokens(code$1, options$1);
|
|
1943
|
+
return {
|
|
1944
|
+
...toKeyedTokens(code$1, tokens, JSON.stringify([lang, "themes" in options$1 ? options$1.themes : options$1.theme]), lineNumbers),
|
|
1945
|
+
bg,
|
|
1946
|
+
fg: fg$1,
|
|
1947
|
+
rootStyle,
|
|
1948
|
+
themeName,
|
|
1949
|
+
lang
|
|
1950
|
+
};
|
|
1951
|
+
}));
|
|
1952
|
+
return `<ShikiMagicMove v-bind="${options}" steps-lz="${lz.compressToBase64(JSON.stringify(steps))}" :title='${JSON.stringify(title)}' :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
1953
|
+
});
|
|
1954
|
+
|
|
1955
|
+
//#endregion
|
|
1956
|
+
//#region node/syntax/codeblock/mermaid.ts
|
|
1957
|
+
const RE_MERMAID = /^mermaid\s*(\{[^\n]*\})?/;
|
|
1958
|
+
var mermaid_default = defineCodeblockTransformer(async ({ info, code }) => {
|
|
1959
|
+
const match = info.match(RE_MERMAID);
|
|
1960
|
+
if (!match) return;
|
|
1961
|
+
const [, options] = match;
|
|
1962
|
+
return `<Mermaid ${options ? `v-bind="${options}"` : ""} code-lz="${lz.compressToBase64(code.trim())}" />`;
|
|
1963
|
+
});
|
|
1964
|
+
|
|
1965
|
+
//#endregion
|
|
1966
|
+
//#region node/syntax/codeblock/monaco.ts
|
|
1967
|
+
const RE_MONACO = /^([\w'-]+)?\s*\{(monaco[\w-]*)\}\s*(\{[^}]*\})?(.*)$/;
|
|
1968
|
+
const RE_DIFF_SEPARATOR = /^\s*~~~\s*\n/m;
|
|
1969
|
+
var monaco_default = defineCodeblockTransformer(async ({ info, code, options: { data: { config }, mode } }) => {
|
|
1970
|
+
const match = info.match(RE_MONACO);
|
|
1971
|
+
if (!match) return;
|
|
1972
|
+
const [, lang = "", monaco, options] = match;
|
|
1973
|
+
if (!(config.monaco === true || config.monaco === mode)) return;
|
|
1974
|
+
let encoded;
|
|
1975
|
+
let diff = "";
|
|
1976
|
+
if (monaco === "monaco-diff") {
|
|
1977
|
+
const [original, modified] = code.split(RE_DIFF_SEPARATOR, 2);
|
|
1978
|
+
encoded = lz.compressToBase64(original);
|
|
1979
|
+
diff = modified === void 0 ? "" : `diff-lz="${lz.compressToBase64(modified)}"`;
|
|
1980
|
+
} else encoded = lz.compressToBase64(code);
|
|
1981
|
+
return `<Monaco ${options ? `v-bind="${options}"` : ""} ${monaco === "monaco-run" ? "runnable" : ""} lang="${lang}" code-lz="${encoded}" ${diff} />`;
|
|
1982
|
+
});
|
|
1983
|
+
|
|
1984
|
+
//#endregion
|
|
1985
|
+
//#region node/syntax/codeblock/plant-uml.ts
|
|
1986
|
+
const RE_PLANT_UML = /^plantuml\s*(\{[^\n]*\})?/;
|
|
1987
|
+
var plant_uml_default = defineCodeblockTransformer(async ({ info, code, options: { data: { config: { plantUmlServer } } } }) => {
|
|
1988
|
+
const match = info.match(RE_PLANT_UML);
|
|
1989
|
+
if (!match) return;
|
|
1990
|
+
const [, options] = match;
|
|
1991
|
+
return `<PlantUml ${options ? `v-bind="${options}"` : ""} code="${encode(code.trim())}"${plantUmlServer === void 0 ? "" : ` server=${JSON.stringify(plantUmlServer)}`} />`;
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
//#endregion
|
|
1995
|
+
//#region node/syntax/codeblock/wrapper.ts
|
|
1996
|
+
const RE_BLOCK_INFO = /^([\w'-]+)?(?:[ \t]*|[ \t][ \w\t'-]*)(?:\[([^\]]*)\])?[ \t]*(?:\{([\w,|\-*]+)\})?[ \t]*(\{[^}]*\})?(.*)$/;
|
|
1997
|
+
var wrapper_default = defineCodeblockTransformer(async ({ info, renderHighlighted }) => {
|
|
1998
|
+
const [, lang = "", title = "", rangeStr = "", options, rest = ""] = info.match(RE_BLOCK_INFO) ?? [];
|
|
1999
|
+
const ranges = normalizeRangeStr(rangeStr);
|
|
2000
|
+
const optionsProp = options ? `v-bind="${options}"` : "";
|
|
2001
|
+
const code = await renderHighlighted({ info: `${lang} ${rest}` });
|
|
2002
|
+
return `<CodeBlockWrapper ${optionsProp} title=${JSON.stringify(title)} :ranges='${JSON.stringify(ranges)}'>${escapeVueInCode(code)}</CodeBlockWrapper>`;
|
|
2003
|
+
});
|
|
2004
|
+
|
|
2005
|
+
//#endregion
|
|
2006
|
+
//#region node/syntax/codeblock/index.ts
|
|
2007
|
+
function MarkdownItCodeblocks(md, options, extraTransformers) {
|
|
2008
|
+
const oldFence = md.renderer.rules.fence;
|
|
2009
|
+
md.renderer.rules.fence = async function(tokens, idx, renderOptions, env, slf) {
|
|
2010
|
+
const token = tokens[idx];
|
|
2011
|
+
const slideNo = env.id?.match(regexSlideSourceId);
|
|
2012
|
+
const ctx = {
|
|
2013
|
+
info: token.info.trim(),
|
|
2014
|
+
code: token.content,
|
|
2015
|
+
fence: token.markup.length,
|
|
2016
|
+
slide: slideNo ? options.data.slides[slideNo[1] - 1] : null,
|
|
2017
|
+
options,
|
|
2018
|
+
renderHighlighted(override) {
|
|
2019
|
+
if (override.info != null) token.info = override.info;
|
|
2020
|
+
if (override.code != null) token.content = override.code;
|
|
2021
|
+
return oldFence(tokens, idx, renderOptions, env, slf);
|
|
1948
2022
|
}
|
|
2023
|
+
};
|
|
2024
|
+
const transformers = [
|
|
2025
|
+
...extraTransformers,
|
|
2026
|
+
mermaid_default,
|
|
2027
|
+
plant_uml_default,
|
|
2028
|
+
magic_move_default,
|
|
2029
|
+
monaco_default,
|
|
2030
|
+
wrapper_default
|
|
2031
|
+
];
|
|
2032
|
+
for (const transformer of transformers) {
|
|
2033
|
+
if (!transformer) continue;
|
|
2034
|
+
const res = await transformer(ctx);
|
|
2035
|
+
if (res != null) return ensureSuffix("\n", res);
|
|
1949
2036
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
...shikiOptions,
|
|
1953
|
-
transformers
|
|
1954
|
-
});
|
|
2037
|
+
throw new Error("Should not reach here");
|
|
2038
|
+
};
|
|
1955
2039
|
}
|
|
1956
2040
|
|
|
1957
2041
|
//#endregion
|
|
1958
|
-
//#region node/syntax/
|
|
2042
|
+
//#region node/syntax/drag.ts
|
|
1959
2043
|
const dragComponentRegex = /<(v-?drag-?\w*)([\s>])/i;
|
|
1960
2044
|
const dragDirectiveRegex = /(?<![</\w])v-drag(=".*?")?/i;
|
|
1961
2045
|
function MarkdownItVDrag(md, markdownTransformMap) {
|
|
1962
2046
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
1963
2047
|
const sourceMapConsumers = /* @__PURE__ */ new WeakMap();
|
|
1964
|
-
function getSourceMapConsumer(id) {
|
|
1965
|
-
const s = markdownTransformMap.get(id);
|
|
2048
|
+
function getSourceMapConsumer(id$2) {
|
|
2049
|
+
const s = id$2 && markdownTransformMap.get(id$2);
|
|
1966
2050
|
if (!s) return void 0;
|
|
1967
2051
|
let smc = sourceMapConsumers.get(s);
|
|
1968
2052
|
if (smc) return smc;
|
|
@@ -1976,7 +2060,7 @@ function MarkdownItVDrag(md, markdownTransformMap) {
|
|
|
1976
2060
|
}
|
|
1977
2061
|
const _parse = md.parse;
|
|
1978
2062
|
md.parse = function(src, env) {
|
|
1979
|
-
const smc = getSourceMapConsumer(env
|
|
2063
|
+
const smc = getSourceMapConsumer(env?.id);
|
|
1980
2064
|
const toOriginalPos = smc ? (line) => smc.originalPositionFor({
|
|
1981
2065
|
line: line + 1,
|
|
1982
2066
|
column: 0
|
|
@@ -2014,211 +2098,126 @@ function MarkdownItVDrag(md, markdownTransformMap) {
|
|
|
2014
2098
|
}
|
|
2015
2099
|
|
|
2016
2100
|
//#endregion
|
|
2017
|
-
//#region node/syntax/
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
md.
|
|
2022
|
-
|
|
2023
|
-
md.use(MarkdownItFootnote);
|
|
2024
|
-
md.use(taskLists, {
|
|
2025
|
-
enabled: true,
|
|
2026
|
-
lineNumber: true,
|
|
2027
|
-
label: true
|
|
2028
|
-
});
|
|
2029
|
-
if (features.katex) md.use(MarkdownItKatex, katexOptions);
|
|
2030
|
-
md.use(MarkdownItVDrag, markdownTransformMap);
|
|
2031
|
-
if (config.comark || config.mdc) md.use(MarkdownItComark);
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
|
-
//#endregion
|
|
2035
|
-
//#region node/setups/transformers.ts
|
|
2036
|
-
async function setupTransformers(roots) {
|
|
2037
|
-
const returns = await loadSetups(roots, "transformers.ts", []);
|
|
2038
|
-
const result = {
|
|
2039
|
-
pre: [],
|
|
2040
|
-
preCodeblock: [],
|
|
2041
|
-
postCodeblock: [],
|
|
2042
|
-
post: []
|
|
2101
|
+
//#region node/syntax/escape-code.ts
|
|
2102
|
+
const RE_CODE_TAG_OPEN = /^<code/;
|
|
2103
|
+
function MarkdownItEscapeInlineCode(md) {
|
|
2104
|
+
const codeInline = md.renderer.rules.code_inline;
|
|
2105
|
+
md.renderer.rules.code_inline = async (tokens, idx, options, env, self) => {
|
|
2106
|
+
return (await codeInline(tokens, idx, options, env, self)).replace(RE_CODE_TAG_OPEN, "<code v-pre");
|
|
2043
2107
|
};
|
|
2044
|
-
for (const r of [...returns].reverse()) {
|
|
2045
|
-
if (r.pre) result.pre.push(...r.pre);
|
|
2046
|
-
if (r.preCodeblock) result.preCodeblock.push(...r.preCodeblock);
|
|
2047
|
-
}
|
|
2048
|
-
for (const r of returns) {
|
|
2049
|
-
if (r.postCodeblock) result.postCodeblock.push(...r.postCodeblock);
|
|
2050
|
-
if (r.post) result.post.push(...r.post);
|
|
2051
|
-
}
|
|
2052
|
-
return result;
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
|
-
//#endregion
|
|
2056
|
-
//#region node/syntax/transform/code-wrapper.ts
|
|
2057
|
-
const reCodeBlock = /^```([\w'-]+)?(?:[ \t]*|[ \t][ \w\t'-]*)(?:\[([^\]]*)\])?[ \t]*(?:\{([\w*,|-]+)\}[ \t]*(\{[^}]*\})?([^\r\n]*))?\r?\n((?:(?!^```)[\s\S])*?)^```$/gm;
|
|
2058
|
-
/**
|
|
2059
|
-
* Transform code block with wrapper
|
|
2060
|
-
*/
|
|
2061
|
-
function transformCodeWrapper(ctx) {
|
|
2062
|
-
ctx.s.replace(reCodeBlock, (full, lang = "", title = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
2063
|
-
const ranges = normalizeRangeStr(rangeStr);
|
|
2064
|
-
code = code.trimEnd();
|
|
2065
|
-
options = options.trim() || "{}";
|
|
2066
|
-
return `\n<CodeBlockWrapper v-bind="${options}" :title='${JSON.stringify(title)}' :ranges='${JSON.stringify(ranges)}'>\n\n\`\`\`${lang}${title ? ` [${title}]` : ""}${attrs ? ` ${attrs.trim()}` : ""}\n${code}\n\`\`\`\n\n</CodeBlockWrapper>`;
|
|
2067
|
-
});
|
|
2068
|
-
}
|
|
2069
|
-
|
|
2070
|
-
//#endregion
|
|
2071
|
-
//#region node/syntax/transform/in-page-css.ts
|
|
2072
|
-
/**
|
|
2073
|
-
* Transform <style> in markdown to scoped style with page selector
|
|
2074
|
-
*/
|
|
2075
|
-
function transformPageCSS(ctx) {
|
|
2076
|
-
const codeBlocks = getCodeBlocks(ctx.s.original);
|
|
2077
|
-
const commentBlocks = getCommentBlocks(ctx.s.original);
|
|
2078
|
-
ctx.s.replace(/(\n<style[^>]*>)([\s\S]+?)(<\/style>)/g, (full, start, css, end, index) => {
|
|
2079
|
-
if (codeBlocks.isInsideCodeblocks(index)) return full;
|
|
2080
|
-
if (commentBlocks.isInsideCommentBlocks(index)) return ``;
|
|
2081
|
-
if (!start.includes("scoped")) start = start.replace("<style", "<style scoped");
|
|
2082
|
-
return `${start}\n${css}${end}`;
|
|
2083
|
-
});
|
|
2084
2108
|
}
|
|
2085
2109
|
|
|
2086
2110
|
//#endregion
|
|
2087
|
-
//#region node/syntax/
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2111
|
+
//#region node/syntax/scoped.ts
|
|
2112
|
+
const RE_STYLE_TAG_OPEN = /<style\b([^>]*)>/gi;
|
|
2113
|
+
const RE_SCOPED_ATTR = /\bscoped\b/i;
|
|
2114
|
+
function MarkdownItStyleScoped(md) {
|
|
2115
|
+
const addScoped = (html) => {
|
|
2116
|
+
return html.replace(RE_STYLE_TAG_OPEN, (match, attrs) => {
|
|
2117
|
+
if (RE_SCOPED_ATTR.test(attrs)) return match;
|
|
2118
|
+
return `<style scoped${attrs}>`;
|
|
2119
|
+
});
|
|
2120
|
+
};
|
|
2121
|
+
const htmlBlock = md.renderer.rules.html_block;
|
|
2122
|
+
md.renderer.rules.html_block = async (...args) => addScoped(await htmlBlock(...args));
|
|
2123
|
+
const htmlInline = md.renderer.rules.html_inline;
|
|
2124
|
+
md.renderer.rules.html_inline = async (...args) => addScoped(await htmlInline(...args));
|
|
2098
2125
|
}
|
|
2099
2126
|
|
|
2100
2127
|
//#endregion
|
|
2101
|
-
//#region node/syntax/
|
|
2102
|
-
|
|
2103
|
-
function
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
replacements.push([
|
|
2115
|
-
start,
|
|
2116
|
-
end,
|
|
2117
|
-
worker()
|
|
2128
|
+
//#region node/syntax/shiki.ts
|
|
2129
|
+
async function MarkdownItShiki({ data: { config }, mode, utils: { shiki, shikiOptions } }) {
|
|
2130
|
+
async function getTwoslashTransformer() {
|
|
2131
|
+
const [, , { transformerTwoslash }] = await Promise.all([
|
|
2132
|
+
shiki.codeToHast("", {
|
|
2133
|
+
lang: "js",
|
|
2134
|
+
...shikiOptions
|
|
2135
|
+
}),
|
|
2136
|
+
shiki.codeToHast("", {
|
|
2137
|
+
lang: "ts",
|
|
2138
|
+
...shikiOptions
|
|
2139
|
+
}),
|
|
2140
|
+
import("@shikijs/vitepress-twoslash")
|
|
2118
2141
|
]);
|
|
2119
|
-
return
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
const defaultLineNumbers = parseLineNumbersOption(options) ?? ctx.options.data.config.lineNumbers;
|
|
2124
|
-
const ranges = matches.map((i) => normalizeRangeStr(i[3]));
|
|
2125
|
-
const steps = await Promise.all(matches.map(async (i) => {
|
|
2126
|
-
const lang = i[1];
|
|
2127
|
-
const lineNumbers = parseLineNumbersOption(i[4]) ?? defaultLineNumbers;
|
|
2128
|
-
const code = i[6].trimEnd();
|
|
2129
|
-
const options$1 = {
|
|
2130
|
-
...ctx.options.utils.shikiOptions,
|
|
2131
|
-
lang
|
|
2132
|
-
};
|
|
2133
|
-
const { tokens, bg, fg: fg$1, rootStyle, themeName } = await codeToTokens(code, options$1);
|
|
2134
|
-
return {
|
|
2135
|
-
...toKeyedTokens(code, tokens, JSON.stringify([lang, "themes" in options$1 ? options$1.themes : options$1.theme]), lineNumbers),
|
|
2136
|
-
bg,
|
|
2137
|
-
fg: fg$1,
|
|
2138
|
-
rootStyle,
|
|
2139
|
-
themeName,
|
|
2140
|
-
lang
|
|
2141
|
-
};
|
|
2142
|
-
}));
|
|
2143
|
-
return `<ShikiMagicMove v-bind="${options}" steps-lz="${lz.compressToBase64(JSON.stringify(steps))}" :title='${JSON.stringify(title)}' :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
2144
|
-
}
|
|
2145
|
-
});
|
|
2146
|
-
for (const [start, end, content] of replacements) ctx.s.overwrite(start, end, await content);
|
|
2147
|
-
}
|
|
2148
|
-
|
|
2149
|
-
//#endregion
|
|
2150
|
-
//#region node/syntax/transform/mermaid.ts
|
|
2151
|
-
/**
|
|
2152
|
-
* Transform Mermaid code blocks (render done on client side)
|
|
2153
|
-
*/
|
|
2154
|
-
function transformMermaid(ctx) {
|
|
2155
|
-
ctx.s.replace(/^```mermaid *(\{[^\n]*\})?\n([\s\S]+?)\n```/gm, (full, options = "", code = "") => {
|
|
2156
|
-
code = code.trim();
|
|
2157
|
-
options = options.trim() || "{}";
|
|
2158
|
-
return `<Mermaid code-lz="${lz.compressToBase64(code)}" v-bind="${options}" />`;
|
|
2159
|
-
});
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2162
|
-
//#endregion
|
|
2163
|
-
//#region node/syntax/transform/monaco.ts
|
|
2164
|
-
function transformMonaco(ctx) {
|
|
2165
|
-
if (!(ctx.options.data.config.monaco === true || ctx.options.data.config.monaco === ctx.options.mode)) {
|
|
2166
|
-
ctx.s.replace(/\{monaco([\w:,-]*)\}/g, "");
|
|
2167
|
-
return;
|
|
2142
|
+
return transformerTwoslash({
|
|
2143
|
+
explicitTrigger: true,
|
|
2144
|
+
twoslashOptions: { handbookOptions: { noErrorValidation: true } }
|
|
2145
|
+
});
|
|
2168
2146
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
options = options.trim() || "{}";
|
|
2182
|
-
return `<Monaco runnable code-lz="${lz.compressToBase64(code)}" lang="${lang}" v-bind="${options}" />`;
|
|
2147
|
+
const transformers = [
|
|
2148
|
+
...shikiOptions.transformers || [],
|
|
2149
|
+
(config.twoslash === true || config.twoslash === mode) && await getTwoslashTransformer(),
|
|
2150
|
+
(config.twoslash === true || config.twoslash === mode) && transformerTwoslashConditional(),
|
|
2151
|
+
{ pre(pre) {
|
|
2152
|
+
this.addClassToHast(pre, "slidev-code");
|
|
2153
|
+
delete pre.properties.tabindex;
|
|
2154
|
+
} }
|
|
2155
|
+
].filter(isTruthy);
|
|
2156
|
+
return fromAsyncCodeToHtml(shiki.codeToHtml, {
|
|
2157
|
+
...shikiOptions,
|
|
2158
|
+
transformers
|
|
2183
2159
|
});
|
|
2184
2160
|
}
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
function
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
});
|
|
2161
|
+
function transformerTwoslashConditional() {
|
|
2162
|
+
return {
|
|
2163
|
+
name: "slidev:twoslash-conditional",
|
|
2164
|
+
code: function applyConditionalFlag(node) {
|
|
2165
|
+
if (node.tagName === "v-menu") {
|
|
2166
|
+
if (node.properties[":shown"] === "true") node.properties[":shown"] = "$nav.currentPage === $page";
|
|
2167
|
+
} else for (const child of node.children) if (child.type === "element") applyConditionalFlag(child);
|
|
2168
|
+
}
|
|
2169
|
+
};
|
|
2195
2170
|
}
|
|
2196
2171
|
|
|
2197
2172
|
//#endregion
|
|
2198
|
-
//#region node/syntax/
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
const
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2173
|
+
//#region node/syntax/slot-sugar.ts
|
|
2174
|
+
const RE_SLOT_MARKER = /^::\s*([\w.\-:]+)\s*::\s*$/;
|
|
2175
|
+
function MarkdownItSlotSugar(md) {
|
|
2176
|
+
md.block.ruler.before("fence", "slot_marker", (state, startLine, _endLine, silent) => {
|
|
2177
|
+
if (state.sCount[startLine] - state.blkIndent > 0) return false;
|
|
2178
|
+
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
2179
|
+
const max = state.eMarks[startLine];
|
|
2180
|
+
const match = state.src.slice(pos, max).match(RE_SLOT_MARKER);
|
|
2181
|
+
if (!match) return false;
|
|
2182
|
+
if (silent) return true;
|
|
2183
|
+
const token = state.push("slot_marker", "", 0);
|
|
2184
|
+
token.meta = { slotName: match[1] };
|
|
2185
|
+
token.map = [startLine, startLine + 1];
|
|
2186
|
+
state.line = startLine + 1;
|
|
2187
|
+
state.env.hasSlotMarker = true;
|
|
2188
|
+
return true;
|
|
2189
|
+
}, { alt: [
|
|
2190
|
+
"paragraph",
|
|
2191
|
+
"reference",
|
|
2192
|
+
"blockquote",
|
|
2193
|
+
"list"
|
|
2194
|
+
] });
|
|
2195
|
+
md.core.ruler.push("slot_sugar_compiler", (state) => {
|
|
2196
|
+
if (!state.env.hasSlotMarker) return;
|
|
2197
|
+
const tokens = state.tokens;
|
|
2198
|
+
const newTokens = [];
|
|
2199
|
+
let hasOpenSlot = false;
|
|
2200
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
2201
|
+
const token = tokens[i];
|
|
2202
|
+
if (token.type === "slot_marker") {
|
|
2203
|
+
if (hasOpenSlot) {
|
|
2204
|
+
const closeHtml = new state.Token("html_block", "", 0);
|
|
2205
|
+
closeHtml.content = "\n</template>\n";
|
|
2206
|
+
newTokens.push(closeHtml);
|
|
2207
|
+
}
|
|
2208
|
+
const openHtml = new state.Token("html_block", "", 0);
|
|
2209
|
+
openHtml.content = `\n<template v-slot:${token.meta.slotName}="slotProps">\n`;
|
|
2210
|
+
newTokens.push(openHtml);
|
|
2211
|
+
hasOpenSlot = true;
|
|
2212
|
+
} else newTokens.push(token);
|
|
2213
|
+
}
|
|
2214
|
+
if (hasOpenSlot) {
|
|
2215
|
+
const closeHtml = new state.Token("html_block", "", 0);
|
|
2216
|
+
closeHtml.content = "\n</template>\n";
|
|
2217
|
+
newTokens.push(closeHtml);
|
|
2219
2218
|
}
|
|
2219
|
+
state.tokens = newTokens;
|
|
2220
2220
|
});
|
|
2221
|
-
if (prevSlot) ctx.s.append("\n\n</template>");
|
|
2222
2221
|
}
|
|
2223
2222
|
|
|
2224
2223
|
//#endregion
|
|
@@ -2254,7 +2253,8 @@ function createMonacoWriterPlugin({ userRoot }) {
|
|
|
2254
2253
|
}
|
|
2255
2254
|
|
|
2256
2255
|
//#endregion
|
|
2257
|
-
//#region node/syntax/
|
|
2256
|
+
//#region node/syntax/snippet.ts
|
|
2257
|
+
const RE_NEWLINE = /\r?\n/;
|
|
2258
2258
|
function dedent(text) {
|
|
2259
2259
|
const lines = text.split("\n");
|
|
2260
2260
|
const minIndentLength = lines.reduce((acc, line) => {
|
|
@@ -2327,76 +2327,96 @@ function findRegion(lines, regionName) {
|
|
|
2327
2327
|
}
|
|
2328
2328
|
return null;
|
|
2329
2329
|
}
|
|
2330
|
-
const
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
const src = slash(
|
|
2330
|
+
const RE_SNIPPET_IMPORT = /^<<<[ \t]*(\S.*?)(#[\w-]+)?[ \t]*(?:[ \t](\S+?))?[ \t]*(\{.*)?$/;
|
|
2331
|
+
function MarkdownItSnippet(md, { userRoot, data: { watchFiles, slides } }) {
|
|
2332
|
+
md.block.ruler.before("fence", "snippet_import", (state, startLine, _endLine, silent) => {
|
|
2333
|
+
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
2334
|
+
const max = state.eMarks[startLine];
|
|
2335
|
+
const match = state.src.slice(pos, max).match(RE_SNIPPET_IMPORT);
|
|
2336
|
+
if (!match) return false;
|
|
2337
|
+
if (silent) return true;
|
|
2338
|
+
let [, filepath = "", regionName = "", lang = "", meta = ""] = match;
|
|
2339
|
+
const slideNo = state.env.id?.match(regexSlideSourceId);
|
|
2340
|
+
const slide = slideNo ? slides[slideNo[1] - 1] : null;
|
|
2341
|
+
if (!slide) {
|
|
2342
|
+
console.warn(yellow(`[markdown-it-snippet] Snippet syntax is not supported in ${state.env.id || "unknown source"}. Skipped.`));
|
|
2343
|
+
return false;
|
|
2344
|
+
}
|
|
2345
|
+
const dir = path.dirname(slide.source.filepath);
|
|
2346
|
+
const src = slash(filepath.startsWith("@/") ? path.resolve(userRoot, filepath.slice(2)) : path.resolve(dir, filepath));
|
|
2347
|
+
lang = lang.trim() || path.extname(filepath).slice(1);
|
|
2347
2348
|
meta = meta.trim();
|
|
2348
|
-
|
|
2349
|
-
lang = lang || path.extname(filepath).slice(1);
|
|
2350
|
-
const isAFile = fs.statSync(src).isFile();
|
|
2351
|
-
if (!fs.existsSync(src) || !isAFile) throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
|
|
2349
|
+
if (!(fs.existsSync(src) && fs.statSync(src).isFile())) throw new Error(`Code snippet path not found: ${src}`);
|
|
2352
2350
|
let content = fs.readFileSync(src, "utf8");
|
|
2353
2351
|
if (regionName) {
|
|
2354
|
-
const lines = content.split(
|
|
2352
|
+
const lines = content.split(RE_NEWLINE);
|
|
2355
2353
|
const region = findRegion(lines, regionName.slice(1));
|
|
2356
2354
|
if (region) content = dedent(lines.slice(region.start, region.end).filter((l) => !(region.re.start.test(l) || region.re.end.test(l))).join("\n"));
|
|
2357
2355
|
}
|
|
2358
|
-
if (meta.
|
|
2356
|
+
if (meta.includes("{monaco-write}")) {
|
|
2359
2357
|
monacoWriterWhitelist.add(filepath);
|
|
2360
2358
|
lang = lang.trim();
|
|
2361
|
-
meta = meta.replace(
|
|
2359
|
+
meta = meta.replace("{monaco-write}", "").trim() || "{}";
|
|
2360
|
+
const safeFilepath = JSON.stringify(filepath).slice(1, -1);
|
|
2362
2361
|
const encoded = lz.compressToBase64(content);
|
|
2363
|
-
|
|
2362
|
+
const token = state.push("html_block", "", 0);
|
|
2363
|
+
token.content = `<Monaco writable="${safeFilepath}" code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />\n`;
|
|
2364
|
+
token.map = [startLine, startLine + 1];
|
|
2364
2365
|
} else {
|
|
2365
2366
|
watchFiles[src] ??= /* @__PURE__ */ new Set();
|
|
2366
2367
|
watchFiles[src].add(slide.index);
|
|
2368
|
+
const token = state.push("fence", "code", 0);
|
|
2369
|
+
token.info = `${lang} ${meta}`.trim();
|
|
2370
|
+
token.content = content.endsWith("\n") ? content : `${content}\n`;
|
|
2371
|
+
token.map = [startLine, startLine + 1];
|
|
2367
2372
|
}
|
|
2368
|
-
|
|
2373
|
+
state.line = startLine + 1;
|
|
2374
|
+
return true;
|
|
2375
|
+
}, { alt: [
|
|
2376
|
+
"paragraph",
|
|
2377
|
+
"reference",
|
|
2378
|
+
"blockquote",
|
|
2379
|
+
"list"
|
|
2380
|
+
] });
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
//#endregion
|
|
2384
|
+
//#region node/syntax/index.ts
|
|
2385
|
+
async function useMarkdownItPlugins(md, options, markdownTransformMap, codeblockTransformers) {
|
|
2386
|
+
const { data: { features, config }, utils: { katexOptions } } = options;
|
|
2387
|
+
md.use(MarkdownItSnippet, options);
|
|
2388
|
+
md.use(await MarkdownItShiki(options));
|
|
2389
|
+
md.use(MarkdownItCodeblocks, options, codeblockTransformers);
|
|
2390
|
+
md.use(MarkdownItLink);
|
|
2391
|
+
md.use(MarkdownItEscapeInlineCode);
|
|
2392
|
+
md.use(MarkdownItFootnote);
|
|
2393
|
+
md.use(taskLists, {
|
|
2394
|
+
enabled: true,
|
|
2395
|
+
lineNumber: true,
|
|
2396
|
+
label: true
|
|
2369
2397
|
});
|
|
2398
|
+
if (features.katex) md.use(MarkdownItKatex, katexOptions);
|
|
2399
|
+
md.use(MarkdownItVDrag, markdownTransformMap);
|
|
2400
|
+
md.use(MarkdownItSlotSugar);
|
|
2401
|
+
if (config.comark || config.mdc) md.use(MarkdownItComark);
|
|
2402
|
+
md.use(MarkdownItStyleScoped);
|
|
2403
|
+
md.use(MarkdownItGitHubAlerts);
|
|
2370
2404
|
}
|
|
2371
2405
|
|
|
2372
2406
|
//#endregion
|
|
2373
|
-
//#region node/
|
|
2374
|
-
|
|
2407
|
+
//#region node/vite/markdown.ts
|
|
2408
|
+
const RE_MD_EXT$1 = /\.md$/;
|
|
2409
|
+
async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
2410
|
+
const markdownTransformMap = /* @__PURE__ */ new Map();
|
|
2375
2411
|
const extras = await setupTransformers(options.roots);
|
|
2376
|
-
|
|
2412
|
+
const transformers = [
|
|
2377
2413
|
...extras.pre,
|
|
2378
|
-
transformSnippet,
|
|
2379
|
-
options.data.config.highlighter === "shiki" && transformMagicMove,
|
|
2380
2414
|
...extras.preCodeblock,
|
|
2381
|
-
transformMermaid,
|
|
2382
|
-
transformPlantUml,
|
|
2383
|
-
options.data.features.monaco && transformMonaco,
|
|
2384
2415
|
...extras.postCodeblock,
|
|
2385
|
-
transformCodeWrapper,
|
|
2386
|
-
options.data.features.katex && transformKaTexWrapper,
|
|
2387
|
-
transformPageCSS,
|
|
2388
|
-
transformSlotSugar,
|
|
2389
2416
|
...extras.post
|
|
2390
2417
|
];
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
|
-
//#endregion
|
|
2394
|
-
//#region node/vite/markdown.ts
|
|
2395
|
-
async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
2396
|
-
const markdownTransformMap = /* @__PURE__ */ new Map();
|
|
2397
|
-
const transformers = await getMarkdownTransformers(options);
|
|
2398
2418
|
return Markdown({
|
|
2399
|
-
include: [
|
|
2419
|
+
include: [RE_MD_EXT$1],
|
|
2400
2420
|
wrapperClasses: "",
|
|
2401
2421
|
headEnabled: false,
|
|
2402
2422
|
frontmatter: false,
|
|
@@ -2410,18 +2430,18 @@ async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
|
2410
2430
|
},
|
|
2411
2431
|
...mdOptions,
|
|
2412
2432
|
async markdownSetup(md) {
|
|
2413
|
-
await useMarkdownItPlugins(md, options, markdownTransformMap);
|
|
2433
|
+
await useMarkdownItPlugins(md, options, markdownTransformMap, extras.codeblocks);
|
|
2414
2434
|
await mdOptions?.markdownSetup?.(md);
|
|
2415
2435
|
},
|
|
2416
2436
|
transforms: {
|
|
2417
2437
|
...mdOptions?.transforms,
|
|
2418
|
-
async before(code, id) {
|
|
2419
|
-
if (options.data.markdownFiles[id]) return "";
|
|
2420
|
-
code = await mdOptions?.transforms?.before?.(code, id) ?? code;
|
|
2421
|
-
const match = id.match(regexSlideSourceId);
|
|
2438
|
+
async before(code, id$2) {
|
|
2439
|
+
if (options.data.markdownFiles[id$2]) return "";
|
|
2440
|
+
code = await mdOptions?.transforms?.before?.(code, id$2) ?? code;
|
|
2441
|
+
const match = id$2.match(regexSlideSourceId);
|
|
2422
2442
|
if (!match) return code;
|
|
2423
2443
|
const s = new MagicString(code);
|
|
2424
|
-
markdownTransformMap.set(id, s);
|
|
2444
|
+
markdownTransformMap.set(id$2, s);
|
|
2425
2445
|
const ctx = {
|
|
2426
2446
|
s,
|
|
2427
2447
|
slide: options.data.slides[+match[1] - 1],
|
|
@@ -2443,13 +2463,13 @@ async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
|
2443
2463
|
function createMonacoTypesLoader({ userRoot, utils }) {
|
|
2444
2464
|
return {
|
|
2445
2465
|
name: "slidev:monaco-types-loader",
|
|
2446
|
-
resolveId(id) {
|
|
2447
|
-
if (id.startsWith("/@slidev-monaco-types/")) return id;
|
|
2466
|
+
resolveId(id$2) {
|
|
2467
|
+
if (id$2.startsWith("/@slidev-monaco-types/")) return id$2;
|
|
2448
2468
|
return null;
|
|
2449
2469
|
},
|
|
2450
|
-
async load(id) {
|
|
2451
|
-
if (!id.startsWith("/@slidev-monaco-types/")) return null;
|
|
2452
|
-
const url = new URL(id, "http://localhost");
|
|
2470
|
+
async load(id$2) {
|
|
2471
|
+
if (!id$2.startsWith("/@slidev-monaco-types/")) return null;
|
|
2472
|
+
const url = new URL(id$2, "http://localhost");
|
|
2453
2473
|
if (url.pathname === "/@slidev-monaco-types/resolve") {
|
|
2454
2474
|
const query = new URLSearchParams(url.search);
|
|
2455
2475
|
const pkg = query.get("pkg");
|
|
@@ -2502,9 +2522,9 @@ function createPatchMonacoSourceMapPlugin() {
|
|
|
2502
2522
|
return {
|
|
2503
2523
|
name: "slidev:patch-monaco-sourcemap",
|
|
2504
2524
|
enforce: "pre",
|
|
2505
|
-
load(id) {
|
|
2506
|
-
if (!id.includes("node_modules/monaco-editor/esm/vs/base")) return;
|
|
2507
|
-
return readFile(cleanUrl(id), "utf-8");
|
|
2525
|
+
load(id$2) {
|
|
2526
|
+
if (!id$2.includes("node_modules/monaco-editor/esm/vs/base")) return;
|
|
2527
|
+
return readFile(cleanUrl(id$2), "utf-8");
|
|
2508
2528
|
}
|
|
2509
2529
|
};
|
|
2510
2530
|
}
|
|
@@ -2515,7 +2535,7 @@ async function createRemoteAssetsPlugin({ data: { config }, mode }, pluginOption
|
|
|
2515
2535
|
if (!(config.remoteAssets === true || config.remoteAssets === mode)) return;
|
|
2516
2536
|
const { VitePluginRemoteAssets, DefaultRules } = await import("vite-plugin-remote-assets");
|
|
2517
2537
|
return VitePluginRemoteAssets({
|
|
2518
|
-
resolveMode: (id) => id.endsWith("index.html") ? "relative" : "@fs",
|
|
2538
|
+
resolveMode: (id$2) => id$2.endsWith("index.html") ? "relative" : "@fs",
|
|
2519
2539
|
awaitDownload: mode === "build",
|
|
2520
2540
|
...pluginOptions.remoteAssets,
|
|
2521
2541
|
rules: [
|
|
@@ -2669,6 +2689,11 @@ async function createUnocssPlugin(options, pluginOptions) {
|
|
|
2669
2689
|
|
|
2670
2690
|
//#endregion
|
|
2671
2691
|
//#region node/vite/vue.ts
|
|
2692
|
+
const RE_VUE_EXT = /\.vue$/;
|
|
2693
|
+
const RE_VUE_QUERY_VUE = /\.vue\?vue/;
|
|
2694
|
+
const RE_VUE_QUERY_V = /\.vue\?v=/;
|
|
2695
|
+
const RE_MD_EXT = /\.md$/;
|
|
2696
|
+
const RE_MD_QUERY_VUE = /\.md\?vue/;
|
|
2672
2697
|
const customElements = new Set([
|
|
2673
2698
|
"annotation",
|
|
2674
2699
|
"math",
|
|
@@ -2702,11 +2727,11 @@ async function createVuePlugin(_options, pluginOptions) {
|
|
|
2702
2727
|
const { vue: vueOptions = {}, vuejsx: vuejsxOptions = {} } = pluginOptions;
|
|
2703
2728
|
const VuePlugin = Vue({
|
|
2704
2729
|
include: [
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2730
|
+
RE_VUE_EXT,
|
|
2731
|
+
RE_VUE_QUERY_VUE,
|
|
2732
|
+
RE_VUE_QUERY_V,
|
|
2733
|
+
RE_MD_EXT,
|
|
2734
|
+
RE_MD_QUERY_VUE
|
|
2710
2735
|
],
|
|
2711
2736
|
exclude: [],
|
|
2712
2737
|
...vueOptions,
|