@slidev/cli 52.14.2 → 52.15.1
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-yk6Ejluk.mjs} +29 -21
- package/dist/cli.mjs +15 -9
- package/dist/{export-C4evmDwN.mjs → export-DA_9kPXd.mjs} +4 -3
- package/dist/index.mjs +3 -3
- package/dist/{resolver-B4CxEjJF.mjs → resolver-XedCEhxI.mjs} +2 -1
- package/dist/{serve-D_ugeQhq.mjs → serve-CYSWeFFN.mjs} +1 -1
- package/dist/{shared-ZIXcnTKJ.mjs → shared-ClfjhvJo.mjs} +486 -450
- 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,12 +1,12 @@
|
|
|
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
|
-
import path, { basename, dirname, join, relative, resolve } from "node:path";
|
|
3
|
+
import path, { basename, dirname, join, relative, resolve, win32 } from "node:path";
|
|
4
4
|
import { loadConfigFromFile, mergeConfig } from "vite";
|
|
5
5
|
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,21 @@ 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;
|
|
73
|
+
const RE_WINDOWS_DRIVE = /^[A-Z]:\//i;
|
|
66
74
|
let jiti;
|
|
67
75
|
function loadModule(absolutePath) {
|
|
68
76
|
jiti ??= createJiti(fileURLToPath(import.meta.url), { moduleCache: false });
|
|
69
77
|
return jiti.import(absolutePath);
|
|
70
78
|
}
|
|
71
79
|
function stringifyMarkdownTokens(tokens) {
|
|
72
|
-
return tokens.map((token) => token.children?.filter((t) => ["text", "code_inline"].includes(t.type) && !t.content.match(
|
|
80
|
+
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
81
|
}
|
|
74
82
|
function generateFontParams(options) {
|
|
75
83
|
const weights = options.weights.flatMap((i) => options.italic ? [`0,${i}`, `1,${i}`] : [`${i}`]).sort().join(";");
|
|
76
|
-
return options.webfonts.map((i) => `family=${i.replace(
|
|
84
|
+
return options.webfonts.map((i) => `family=${i.replace(RE_QUOTED_STRING, "$1").replace(RE_WHITESPACE, "+")}:${options.italic ? "ital," : ""}wght@${weights}`).join("&");
|
|
77
85
|
}
|
|
78
86
|
function generateGoogleFontsUrl(options) {
|
|
79
87
|
return `https://fonts.googleapis.com/css2?${generateFontParams(options)}&display=swap`;
|
|
@@ -124,12 +132,21 @@ function getBodyJson(req) {
|
|
|
124
132
|
});
|
|
125
133
|
});
|
|
126
134
|
}
|
|
127
|
-
function
|
|
128
|
-
const
|
|
135
|
+
function getImportGlobRelativePath(from, to) {
|
|
136
|
+
const normalizedFrom = slash(from);
|
|
137
|
+
const normalizedTo = slash(to);
|
|
138
|
+
return slash(RE_WINDOWS_DRIVE.test(normalizedFrom) || RE_WINDOWS_DRIVE.test(normalizedTo) ? win32.relative(normalizedFrom, normalizedTo) : relative(normalizedFrom, normalizedTo));
|
|
139
|
+
}
|
|
140
|
+
function makeAbsoluteImportGlob(self, globs, options = {}, baseRoot) {
|
|
141
|
+
const root = baseRoot && globs.some((glob) => RE_WINDOWS_DRIVE.test(slash(glob))) ? baseRoot : void 0;
|
|
142
|
+
const relativeGlobs = globs.map((glob) => {
|
|
143
|
+
const relativeGlob = getImportGlobRelativePath(root ?? self, glob);
|
|
144
|
+
return root && !relativeGlob.startsWith(".") && !RE_WINDOWS_DRIVE.test(relativeGlob) ? `./${relativeGlob}` : relativeGlob;
|
|
145
|
+
});
|
|
129
146
|
const opts = {
|
|
130
147
|
eager: true,
|
|
131
148
|
exhaustive: true,
|
|
132
|
-
base: "/",
|
|
149
|
+
...root ? { base: "/" } : {},
|
|
133
150
|
...options
|
|
134
151
|
};
|
|
135
152
|
return `import.meta.glob(${JSON.stringify(relativeGlobs)}, ${JSON.stringify(opts)})`;
|
|
@@ -155,6 +172,7 @@ async function setupVitePlugins(options) {
|
|
|
155
172
|
|
|
156
173
|
//#endregion
|
|
157
174
|
//#region node/vite/compilerFlagsVue.ts
|
|
175
|
+
const RE_VUE_FILE = /\.vue(?:$|\?)/;
|
|
158
176
|
/**
|
|
159
177
|
* Replace compiler flags like `__DEV__` in Vue SFC
|
|
160
178
|
*/
|
|
@@ -163,8 +181,8 @@ function createVueCompilerFlagsPlugin(options) {
|
|
|
163
181
|
return {
|
|
164
182
|
name: "slidev:flags",
|
|
165
183
|
enforce: "pre",
|
|
166
|
-
transform: { handler(code, id) {
|
|
167
|
-
if (!
|
|
184
|
+
transform: { handler(code, id$2) {
|
|
185
|
+
if (!RE_VUE_FILE.test(id$2) && !id$2.includes("?vue&")) return;
|
|
168
186
|
const original = code;
|
|
169
187
|
define.forEach(([from, to]) => {
|
|
170
188
|
code = code.replaceAll(from, to);
|
|
@@ -176,6 +194,11 @@ function createVueCompilerFlagsPlugin(options) {
|
|
|
176
194
|
|
|
177
195
|
//#endregion
|
|
178
196
|
//#region node/vite/components.ts
|
|
197
|
+
const RE_VUE_EXT$1 = /\.vue$/;
|
|
198
|
+
const RE_VUE_QUERY_VUE$1 = /\.vue\?vue/;
|
|
199
|
+
const RE_VUE_QUERY_V$1 = /\.vue\?v=/;
|
|
200
|
+
const RE_MD_EXT$2 = /\.md$/;
|
|
201
|
+
const RE_MD_QUERY_VUE$1 = /\.md\?vue/;
|
|
179
202
|
function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
|
|
180
203
|
return Components({
|
|
181
204
|
extensions: [
|
|
@@ -189,11 +212,11 @@ function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
|
|
|
189
212
|
dirs: [join(clientRoot, "builtin"), ...roots.map((i) => join(i, "components"))],
|
|
190
213
|
globsExclude: [],
|
|
191
214
|
include: [
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
215
|
+
RE_VUE_EXT$1,
|
|
216
|
+
RE_VUE_QUERY_VUE$1,
|
|
217
|
+
RE_VUE_QUERY_V$1,
|
|
218
|
+
RE_MD_EXT$2,
|
|
219
|
+
RE_MD_QUERY_VUE$1
|
|
197
220
|
],
|
|
198
221
|
exclude: [],
|
|
199
222
|
resolvers: [IconsResolver({
|
|
@@ -216,14 +239,16 @@ const templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $pa
|
|
|
216
239
|
|
|
217
240
|
//#endregion
|
|
218
241
|
//#region node/vite/contextInjection.ts
|
|
242
|
+
const RE_EXPORT_DEFAULT_OBJECT = /export\s+default\s+\{/;
|
|
243
|
+
const RE_INJECT_OPTION = /.*inject\s*:\s*([[{])/;
|
|
219
244
|
/**
|
|
220
245
|
* Inject `$slidev` into the script block of a Vue component
|
|
221
246
|
*/
|
|
222
247
|
function createContextInjectionPlugin() {
|
|
223
248
|
return {
|
|
224
249
|
name: "slidev:context-injection",
|
|
225
|
-
transform: { async handler(code, id) {
|
|
226
|
-
if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/")) return;
|
|
250
|
+
transform: { async handler(code, id$2) {
|
|
251
|
+
if (!id$2.endsWith(".vue") || id$2.includes("/@slidev/client/") || id$2.includes("/packages/client/")) return;
|
|
227
252
|
if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()")) return code;
|
|
228
253
|
const imports = [
|
|
229
254
|
templateImportContextUtils,
|
|
@@ -237,7 +262,7 @@ function createContextInjectionPlugin() {
|
|
|
237
262
|
const setupTagEnd = (setupScriptMatch.index || 0) + setupTag.length;
|
|
238
263
|
return `${code.slice(0, setupTagEnd)}\n${imports.join("\n")}\n${code.slice(setupTagEnd)}`;
|
|
239
264
|
} else if (!setupScriptMatch && matchScripts.length === 1) {
|
|
240
|
-
const matchExport = code.match(
|
|
265
|
+
const matchExport = code.match(RE_EXPORT_DEFAULT_OBJECT);
|
|
241
266
|
if (matchExport) {
|
|
242
267
|
const exportIndex = (matchExport.index || 0) + matchExport[0].length;
|
|
243
268
|
let component = code.slice(exportIndex);
|
|
@@ -248,7 +273,7 @@ import { injectionSlidevContext } from "@slidev/client/constants.ts"
|
|
|
248
273
|
${code.slice(scriptIndex)}`;
|
|
249
274
|
let injectIndex = exportIndex + 70;
|
|
250
275
|
let injectObject = "$slidev: { from: injectionSlidevContext },";
|
|
251
|
-
const matchInject = component.match(
|
|
276
|
+
const matchInject = component.match(RE_INJECT_OPTION);
|
|
252
277
|
if (matchInject) {
|
|
253
278
|
injectIndex += (matchInject.index || 0) + matchInject[0].length;
|
|
254
279
|
if (matchInject[1] === "[") {
|
|
@@ -269,6 +294,10 @@ ${code.slice(scriptIndex)}`;
|
|
|
269
294
|
|
|
270
295
|
//#endregion
|
|
271
296
|
//#region node/vite/extendConfig.ts
|
|
297
|
+
const RE_SLIDEV_CLIENT = /^@slidev\/client$/;
|
|
298
|
+
const RE_SLIDEV_CLIENT_SUBPATH = /^@slidev\/client\/(.*)/;
|
|
299
|
+
const RE_SLIDEV_VIRTUAL = /^#slidev\/(.*)/;
|
|
300
|
+
const RE_MONACO_EDITOR = /\/monaco-editor(?:-core)?\//;
|
|
272
301
|
const INCLUDE_GLOBAL = [
|
|
273
302
|
"@typescript/ata",
|
|
274
303
|
"file-saver",
|
|
@@ -335,15 +364,15 @@ function createConfigPlugin(options) {
|
|
|
335
364
|
resolve: {
|
|
336
365
|
alias: [
|
|
337
366
|
{
|
|
338
|
-
find:
|
|
367
|
+
find: RE_SLIDEV_CLIENT,
|
|
339
368
|
replacement: `${toAtFS(options.clientRoot)}/index.ts`
|
|
340
369
|
},
|
|
341
370
|
{
|
|
342
|
-
find:
|
|
371
|
+
find: RE_SLIDEV_CLIENT_SUBPATH,
|
|
343
372
|
replacement: `${toAtFS(options.clientRoot)}/$1`
|
|
344
373
|
},
|
|
345
374
|
{
|
|
346
|
-
find:
|
|
375
|
+
find: RE_SLIDEV_VIRTUAL,
|
|
347
376
|
replacement: "/@slidev/$1"
|
|
348
377
|
},
|
|
349
378
|
{
|
|
@@ -380,21 +409,21 @@ function createConfigPlugin(options) {
|
|
|
380
409
|
const DEFAULT = "assets/[name]-[hash].js";
|
|
381
410
|
if (chunkInfo.name.includes("/")) return DEFAULT;
|
|
382
411
|
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(
|
|
412
|
+
if (chunkInfo.moduleIds.filter((i) => i.match(RE_MONACO_EDITOR)).length > chunkInfo.moduleIds.length * .6) return "assets/monaco/[name]-[hash].js";
|
|
384
413
|
return DEFAULT;
|
|
385
414
|
},
|
|
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}`));
|
|
415
|
+
manualChunks(id$2) {
|
|
416
|
+
if (id$2.startsWith("/@slidev-monaco-types/") || id$2.includes("/@slidev/monaco-types") || id$2.endsWith("?monaco-types&raw")) return "monaco/bundled-types";
|
|
417
|
+
if (id$2.includes("/shiki/") || id$2.includes("/@shikijs/")) return `modules/shiki`;
|
|
418
|
+
if (id$2.startsWith("~icons/")) return "modules/unplugin-icons";
|
|
419
|
+
const matchedAsyncModule = ASYNC_MODULES.find((i) => id$2.includes(`/node_modules/${i}`));
|
|
391
420
|
if (matchedAsyncModule) return `modules/${matchedAsyncModule.replace("@", "").replace("/", "-")}`;
|
|
392
421
|
}
|
|
393
422
|
} } },
|
|
394
423
|
cacheDir: isInstalledGlobally.value ? join(options.cliRoot, "node_modules/.vite") : void 0
|
|
395
424
|
};
|
|
396
|
-
function isSlidevClient(id) {
|
|
397
|
-
return id.includes("/@slidev/") || id.includes("/slidev/packages/client/") || id.includes("/@vueuse/");
|
|
425
|
+
function isSlidevClient(id$2) {
|
|
426
|
+
return id$2.includes("/@slidev/") || id$2.includes("/slidev/packages/client/") || id$2.includes("/@vueuse/");
|
|
398
427
|
}
|
|
399
428
|
return mergeConfig(injection, config);
|
|
400
429
|
},
|
|
@@ -426,8 +455,8 @@ function createHmrPatchPlugin() {
|
|
|
426
455
|
name: "slidev:hmr-patch",
|
|
427
456
|
transform: {
|
|
428
457
|
filter: { id: { include: regexSlideSourceId } },
|
|
429
|
-
handler(code, id) {
|
|
430
|
-
if (!id.match(regexSlideSourceId)) return;
|
|
458
|
+
handler(code, id$2) {
|
|
459
|
+
if (!id$2.match(regexSlideSourceId)) return;
|
|
431
460
|
return code.replace("if (_rerender_only)", "if (false)");
|
|
432
461
|
}
|
|
433
462
|
}
|
|
@@ -458,13 +487,14 @@ async function createInspectPlugin(options, pluginOptions) {
|
|
|
458
487
|
|
|
459
488
|
//#endregion
|
|
460
489
|
//#region node/vite/layoutWrapper.ts
|
|
490
|
+
const RE_SCRIPT_SETUP_TAG = /^<script setup.*>/m;
|
|
461
491
|
function createLayoutWrapperPlugin({ data, utils }) {
|
|
462
492
|
return {
|
|
463
493
|
name: "slidev:layout-wrapper",
|
|
464
494
|
transform: {
|
|
465
495
|
filter: { id: { include: regexSlideSourceId } },
|
|
466
|
-
async handler(code, id) {
|
|
467
|
-
const match = id.match(regexSlideSourceId);
|
|
496
|
+
async handler(code, id$2) {
|
|
497
|
+
const match = id$2.match(regexSlideSourceId);
|
|
468
498
|
if (!match) return;
|
|
469
499
|
const [, no, type] = match;
|
|
470
500
|
if (type !== "md") return;
|
|
@@ -476,7 +506,7 @@ function createLayoutWrapperPlugin({ data, utils }) {
|
|
|
476
506
|
console.error();
|
|
477
507
|
layoutName = "default";
|
|
478
508
|
}
|
|
479
|
-
const setupTag = code.match(
|
|
509
|
+
const setupTag = code.match(RE_SCRIPT_SETUP_TAG);
|
|
480
510
|
if (!setupTag) throw new Error(`[Slidev] Internal error: <script setup> block not found in slide ${index + 1}.`);
|
|
481
511
|
const templatePart = code.slice(0, setupTag.index);
|
|
482
512
|
const scriptPart = code.slice(setupTag.index);
|
|
@@ -503,7 +533,7 @@ function createLayoutWrapperPlugin({ data, utils }) {
|
|
|
503
533
|
|
|
504
534
|
//#endregion
|
|
505
535
|
//#region package.json
|
|
506
|
-
var version = "52.
|
|
536
|
+
var version = "52.15.1";
|
|
507
537
|
|
|
508
538
|
//#endregion
|
|
509
539
|
//#region node/integrations/addons.ts
|
|
@@ -545,6 +575,8 @@ async function getThemeMeta(name, root) {
|
|
|
545
575
|
|
|
546
576
|
//#endregion
|
|
547
577
|
//#region node/setups/indexHtml.ts
|
|
578
|
+
const RE_TRAILING_SLASH = /\/$/;
|
|
579
|
+
const RE_BODY_CONTENT = /<body>([\s\S]*?)<\/body>/i;
|
|
548
580
|
function escapeHtml(str) {
|
|
549
581
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
550
582
|
}
|
|
@@ -555,7 +587,7 @@ function collectPreloadImages(data, base) {
|
|
|
555
587
|
if (data.config.preloadImages === false) return [];
|
|
556
588
|
const seen = /* @__PURE__ */ new Set();
|
|
557
589
|
const links = [];
|
|
558
|
-
const basePrefix = base ? base.replace(
|
|
590
|
+
const basePrefix = base ? base.replace(RE_TRAILING_SLASH, "") : "";
|
|
559
591
|
for (const slide of data.slides) {
|
|
560
592
|
const images = slide.images || slide.source?.images;
|
|
561
593
|
if (!images?.length) continue;
|
|
@@ -585,10 +617,11 @@ async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data,
|
|
|
585
617
|
console.error(yellow("This file may be generated by Slidev, please remove it from your project."));
|
|
586
618
|
continue;
|
|
587
619
|
}
|
|
588
|
-
inputs.push(
|
|
589
|
-
body += `\n${(html.match(
|
|
620
|
+
inputs.push(parseHtmlForUnheadExtraction(html).input);
|
|
621
|
+
body += `\n${(html.match(RE_BODY_CONTENT)?.[1] || "").trim()}`;
|
|
590
622
|
}
|
|
591
623
|
if (data.features.tweet) body += "\n<script async src=\"https://platform.twitter.com/widgets.js\"><\/script>";
|
|
624
|
+
if (data.features.bluesky) body += "\n<script async src=\"https://embed.bsky.app/static/embed.js\" charset=\"utf-8\"><\/script>";
|
|
592
625
|
const webFontsLink = [];
|
|
593
626
|
if (data.config.fonts.webfonts.length) {
|
|
594
627
|
const { provider } = data.config.fonts;
|
|
@@ -799,6 +832,7 @@ async function setupShiki(roots) {
|
|
|
799
832
|
|
|
800
833
|
//#endregion
|
|
801
834
|
//#region node/options.ts
|
|
835
|
+
const RE_FILE_EXTENSION = /\.\w+$/;
|
|
802
836
|
const debug = createDebug("slidev:options");
|
|
803
837
|
async function resolveOptions(entryOptions, mode) {
|
|
804
838
|
const entry = await resolveEntry(entryOptions.entry);
|
|
@@ -817,6 +851,7 @@ async function resolveOptions(entryOptions, mode) {
|
|
|
817
851
|
rootsInfo.userRoot
|
|
818
852
|
]);
|
|
819
853
|
if (entryOptions.download) config.download ||= entryOptions.download;
|
|
854
|
+
if (entryOptions.routerMode) config.routerMode = entryOptions.routerMode;
|
|
820
855
|
debug({
|
|
821
856
|
...rootsInfo,
|
|
822
857
|
...entryOptions,
|
|
@@ -875,7 +910,7 @@ async function createDataUtils(resolved) {
|
|
|
875
910
|
suppressErrors: true
|
|
876
911
|
})));
|
|
877
912
|
for (const layoutPath of layoutPaths.flat(1)) {
|
|
878
|
-
const layoutName = path.basename(layoutPath).replace(
|
|
913
|
+
const layoutName = path.basename(layoutPath).replace(RE_FILE_EXTENSION, "");
|
|
879
914
|
layouts[layoutName] = layoutPath;
|
|
880
915
|
}
|
|
881
916
|
return layouts;
|
|
@@ -906,52 +941,10 @@ function getDefine(options) {
|
|
|
906
941
|
}
|
|
907
942
|
|
|
908
943
|
//#endregion
|
|
909
|
-
//#region node/syntax/
|
|
944
|
+
//#region node/syntax/utils.ts
|
|
910
945
|
function normalizeRangeStr(rangeStr = "") {
|
|
911
946
|
return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
912
947
|
}
|
|
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
948
|
/**
|
|
956
949
|
* Escape `{{` in code block to prevent Vue interpret it, #99, #1316
|
|
957
950
|
*/
|
|
@@ -960,7 +953,8 @@ function escapeVueInCode(md) {
|
|
|
960
953
|
}
|
|
961
954
|
|
|
962
955
|
//#endregion
|
|
963
|
-
//#region node/syntax/
|
|
956
|
+
//#region node/syntax/katex.ts
|
|
957
|
+
const RE_KATEX_BLOCK_INFO = /^\{([\w*,|-]+)\}\s*(\{[^}]*\})?/;
|
|
964
958
|
function isValidDelim(state, pos) {
|
|
965
959
|
const max = state.posMax;
|
|
966
960
|
let can_open = true;
|
|
@@ -1015,7 +1009,7 @@ function math_inline(state, silent) {
|
|
|
1015
1009
|
state.pos = match + 1;
|
|
1016
1010
|
return true;
|
|
1017
1011
|
}
|
|
1018
|
-
|
|
1012
|
+
const math_block = function(state, start, end, silent) {
|
|
1019
1013
|
let firstLine;
|
|
1020
1014
|
let lastLine;
|
|
1021
1015
|
let next;
|
|
@@ -1026,11 +1020,13 @@ function math_block(state, start, end, silent) {
|
|
|
1026
1020
|
if (pos + 2 > max) return false;
|
|
1027
1021
|
if (state.src.slice(pos, pos + 2) !== "$$") return false;
|
|
1028
1022
|
pos += 2;
|
|
1029
|
-
firstLine = state.src.slice(pos, max);
|
|
1023
|
+
firstLine = state.src.slice(pos, max).trim();
|
|
1030
1024
|
if (silent) return true;
|
|
1031
|
-
|
|
1032
|
-
|
|
1025
|
+
let singleLine = false;
|
|
1026
|
+
if (firstLine.slice(-2) === "$$") {
|
|
1027
|
+
firstLine = firstLine.slice(0, -2).trim();
|
|
1033
1028
|
found = true;
|
|
1029
|
+
singleLine = true;
|
|
1034
1030
|
}
|
|
1035
1031
|
for (next = start; !found;) {
|
|
1036
1032
|
next++;
|
|
@@ -1047,11 +1043,15 @@ function math_block(state, start, end, silent) {
|
|
|
1047
1043
|
state.line = next + 1;
|
|
1048
1044
|
const token = state.push("math_block", "math", 0);
|
|
1049
1045
|
token.block = true;
|
|
1050
|
-
token.content =
|
|
1046
|
+
if (singleLine) token.content = firstLine;
|
|
1047
|
+
else {
|
|
1048
|
+
token.info = firstLine;
|
|
1049
|
+
token.content = state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : "");
|
|
1050
|
+
}
|
|
1051
1051
|
token.map = [start, state.line];
|
|
1052
1052
|
token.markup = "$$";
|
|
1053
1053
|
return true;
|
|
1054
|
-
}
|
|
1054
|
+
};
|
|
1055
1055
|
function MarkdownItKatex(md, options) {
|
|
1056
1056
|
const katexInline = function(latex) {
|
|
1057
1057
|
options.displayMode = false;
|
|
@@ -1075,7 +1075,10 @@ function MarkdownItKatex(md, options) {
|
|
|
1075
1075
|
}
|
|
1076
1076
|
};
|
|
1077
1077
|
const blockRenderer = function(tokens, idx) {
|
|
1078
|
-
|
|
1078
|
+
const token = tokens[idx];
|
|
1079
|
+
const [, rangeStr, options$1] = RE_KATEX_BLOCK_INFO.exec(token.info) || [];
|
|
1080
|
+
const ranges = normalizeRangeStr(rangeStr);
|
|
1081
|
+
return `<KaTexBlockWrapper ${options$1 ? `v-bind="${options$1}"` : ""} :ranges='${JSON.stringify(ranges)}'>${katexBlock(tokens[idx].content)}</KaTexBlockWrapper>\n`;
|
|
1079
1082
|
};
|
|
1080
1083
|
md.inline.ruler.after("escape", "math_inline", math_inline);
|
|
1081
1084
|
md.block.ruler.after("blockquote", "math_block", math_block, { alt: [
|
|
@@ -1088,6 +1091,23 @@ function MarkdownItKatex(md, options) {
|
|
|
1088
1091
|
md.renderer.rules.math_block = blockRenderer;
|
|
1089
1092
|
}
|
|
1090
1093
|
|
|
1094
|
+
//#endregion
|
|
1095
|
+
//#region node/virtual/conditional-styles.ts
|
|
1096
|
+
const id$1 = "/@slidev/conditional-styles";
|
|
1097
|
+
const templateConditionalStyles = {
|
|
1098
|
+
id: id$1,
|
|
1099
|
+
async getContent({ data, roots, userRoot }) {
|
|
1100
|
+
const imports = [];
|
|
1101
|
+
for (const root of roots) imports.push(makeAbsoluteImportGlob(id$1, [
|
|
1102
|
+
join(root, "styles/index.{ts,js,css}"),
|
|
1103
|
+
join(root, "styles.{ts,js,css}"),
|
|
1104
|
+
join(root, "style.{ts,js,css}")
|
|
1105
|
+
], {}, userRoot));
|
|
1106
|
+
if (data.features.katex) imports.push(`import "${await resolveImportUrl("katex/dist/katex.min.css")}"`);
|
|
1107
|
+
return imports.join("\n");
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1091
1111
|
//#endregion
|
|
1092
1112
|
//#region node/virtual/configs.ts
|
|
1093
1113
|
const templateConfigs = {
|
|
@@ -1138,15 +1158,16 @@ console.warn('/@slidev/titles.md is deprecated, import from #slidev/title-render
|
|
|
1138
1158
|
|
|
1139
1159
|
//#endregion
|
|
1140
1160
|
//#region node/virtual/global-layers.ts
|
|
1161
|
+
const id = `/@slidev/global-layers`;
|
|
1141
1162
|
const templateGlobalLayers = {
|
|
1142
|
-
id
|
|
1143
|
-
getContent({
|
|
1163
|
+
id,
|
|
1164
|
+
getContent({ roots, userRoot }) {
|
|
1144
1165
|
function* getComponent(name, names) {
|
|
1145
1166
|
yield `const ${name}Components = [\n`;
|
|
1146
1167
|
for (const root of roots) {
|
|
1147
1168
|
const globs = names.map((name$1) => join(root, `${name$1}.{ts,js,vue}`));
|
|
1148
1169
|
yield " Object.values(";
|
|
1149
|
-
yield makeAbsoluteImportGlob(
|
|
1170
|
+
yield makeAbsoluteImportGlob(id, globs, { import: "default" }, userRoot);
|
|
1150
1171
|
yield ")[0],\n";
|
|
1151
1172
|
}
|
|
1152
1173
|
yield `].filter(Boolean)\n`;
|
|
@@ -1262,11 +1283,12 @@ export default {
|
|
|
1262
1283
|
//#endregion
|
|
1263
1284
|
//#region node/virtual/setups.ts
|
|
1264
1285
|
function createSetupTemplate(name) {
|
|
1286
|
+
const id$2 = `/@slidev/setups/${name}`;
|
|
1265
1287
|
return {
|
|
1266
|
-
id:
|
|
1267
|
-
getContent({
|
|
1288
|
+
id: id$2,
|
|
1289
|
+
getContent({ roots, userRoot }) {
|
|
1268
1290
|
return `export default [${roots.map((root) => {
|
|
1269
|
-
return `Object.values(${makeAbsoluteImportGlob(
|
|
1291
|
+
return `Object.values(${makeAbsoluteImportGlob(id$2, [join(root, `setup/${name}.{ts,js,mts,mjs}`)], { import: "default" }, userRoot)})[0]`;
|
|
1270
1292
|
}).join(", ")}].filter(Boolean)`;
|
|
1271
1293
|
}
|
|
1272
1294
|
};
|
|
@@ -1323,34 +1345,6 @@ const templateSlides = {
|
|
|
1323
1345
|
}
|
|
1324
1346
|
};
|
|
1325
1347
|
|
|
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
1348
|
//#endregion
|
|
1355
1349
|
//#region node/virtual/titles.ts
|
|
1356
1350
|
const templateTitleRendererMd = {
|
|
@@ -1374,7 +1368,7 @@ const templates = [
|
|
|
1374
1368
|
templateMonacoTypes,
|
|
1375
1369
|
templateMonacoRunDeps,
|
|
1376
1370
|
templateConfigs,
|
|
1377
|
-
|
|
1371
|
+
templateConditionalStyles,
|
|
1378
1372
|
templateGlobalLayers,
|
|
1379
1373
|
templateNavControls,
|
|
1380
1374
|
templateSlides,
|
|
@@ -1388,6 +1382,7 @@ const templates = [
|
|
|
1388
1382
|
|
|
1389
1383
|
//#endregion
|
|
1390
1384
|
//#region node/vite/loaders.ts
|
|
1385
|
+
const RE_WORD_CHARS_ONLY = /^[\w-]+$/;
|
|
1391
1386
|
function createSlidesLoader(options, serverOptions) {
|
|
1392
1387
|
const { data, mode, utils, withoutNotes } = options;
|
|
1393
1388
|
const notesMd = MarkdownExit({ html: true });
|
|
@@ -1528,32 +1523,32 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1528
1523
|
const moduleEntries = [
|
|
1529
1524
|
...ctx.modules.filter((i) => i.id === templateMonacoRunDeps.id || i.id === templateMonacoTypes.id),
|
|
1530
1525
|
...vueModules,
|
|
1531
|
-
...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
|
|
1526
|
+
...Array.from(moduleIds).map((id$2) => ctx.server.moduleGraph.getModuleById(id$2))
|
|
1532
1527
|
].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
|
|
1533
1528
|
updateServerWatcher();
|
|
1534
1529
|
return moduleEntries;
|
|
1535
1530
|
},
|
|
1536
1531
|
resolveId: {
|
|
1537
1532
|
order: "pre",
|
|
1538
|
-
handler(id) {
|
|
1539
|
-
if (id.startsWith("/@slidev/") || id.includes("__slidev_")) return id;
|
|
1533
|
+
handler(id$2) {
|
|
1534
|
+
if (id$2.startsWith("/@slidev/") || id$2.includes("__slidev_")) return id$2;
|
|
1540
1535
|
return null;
|
|
1541
1536
|
}
|
|
1542
1537
|
},
|
|
1543
|
-
async load(id) {
|
|
1544
|
-
const template = templates.find((i) => i.id === id);
|
|
1538
|
+
async load(id$2) {
|
|
1539
|
+
const template = templates.find((i) => i.id === id$2);
|
|
1545
1540
|
if (template) return {
|
|
1546
1541
|
code: await template.getContent.call(this, options),
|
|
1547
1542
|
map: { mappings: "" }
|
|
1548
1543
|
};
|
|
1549
|
-
const matchFacade = id.match(regexSlideFacadeId);
|
|
1544
|
+
const matchFacade = id$2.match(regexSlideFacadeId);
|
|
1550
1545
|
if (matchFacade) {
|
|
1551
1546
|
const [, no, type] = matchFacade;
|
|
1552
1547
|
const idx = +no - 1;
|
|
1553
1548
|
const sourceId = JSON.stringify(sourceIds[type][idx]);
|
|
1554
1549
|
return [`export * from ${sourceId}`, `export { default } from ${sourceId}`].join("\n");
|
|
1555
1550
|
}
|
|
1556
|
-
const matchSource = id.match(regexSlideSourceId);
|
|
1551
|
+
const matchSource = id$2.match(regexSlideSourceId);
|
|
1557
1552
|
if (matchSource) {
|
|
1558
1553
|
const [, no, type] = matchSource;
|
|
1559
1554
|
const idx = +no - 1;
|
|
@@ -1616,7 +1611,7 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1616
1611
|
};
|
|
1617
1612
|
}
|
|
1618
1613
|
}
|
|
1619
|
-
if (data.markdownFiles[id]) return "";
|
|
1614
|
+
if (data.markdownFiles[id$2]) return "";
|
|
1620
1615
|
}
|
|
1621
1616
|
};
|
|
1622
1617
|
function renderNote(text = "") {
|
|
@@ -1627,7 +1622,7 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1627
1622
|
clickCount += Number(count);
|
|
1628
1623
|
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
1629
1624
|
});
|
|
1630
|
-
const keys = Object.keys(notesAutoRuby).sort((b, a) => b.length - a.length).map((i) =>
|
|
1625
|
+
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
1626
|
if (keys.length) {
|
|
1632
1627
|
const regex = new RegExp(`(${keys.join("|")})`, "g");
|
|
1633
1628
|
md = md.replace(regex, (match) => {
|
|
@@ -1646,6 +1641,29 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1646
1641
|
}
|
|
1647
1642
|
}
|
|
1648
1643
|
|
|
1644
|
+
//#endregion
|
|
1645
|
+
//#region node/setups/transformers.ts
|
|
1646
|
+
async function setupTransformers(roots) {
|
|
1647
|
+
const returns = await loadSetups(roots, "transformers.ts", []);
|
|
1648
|
+
const result = {
|
|
1649
|
+
pre: [],
|
|
1650
|
+
preCodeblock: [],
|
|
1651
|
+
postCodeblock: [],
|
|
1652
|
+
post: [],
|
|
1653
|
+
codeblocks: []
|
|
1654
|
+
};
|
|
1655
|
+
for (const r of [...returns].reverse()) {
|
|
1656
|
+
if (r.pre) result.pre.push(...r.pre);
|
|
1657
|
+
if (r.preCodeblock) result.preCodeblock.push(...r.preCodeblock);
|
|
1658
|
+
}
|
|
1659
|
+
for (const r of returns) {
|
|
1660
|
+
if (r.postCodeblock) result.postCodeblock.push(...r.postCodeblock);
|
|
1661
|
+
if (r.post) result.post.push(...r.post);
|
|
1662
|
+
if (r.codeblocks) result.codeblocks.push(...r.codeblocks);
|
|
1663
|
+
}
|
|
1664
|
+
return result;
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1649
1667
|
//#endregion
|
|
1650
1668
|
//#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
1669
|
var SpecialCharacters;
|
|
@@ -1865,11 +1883,11 @@ function isTodoItem(tokens, index) {
|
|
|
1865
1883
|
}
|
|
1866
1884
|
function todoify(token, options) {
|
|
1867
1885
|
if (token.children == null) return;
|
|
1868
|
-
const id = generateIdForToken(token);
|
|
1869
|
-
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
1886
|
+
const id$2 = generateIdForToken(token);
|
|
1887
|
+
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id$2));
|
|
1870
1888
|
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
1871
1889
|
if (options.label) {
|
|
1872
|
-
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
1890
|
+
token.children.splice(1, 0, createLabelBeginToken(id$2));
|
|
1873
1891
|
token.children.push(createLabelEndToken());
|
|
1874
1892
|
}
|
|
1875
1893
|
}
|
|
@@ -1877,17 +1895,17 @@ function generateIdForToken(token) {
|
|
|
1877
1895
|
if (token.map) return `task-item-${token.map[0]}`;
|
|
1878
1896
|
else return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
|
|
1879
1897
|
}
|
|
1880
|
-
function createCheckboxToken(token, enabled, id) {
|
|
1898
|
+
function createCheckboxToken(token, enabled, id$2) {
|
|
1881
1899
|
const checkbox = new token_default("taskListItemCheckbox", "", 0);
|
|
1882
1900
|
if (!enabled) checkbox.attrSet("disabled", "true");
|
|
1883
1901
|
if (token.map) checkbox.attrSet("line", token.map[0].toString());
|
|
1884
|
-
checkbox.attrSet("id", id);
|
|
1902
|
+
checkbox.attrSet("id", id$2);
|
|
1885
1903
|
if (checkboxRegex.exec(token.content)?.[1].toLowerCase() === "x") checkbox.attrSet("checked", "true");
|
|
1886
1904
|
return checkbox;
|
|
1887
1905
|
}
|
|
1888
|
-
function createLabelBeginToken(id) {
|
|
1906
|
+
function createLabelBeginToken(id$2) {
|
|
1889
1907
|
const labelBeginToken = new token_default("taskListItemLabel_open", "", 1);
|
|
1890
|
-
labelBeginToken.attrSet("id", id);
|
|
1908
|
+
labelBeginToken.attrSet("id", id$2);
|
|
1891
1909
|
return labelBeginToken;
|
|
1892
1910
|
}
|
|
1893
1911
|
function createLabelEndToken() {
|
|
@@ -1907,62 +1925,139 @@ function startsWithTodoMarkdown(token) {
|
|
|
1907
1925
|
}
|
|
1908
1926
|
|
|
1909
1927
|
//#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
|
-
|
|
1928
|
+
//#region node/syntax/codeblock/magic-move.ts
|
|
1929
|
+
const RE_MAGIC_MOVE_INFO = /^(?:md|markdown) magic-move\s*(?:\[([^\]]*)\])?\s*(\{[^}]*\})?/;
|
|
1930
|
+
const RE_CODE_BLOCK = /^```([\w'-]+)?(?:[ \t]*|[ \t][ \w\t'-]*)(?:\[([^\]]*)\])?[ \t]*(?:\{([\w*,|-]+)\}[ \t]*(\{[^}]*\})?([^\r\n]*))?\r?\n((?:(?!^```)[\s\S])*?)^```$/gm;
|
|
1931
|
+
const RE_LINES_TRUE = /\blines: *true\b/;
|
|
1932
|
+
const RE_LINES_FALSE = /\blines: *false\b/;
|
|
1933
|
+
function parseLineNumbersOption(options) {
|
|
1934
|
+
return RE_LINES_TRUE.test(options) ? true : RE_LINES_FALSE.test(options) ? false : void 0;
|
|
1935
|
+
}
|
|
1936
|
+
var magic_move_default = defineCodeblockTransformer(async ({ info, fence, code, options: { data: { config }, utils: { shikiOptions, shiki } } }) => {
|
|
1937
|
+
if (fence !== 4) return;
|
|
1938
|
+
const match = info.match(RE_MAGIC_MOVE_INFO);
|
|
1939
|
+
if (!match) return;
|
|
1940
|
+
const [, title = "", options = "{}"] = match;
|
|
1941
|
+
const defaultLineNumbers = parseLineNumbersOption(options) ?? config.lineNumbers;
|
|
1942
|
+
const matches = Array.from(code.matchAll(RE_CODE_BLOCK));
|
|
1943
|
+
if (!matches.length) throw new Error("Magic Move block must contain at least one code block");
|
|
1944
|
+
const ranges = matches.map((i) => normalizeRangeStr(i[3]));
|
|
1945
|
+
const steps = await Promise.all(matches.map(async (i) => {
|
|
1946
|
+
const lang = i[1];
|
|
1947
|
+
const lineNumbers = parseLineNumbersOption(i[4]) ?? defaultLineNumbers;
|
|
1948
|
+
const code$1 = i[6].trimEnd();
|
|
1949
|
+
const options$1 = {
|
|
1950
|
+
...shikiOptions,
|
|
1951
|
+
lang
|
|
1952
|
+
};
|
|
1953
|
+
const { tokens, bg, fg: fg$1, rootStyle, themeName } = await shiki.codeToTokens(code$1, options$1);
|
|
1954
|
+
return {
|
|
1955
|
+
...toKeyedTokens(code$1, tokens, JSON.stringify([lang, "themes" in options$1 ? options$1.themes : options$1.theme]), lineNumbers),
|
|
1956
|
+
bg,
|
|
1957
|
+
fg: fg$1,
|
|
1958
|
+
rootStyle,
|
|
1959
|
+
themeName,
|
|
1960
|
+
lang
|
|
1961
|
+
};
|
|
1962
|
+
}));
|
|
1963
|
+
return `<ShikiMagicMove v-bind="${options}" steps-lz="${lz.compressToBase64(JSON.stringify(steps))}" :title='${JSON.stringify(title)}' :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
1964
|
+
});
|
|
1965
|
+
|
|
1966
|
+
//#endregion
|
|
1967
|
+
//#region node/syntax/codeblock/mermaid.ts
|
|
1968
|
+
const RE_MERMAID = /^mermaid\s*(\{[^\n]*\})?/;
|
|
1969
|
+
var mermaid_default = defineCodeblockTransformer(async ({ info, code }) => {
|
|
1970
|
+
const match = info.match(RE_MERMAID);
|
|
1971
|
+
if (!match) return;
|
|
1972
|
+
const [, options] = match;
|
|
1973
|
+
return `<Mermaid ${options ? `v-bind="${options}"` : ""} code-lz="${lz.compressToBase64(code.trim())}" />`;
|
|
1974
|
+
});
|
|
1975
|
+
|
|
1976
|
+
//#endregion
|
|
1977
|
+
//#region node/syntax/codeblock/monaco.ts
|
|
1978
|
+
const RE_MONACO = /^([\w'-]+)?\s*\{(monaco[\w-]*)\}\s*(\{[^}]*\})?(.*)$/;
|
|
1979
|
+
const RE_DIFF_SEPARATOR = /^\s*~~~\s*\n/m;
|
|
1980
|
+
var monaco_default = defineCodeblockTransformer(async ({ info, code, options: { data: { config }, mode } }) => {
|
|
1981
|
+
const match = info.match(RE_MONACO);
|
|
1982
|
+
if (!match) return;
|
|
1983
|
+
const [, lang = "", monaco, options] = match;
|
|
1984
|
+
if (!(config.monaco === true || config.monaco === mode)) return;
|
|
1985
|
+
let encoded;
|
|
1986
|
+
let diff = "";
|
|
1987
|
+
if (monaco === "monaco-diff") {
|
|
1988
|
+
const [original, modified] = code.split(RE_DIFF_SEPARATOR, 2);
|
|
1989
|
+
encoded = lz.compressToBase64(original);
|
|
1990
|
+
diff = modified === void 0 ? "" : `diff-lz="${lz.compressToBase64(modified)}"`;
|
|
1991
|
+
} else encoded = lz.compressToBase64(code);
|
|
1992
|
+
return `<Monaco ${options ? `v-bind="${options}"` : ""} ${monaco === "monaco-run" ? "runnable" : ""} lang="${lang}" code-lz="${encoded}" ${diff} />`;
|
|
1993
|
+
});
|
|
1994
|
+
|
|
1995
|
+
//#endregion
|
|
1996
|
+
//#region node/syntax/codeblock/plant-uml.ts
|
|
1997
|
+
const RE_PLANT_UML = /^plantuml\s*(\{[^\n]*\})?/;
|
|
1998
|
+
var plant_uml_default = defineCodeblockTransformer(async ({ info, code, options: { data: { config: { plantUmlServer } } } }) => {
|
|
1999
|
+
const match = info.match(RE_PLANT_UML);
|
|
2000
|
+
if (!match) return;
|
|
2001
|
+
const [, options] = match;
|
|
2002
|
+
return `<PlantUml ${options ? `v-bind="${options}"` : ""} code="${encode(code.trim())}"${plantUmlServer === void 0 ? "" : ` server=${JSON.stringify(plantUmlServer)}`} />`;
|
|
2003
|
+
});
|
|
2004
|
+
|
|
2005
|
+
//#endregion
|
|
2006
|
+
//#region node/syntax/codeblock/wrapper.ts
|
|
2007
|
+
const RE_BLOCK_INFO = /^([\w'-]+)?(?:[ \t]*|[ \t][ \w\t'-]*)(?:\[([^\]]*)\])?[ \t]*(?:\{([\w,|\-*]+)\})?[ \t]*(\{[^}]*\})?(.*)$/;
|
|
2008
|
+
var wrapper_default = defineCodeblockTransformer(async ({ info, renderHighlighted }) => {
|
|
2009
|
+
const [, lang = "", title = "", rangeStr = "", options, rest = ""] = info.match(RE_BLOCK_INFO) ?? [];
|
|
2010
|
+
const ranges = normalizeRangeStr(rangeStr);
|
|
2011
|
+
const optionsProp = options ? `v-bind="${options}"` : "";
|
|
2012
|
+
const code = await renderHighlighted({ info: `${lang} ${rest}` });
|
|
2013
|
+
return `<CodeBlockWrapper ${optionsProp} title=${JSON.stringify(title)} :ranges='${JSON.stringify(ranges)}'>${escapeVueInCode(code)}</CodeBlockWrapper>`;
|
|
2014
|
+
});
|
|
2015
|
+
|
|
2016
|
+
//#endregion
|
|
2017
|
+
//#region node/syntax/codeblock/index.ts
|
|
2018
|
+
function MarkdownItCodeblocks(md, options, extraTransformers) {
|
|
2019
|
+
const oldFence = md.renderer.rules.fence;
|
|
2020
|
+
md.renderer.rules.fence = async function(tokens, idx, renderOptions, env, slf) {
|
|
2021
|
+
const token = tokens[idx];
|
|
2022
|
+
const slideNo = env.id?.match(regexSlideSourceId);
|
|
2023
|
+
const ctx = {
|
|
2024
|
+
info: token.info.trim(),
|
|
2025
|
+
code: token.content,
|
|
2026
|
+
fence: token.markup.length,
|
|
2027
|
+
slide: slideNo ? options.data.slides[slideNo[1] - 1] : null,
|
|
2028
|
+
options,
|
|
2029
|
+
renderHighlighted(override) {
|
|
2030
|
+
if (override.info != null) token.info = override.info;
|
|
2031
|
+
if (override.code != null) token.content = override.code;
|
|
2032
|
+
return oldFence(tokens, idx, renderOptions, env, slf);
|
|
1948
2033
|
}
|
|
2034
|
+
};
|
|
2035
|
+
const transformers = [
|
|
2036
|
+
...extraTransformers,
|
|
2037
|
+
mermaid_default,
|
|
2038
|
+
plant_uml_default,
|
|
2039
|
+
magic_move_default,
|
|
2040
|
+
monaco_default,
|
|
2041
|
+
wrapper_default
|
|
2042
|
+
];
|
|
2043
|
+
for (const transformer of transformers) {
|
|
2044
|
+
if (!transformer) continue;
|
|
2045
|
+
const res = await transformer(ctx);
|
|
2046
|
+
if (res != null) return ensureSuffix("\n", res);
|
|
1949
2047
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
...shikiOptions,
|
|
1953
|
-
transformers
|
|
1954
|
-
});
|
|
2048
|
+
throw new Error("Should not reach here");
|
|
2049
|
+
};
|
|
1955
2050
|
}
|
|
1956
2051
|
|
|
1957
2052
|
//#endregion
|
|
1958
|
-
//#region node/syntax/
|
|
2053
|
+
//#region node/syntax/drag.ts
|
|
1959
2054
|
const dragComponentRegex = /<(v-?drag-?\w*)([\s>])/i;
|
|
1960
2055
|
const dragDirectiveRegex = /(?<![</\w])v-drag(=".*?")?/i;
|
|
1961
2056
|
function MarkdownItVDrag(md, markdownTransformMap) {
|
|
1962
2057
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
1963
2058
|
const sourceMapConsumers = /* @__PURE__ */ new WeakMap();
|
|
1964
|
-
function getSourceMapConsumer(id) {
|
|
1965
|
-
const s = markdownTransformMap.get(id);
|
|
2059
|
+
function getSourceMapConsumer(id$2) {
|
|
2060
|
+
const s = id$2 && markdownTransformMap.get(id$2);
|
|
1966
2061
|
if (!s) return void 0;
|
|
1967
2062
|
let smc = sourceMapConsumers.get(s);
|
|
1968
2063
|
if (smc) return smc;
|
|
@@ -1976,7 +2071,7 @@ function MarkdownItVDrag(md, markdownTransformMap) {
|
|
|
1976
2071
|
}
|
|
1977
2072
|
const _parse = md.parse;
|
|
1978
2073
|
md.parse = function(src, env) {
|
|
1979
|
-
const smc = getSourceMapConsumer(env
|
|
2074
|
+
const smc = getSourceMapConsumer(env?.id);
|
|
1980
2075
|
const toOriginalPos = smc ? (line) => smc.originalPositionFor({
|
|
1981
2076
|
line: line + 1,
|
|
1982
2077
|
column: 0
|
|
@@ -2014,211 +2109,126 @@ function MarkdownItVDrag(md, markdownTransformMap) {
|
|
|
2014
2109
|
}
|
|
2015
2110
|
|
|
2016
2111
|
//#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: []
|
|
2112
|
+
//#region node/syntax/escape-code.ts
|
|
2113
|
+
const RE_CODE_TAG_OPEN = /^<code/;
|
|
2114
|
+
function MarkdownItEscapeInlineCode(md) {
|
|
2115
|
+
const codeInline = md.renderer.rules.code_inline;
|
|
2116
|
+
md.renderer.rules.code_inline = async (tokens, idx, options, env, self) => {
|
|
2117
|
+
return (await codeInline(tokens, idx, options, env, self)).replace(RE_CODE_TAG_OPEN, "<code v-pre");
|
|
2043
2118
|
};
|
|
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
2119
|
}
|
|
2085
2120
|
|
|
2086
2121
|
//#endregion
|
|
2087
|
-
//#region node/syntax/
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2122
|
+
//#region node/syntax/scoped.ts
|
|
2123
|
+
const RE_STYLE_TAG_OPEN = /<style\b([^>]*)>/gi;
|
|
2124
|
+
const RE_SCOPED_ATTR = /\bscoped\b/i;
|
|
2125
|
+
function MarkdownItStyleScoped(md) {
|
|
2126
|
+
const addScoped = (html) => {
|
|
2127
|
+
return html.replace(RE_STYLE_TAG_OPEN, (match, attrs) => {
|
|
2128
|
+
if (RE_SCOPED_ATTR.test(attrs)) return match;
|
|
2129
|
+
return `<style scoped${attrs}>`;
|
|
2130
|
+
});
|
|
2131
|
+
};
|
|
2132
|
+
const htmlBlock = md.renderer.rules.html_block;
|
|
2133
|
+
md.renderer.rules.html_block = async (...args) => addScoped(await htmlBlock(...args));
|
|
2134
|
+
const htmlInline = md.renderer.rules.html_inline;
|
|
2135
|
+
md.renderer.rules.html_inline = async (...args) => addScoped(await htmlInline(...args));
|
|
2098
2136
|
}
|
|
2099
2137
|
|
|
2100
2138
|
//#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()
|
|
2139
|
+
//#region node/syntax/shiki.ts
|
|
2140
|
+
async function MarkdownItShiki({ data: { config }, mode, utils: { shiki, shikiOptions } }) {
|
|
2141
|
+
async function getTwoslashTransformer() {
|
|
2142
|
+
const [, , { transformerTwoslash }] = await Promise.all([
|
|
2143
|
+
shiki.codeToHast("", {
|
|
2144
|
+
lang: "js",
|
|
2145
|
+
...shikiOptions
|
|
2146
|
+
}),
|
|
2147
|
+
shiki.codeToHast("", {
|
|
2148
|
+
lang: "ts",
|
|
2149
|
+
...shikiOptions
|
|
2150
|
+
}),
|
|
2151
|
+
import("@shikijs/vitepress-twoslash")
|
|
2118
2152
|
]);
|
|
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;
|
|
2153
|
+
return transformerTwoslash({
|
|
2154
|
+
explicitTrigger: true,
|
|
2155
|
+
twoslashOptions: { handbookOptions: { noErrorValidation: true } }
|
|
2156
|
+
});
|
|
2168
2157
|
}
|
|
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}" />`;
|
|
2158
|
+
const transformers = [
|
|
2159
|
+
...shikiOptions.transformers || [],
|
|
2160
|
+
(config.twoslash === true || config.twoslash === mode) && await getTwoslashTransformer(),
|
|
2161
|
+
(config.twoslash === true || config.twoslash === mode) && transformerTwoslashConditional(),
|
|
2162
|
+
{ pre(pre) {
|
|
2163
|
+
this.addClassToHast(pre, "slidev-code");
|
|
2164
|
+
delete pre.properties.tabindex;
|
|
2165
|
+
} }
|
|
2166
|
+
].filter(isTruthy);
|
|
2167
|
+
return fromAsyncCodeToHtml(shiki.codeToHtml, {
|
|
2168
|
+
...shikiOptions,
|
|
2169
|
+
transformers
|
|
2183
2170
|
});
|
|
2184
2171
|
}
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
function
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
});
|
|
2172
|
+
function transformerTwoslashConditional() {
|
|
2173
|
+
return {
|
|
2174
|
+
name: "slidev:twoslash-conditional",
|
|
2175
|
+
code: function applyConditionalFlag(node) {
|
|
2176
|
+
if (node.tagName === "v-menu") {
|
|
2177
|
+
if (node.properties[":shown"] === "true") node.properties[":shown"] = "$nav.currentPage === $page";
|
|
2178
|
+
} else for (const child of node.children) if (child.type === "element") applyConditionalFlag(child);
|
|
2179
|
+
}
|
|
2180
|
+
};
|
|
2195
2181
|
}
|
|
2196
2182
|
|
|
2197
2183
|
//#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
|
-
|
|
2184
|
+
//#region node/syntax/slot-sugar.ts
|
|
2185
|
+
const RE_SLOT_MARKER = /^::\s*([\w.\-:]+)\s*::\s*$/;
|
|
2186
|
+
function MarkdownItSlotSugar(md) {
|
|
2187
|
+
md.block.ruler.before("fence", "slot_marker", (state, startLine, _endLine, silent) => {
|
|
2188
|
+
if (state.sCount[startLine] - state.blkIndent > 0) return false;
|
|
2189
|
+
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
2190
|
+
const max = state.eMarks[startLine];
|
|
2191
|
+
const match = state.src.slice(pos, max).match(RE_SLOT_MARKER);
|
|
2192
|
+
if (!match) return false;
|
|
2193
|
+
if (silent) return true;
|
|
2194
|
+
const token = state.push("slot_marker", "", 0);
|
|
2195
|
+
token.meta = { slotName: match[1] };
|
|
2196
|
+
token.map = [startLine, startLine + 1];
|
|
2197
|
+
state.line = startLine + 1;
|
|
2198
|
+
state.env.hasSlotMarker = true;
|
|
2199
|
+
return true;
|
|
2200
|
+
}, { alt: [
|
|
2201
|
+
"paragraph",
|
|
2202
|
+
"reference",
|
|
2203
|
+
"blockquote",
|
|
2204
|
+
"list"
|
|
2205
|
+
] });
|
|
2206
|
+
md.core.ruler.push("slot_sugar_compiler", (state) => {
|
|
2207
|
+
if (!state.env.hasSlotMarker) return;
|
|
2208
|
+
const tokens = state.tokens;
|
|
2209
|
+
const newTokens = [];
|
|
2210
|
+
let hasOpenSlot = false;
|
|
2211
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
2212
|
+
const token = tokens[i];
|
|
2213
|
+
if (token.type === "slot_marker") {
|
|
2214
|
+
if (hasOpenSlot) {
|
|
2215
|
+
const closeHtml = new state.Token("html_block", "", 0);
|
|
2216
|
+
closeHtml.content = "\n</template>\n";
|
|
2217
|
+
newTokens.push(closeHtml);
|
|
2218
|
+
}
|
|
2219
|
+
const openHtml = new state.Token("html_block", "", 0);
|
|
2220
|
+
openHtml.content = `\n<template v-slot:${token.meta.slotName}="slotProps">\n`;
|
|
2221
|
+
newTokens.push(openHtml);
|
|
2222
|
+
hasOpenSlot = true;
|
|
2223
|
+
} else newTokens.push(token);
|
|
2224
|
+
}
|
|
2225
|
+
if (hasOpenSlot) {
|
|
2226
|
+
const closeHtml = new state.Token("html_block", "", 0);
|
|
2227
|
+
closeHtml.content = "\n</template>\n";
|
|
2228
|
+
newTokens.push(closeHtml);
|
|
2219
2229
|
}
|
|
2230
|
+
state.tokens = newTokens;
|
|
2220
2231
|
});
|
|
2221
|
-
if (prevSlot) ctx.s.append("\n\n</template>");
|
|
2222
2232
|
}
|
|
2223
2233
|
|
|
2224
2234
|
//#endregion
|
|
@@ -2254,7 +2264,8 @@ function createMonacoWriterPlugin({ userRoot }) {
|
|
|
2254
2264
|
}
|
|
2255
2265
|
|
|
2256
2266
|
//#endregion
|
|
2257
|
-
//#region node/syntax/
|
|
2267
|
+
//#region node/syntax/snippet.ts
|
|
2268
|
+
const RE_NEWLINE = /\r?\n/;
|
|
2258
2269
|
function dedent(text) {
|
|
2259
2270
|
const lines = text.split("\n");
|
|
2260
2271
|
const minIndentLength = lines.reduce((acc, line) => {
|
|
@@ -2327,76 +2338,96 @@ function findRegion(lines, regionName) {
|
|
|
2327
2338
|
}
|
|
2328
2339
|
return null;
|
|
2329
2340
|
}
|
|
2330
|
-
const
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
const src = slash(
|
|
2341
|
+
const RE_SNIPPET_IMPORT = /^<<<[ \t]*(\S.*?)(#[\w-]+)?[ \t]*(?:[ \t](\S+?))?[ \t]*(\{.*)?$/;
|
|
2342
|
+
function MarkdownItSnippet(md, { userRoot, data: { watchFiles, slides } }) {
|
|
2343
|
+
md.block.ruler.before("fence", "snippet_import", (state, startLine, _endLine, silent) => {
|
|
2344
|
+
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
2345
|
+
const max = state.eMarks[startLine];
|
|
2346
|
+
const match = state.src.slice(pos, max).match(RE_SNIPPET_IMPORT);
|
|
2347
|
+
if (!match) return false;
|
|
2348
|
+
if (silent) return true;
|
|
2349
|
+
let [, filepath = "", regionName = "", lang = "", meta = ""] = match;
|
|
2350
|
+
const slideNo = state.env.id?.match(regexSlideSourceId);
|
|
2351
|
+
const slide = slideNo ? slides[slideNo[1] - 1] : null;
|
|
2352
|
+
if (!slide) {
|
|
2353
|
+
console.warn(yellow(`[markdown-it-snippet] Snippet syntax is not supported in ${state.env.id || "unknown source"}. Skipped.`));
|
|
2354
|
+
return false;
|
|
2355
|
+
}
|
|
2356
|
+
const dir = path.dirname(slide.source.filepath);
|
|
2357
|
+
const src = slash(filepath.startsWith("@/") ? path.resolve(userRoot, filepath.slice(2)) : path.resolve(dir, filepath));
|
|
2358
|
+
lang = lang.trim() || path.extname(filepath).slice(1);
|
|
2347
2359
|
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`);
|
|
2360
|
+
if (!(fs.existsSync(src) && fs.statSync(src).isFile())) throw new Error(`Code snippet path not found: ${src}`);
|
|
2352
2361
|
let content = fs.readFileSync(src, "utf8");
|
|
2353
2362
|
if (regionName) {
|
|
2354
|
-
const lines = content.split(
|
|
2363
|
+
const lines = content.split(RE_NEWLINE);
|
|
2355
2364
|
const region = findRegion(lines, regionName.slice(1));
|
|
2356
2365
|
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
2366
|
}
|
|
2358
|
-
if (meta.
|
|
2367
|
+
if (meta.includes("{monaco-write}")) {
|
|
2359
2368
|
monacoWriterWhitelist.add(filepath);
|
|
2360
2369
|
lang = lang.trim();
|
|
2361
|
-
meta = meta.replace(
|
|
2370
|
+
meta = meta.replace("{monaco-write}", "").trim() || "{}";
|
|
2371
|
+
const safeFilepath = JSON.stringify(filepath).slice(1, -1);
|
|
2362
2372
|
const encoded = lz.compressToBase64(content);
|
|
2363
|
-
|
|
2373
|
+
const token = state.push("html_block", "", 0);
|
|
2374
|
+
token.content = `<Monaco writable="${safeFilepath}" code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />\n`;
|
|
2375
|
+
token.map = [startLine, startLine + 1];
|
|
2364
2376
|
} else {
|
|
2365
2377
|
watchFiles[src] ??= /* @__PURE__ */ new Set();
|
|
2366
2378
|
watchFiles[src].add(slide.index);
|
|
2379
|
+
const token = state.push("fence", "code", 0);
|
|
2380
|
+
token.info = `${lang} ${meta}`.trim();
|
|
2381
|
+
token.content = content.endsWith("\n") ? content : `${content}\n`;
|
|
2382
|
+
token.map = [startLine, startLine + 1];
|
|
2367
2383
|
}
|
|
2368
|
-
|
|
2384
|
+
state.line = startLine + 1;
|
|
2385
|
+
return true;
|
|
2386
|
+
}, { alt: [
|
|
2387
|
+
"paragraph",
|
|
2388
|
+
"reference",
|
|
2389
|
+
"blockquote",
|
|
2390
|
+
"list"
|
|
2391
|
+
] });
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
//#endregion
|
|
2395
|
+
//#region node/syntax/index.ts
|
|
2396
|
+
async function useMarkdownItPlugins(md, options, markdownTransformMap, codeblockTransformers) {
|
|
2397
|
+
const { data: { features, config }, utils: { katexOptions } } = options;
|
|
2398
|
+
md.use(MarkdownItSnippet, options);
|
|
2399
|
+
md.use(await MarkdownItShiki(options));
|
|
2400
|
+
md.use(MarkdownItCodeblocks, options, codeblockTransformers);
|
|
2401
|
+
md.use(MarkdownItLink);
|
|
2402
|
+
md.use(MarkdownItEscapeInlineCode);
|
|
2403
|
+
md.use(MarkdownItFootnote);
|
|
2404
|
+
md.use(taskLists, {
|
|
2405
|
+
enabled: true,
|
|
2406
|
+
lineNumber: true,
|
|
2407
|
+
label: true
|
|
2369
2408
|
});
|
|
2409
|
+
if (features.katex) md.use(MarkdownItKatex, katexOptions);
|
|
2410
|
+
md.use(MarkdownItVDrag, markdownTransformMap);
|
|
2411
|
+
md.use(MarkdownItSlotSugar);
|
|
2412
|
+
if (config.comark || config.mdc) md.use(MarkdownItComark);
|
|
2413
|
+
md.use(MarkdownItStyleScoped);
|
|
2414
|
+
md.use(MarkdownItGitHubAlerts);
|
|
2370
2415
|
}
|
|
2371
2416
|
|
|
2372
2417
|
//#endregion
|
|
2373
|
-
//#region node/
|
|
2374
|
-
|
|
2418
|
+
//#region node/vite/markdown.ts
|
|
2419
|
+
const RE_MD_EXT$1 = /\.md$/;
|
|
2420
|
+
async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
2421
|
+
const markdownTransformMap = /* @__PURE__ */ new Map();
|
|
2375
2422
|
const extras = await setupTransformers(options.roots);
|
|
2376
|
-
|
|
2423
|
+
const transformers = [
|
|
2377
2424
|
...extras.pre,
|
|
2378
|
-
transformSnippet,
|
|
2379
|
-
options.data.config.highlighter === "shiki" && transformMagicMove,
|
|
2380
2425
|
...extras.preCodeblock,
|
|
2381
|
-
transformMermaid,
|
|
2382
|
-
transformPlantUml,
|
|
2383
|
-
options.data.features.monaco && transformMonaco,
|
|
2384
2426
|
...extras.postCodeblock,
|
|
2385
|
-
transformCodeWrapper,
|
|
2386
|
-
options.data.features.katex && transformKaTexWrapper,
|
|
2387
|
-
transformPageCSS,
|
|
2388
|
-
transformSlotSugar,
|
|
2389
2427
|
...extras.post
|
|
2390
2428
|
];
|
|
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
2429
|
return Markdown({
|
|
2399
|
-
include: [
|
|
2430
|
+
include: [RE_MD_EXT$1],
|
|
2400
2431
|
wrapperClasses: "",
|
|
2401
2432
|
headEnabled: false,
|
|
2402
2433
|
frontmatter: false,
|
|
@@ -2410,18 +2441,18 @@ async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
|
2410
2441
|
},
|
|
2411
2442
|
...mdOptions,
|
|
2412
2443
|
async markdownSetup(md) {
|
|
2413
|
-
await useMarkdownItPlugins(md, options, markdownTransformMap);
|
|
2444
|
+
await useMarkdownItPlugins(md, options, markdownTransformMap, extras.codeblocks);
|
|
2414
2445
|
await mdOptions?.markdownSetup?.(md);
|
|
2415
2446
|
},
|
|
2416
2447
|
transforms: {
|
|
2417
2448
|
...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);
|
|
2449
|
+
async before(code, id$2) {
|
|
2450
|
+
if (options.data.markdownFiles[id$2]) return "";
|
|
2451
|
+
code = await mdOptions?.transforms?.before?.(code, id$2) ?? code;
|
|
2452
|
+
const match = id$2.match(regexSlideSourceId);
|
|
2422
2453
|
if (!match) return code;
|
|
2423
2454
|
const s = new MagicString(code);
|
|
2424
|
-
markdownTransformMap.set(id, s);
|
|
2455
|
+
markdownTransformMap.set(id$2, s);
|
|
2425
2456
|
const ctx = {
|
|
2426
2457
|
s,
|
|
2427
2458
|
slide: options.data.slides[+match[1] - 1],
|
|
@@ -2443,13 +2474,13 @@ async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
|
2443
2474
|
function createMonacoTypesLoader({ userRoot, utils }) {
|
|
2444
2475
|
return {
|
|
2445
2476
|
name: "slidev:monaco-types-loader",
|
|
2446
|
-
resolveId(id) {
|
|
2447
|
-
if (id.startsWith("/@slidev-monaco-types/")) return id;
|
|
2477
|
+
resolveId(id$2) {
|
|
2478
|
+
if (id$2.startsWith("/@slidev-monaco-types/")) return id$2;
|
|
2448
2479
|
return null;
|
|
2449
2480
|
},
|
|
2450
|
-
async load(id) {
|
|
2451
|
-
if (!id.startsWith("/@slidev-monaco-types/")) return null;
|
|
2452
|
-
const url = new URL(id, "http://localhost");
|
|
2481
|
+
async load(id$2) {
|
|
2482
|
+
if (!id$2.startsWith("/@slidev-monaco-types/")) return null;
|
|
2483
|
+
const url = new URL(id$2, "http://localhost");
|
|
2453
2484
|
if (url.pathname === "/@slidev-monaco-types/resolve") {
|
|
2454
2485
|
const query = new URLSearchParams(url.search);
|
|
2455
2486
|
const pkg = query.get("pkg");
|
|
@@ -2502,9 +2533,9 @@ function createPatchMonacoSourceMapPlugin() {
|
|
|
2502
2533
|
return {
|
|
2503
2534
|
name: "slidev:patch-monaco-sourcemap",
|
|
2504
2535
|
enforce: "pre",
|
|
2505
|
-
load(id) {
|
|
2506
|
-
if (!id.includes("node_modules/monaco-editor/esm/vs/base")) return;
|
|
2507
|
-
return readFile(cleanUrl(id), "utf-8");
|
|
2536
|
+
load(id$2) {
|
|
2537
|
+
if (!id$2.includes("node_modules/monaco-editor/esm/vs/base")) return;
|
|
2538
|
+
return readFile(cleanUrl(id$2), "utf-8");
|
|
2508
2539
|
}
|
|
2509
2540
|
};
|
|
2510
2541
|
}
|
|
@@ -2515,7 +2546,7 @@ async function createRemoteAssetsPlugin({ data: { config }, mode }, pluginOption
|
|
|
2515
2546
|
if (!(config.remoteAssets === true || config.remoteAssets === mode)) return;
|
|
2516
2547
|
const { VitePluginRemoteAssets, DefaultRules } = await import("vite-plugin-remote-assets");
|
|
2517
2548
|
return VitePluginRemoteAssets({
|
|
2518
|
-
resolveMode: (id) => id.endsWith("index.html") ? "relative" : "@fs",
|
|
2549
|
+
resolveMode: (id$2) => id$2.endsWith("index.html") ? "relative" : "@fs",
|
|
2519
2550
|
awaitDownload: mode === "build",
|
|
2520
2551
|
...pluginOptions.remoteAssets,
|
|
2521
2552
|
rules: [
|
|
@@ -2669,6 +2700,11 @@ async function createUnocssPlugin(options, pluginOptions) {
|
|
|
2669
2700
|
|
|
2670
2701
|
//#endregion
|
|
2671
2702
|
//#region node/vite/vue.ts
|
|
2703
|
+
const RE_VUE_EXT = /\.vue$/;
|
|
2704
|
+
const RE_VUE_QUERY_VUE = /\.vue\?vue/;
|
|
2705
|
+
const RE_VUE_QUERY_V = /\.vue\?v=/;
|
|
2706
|
+
const RE_MD_EXT = /\.md$/;
|
|
2707
|
+
const RE_MD_QUERY_VUE = /\.md\?vue/;
|
|
2672
2708
|
const customElements = new Set([
|
|
2673
2709
|
"annotation",
|
|
2674
2710
|
"math",
|
|
@@ -2702,11 +2738,11 @@ async function createVuePlugin(_options, pluginOptions) {
|
|
|
2702
2738
|
const { vue: vueOptions = {}, vuejsx: vuejsxOptions = {} } = pluginOptions;
|
|
2703
2739
|
const VuePlugin = Vue({
|
|
2704
2740
|
include: [
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2741
|
+
RE_VUE_EXT,
|
|
2742
|
+
RE_VUE_QUERY_VUE,
|
|
2743
|
+
RE_VUE_QUERY_V,
|
|
2744
|
+
RE_MD_EXT,
|
|
2745
|
+
RE_MD_QUERY_VUE
|
|
2710
2746
|
],
|
|
2711
2747
|
exclude: [],
|
|
2712
2748
|
...vueOptions,
|