@slidev/cli 0.48.0-beta.23 → 0.48.0-beta.25
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-PDGXAWGC.mjs → build-LYRLCEWM.mjs} +5 -5
- package/dist/{chunk-CV7OWJOF.mjs → chunk-HKSSAKUU.mjs} +5 -1
- package/dist/{chunk-TKQ4IRDS.mjs → chunk-HU4YBG2Z.mjs} +15 -11
- package/dist/{chunk-O6TYYGU6.mjs → chunk-LOUKLO2C.mjs} +1 -1
- package/dist/{chunk-7IY2RRV6.mjs → chunk-YO3LH3HD.mjs} +1345 -1270
- package/dist/cli.mjs +8 -10
- package/dist/{export-2XPAFE22.mjs → export-RHB5HDXR.mjs} +2 -2
- package/dist/index.d.mts +5 -84
- package/dist/index.mjs +4 -4
- package/dist/{unocss-M5KPNI4Z.mjs → unocss-AGKZGMYO.mjs} +2 -2
- package/package.json +4 -4
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadSetups
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LOUKLO2C.mjs";
|
|
4
4
|
import {
|
|
5
5
|
resolveImportPath,
|
|
6
|
+
resolveImportUrl,
|
|
6
7
|
toAtFS
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HKSSAKUU.mjs";
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
-
var version = "0.48.0-beta.23";
|
|
11
|
-
|
|
12
|
-
// node/common.ts
|
|
10
|
+
// node/commands/shared.ts
|
|
13
11
|
import { existsSync, promises as fs } from "node:fs";
|
|
14
12
|
import { join } from "node:path";
|
|
15
13
|
import { loadConfigFromFile, mergeConfig, resolveConfig } from "vite";
|
|
16
14
|
|
|
17
15
|
// node/utils.ts
|
|
18
|
-
import { satisfies } from "semver";
|
|
19
16
|
function stringifyMarkdownTokens(tokens) {
|
|
20
17
|
return tokens.map((token) => token.children?.filter((t) => ["text", "code_inline"].includes(t.type) && !t.content.match(/^\s*$/)).map((t) => t.content.trim()).join(" ")).filter(Boolean).join(" ");
|
|
21
18
|
}
|
|
@@ -24,12 +21,8 @@ function generateGoogleFontsUrl(options) {
|
|
|
24
21
|
const fonts = options.webfonts.map((i) => `family=${i.replace(/^(['"])(.*)\1$/, "$1").replace(/\s+/g, "+")}:${options.italic ? "ital," : ""}wght@${weights}`).join("&");
|
|
25
22
|
return `https://fonts.googleapis.com/css2?${fonts}&display=swap`;
|
|
26
23
|
}
|
|
27
|
-
function checkEngine(name, engines = {}) {
|
|
28
|
-
if (engines.slidev && !satisfies(version, engines.slidev, { includePrerelease: true }))
|
|
29
|
-
throw new Error(`[slidev] addon "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
|
|
30
|
-
}
|
|
31
24
|
|
|
32
|
-
// node/
|
|
25
|
+
// node/commands/shared.ts
|
|
33
26
|
async function getIndexHtml({ clientRoot, roots, data }) {
|
|
34
27
|
let main = await fs.readFile(join(clientRoot, "index.html"), "utf-8");
|
|
35
28
|
let head = "";
|
|
@@ -73,20 +66,18 @@ async function mergeViteConfigs({ roots, entry }, viteConfig, config, command) {
|
|
|
73
66
|
return config;
|
|
74
67
|
}
|
|
75
68
|
|
|
76
|
-
// node/
|
|
77
|
-
import { join as
|
|
78
|
-
import { existsSync as
|
|
69
|
+
// node/vite/index.ts
|
|
70
|
+
import { join as join8 } from "node:path";
|
|
71
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
79
72
|
import process from "node:process";
|
|
80
73
|
import { fileURLToPath } from "node:url";
|
|
81
|
-
import Vue from "@vitejs/plugin-vue";
|
|
82
|
-
import VueJsx from "@vitejs/plugin-vue-jsx";
|
|
83
74
|
import Icons from "unplugin-icons/vite";
|
|
84
75
|
import IconsResolver from "unplugin-icons/resolver";
|
|
85
76
|
import Components from "unplugin-vue-components/vite";
|
|
86
77
|
import ServerRef from "vite-plugin-vue-server-ref";
|
|
87
78
|
import { notNullish as notNullish2 } from "@antfu/utils";
|
|
88
79
|
|
|
89
|
-
// node/drawings.ts
|
|
80
|
+
// node/integrations/drawings.ts
|
|
90
81
|
import { basename, dirname, join as join2, resolve } from "node:path";
|
|
91
82
|
import fs2 from "fs-extra";
|
|
92
83
|
import fg from "fast-glob";
|
|
@@ -137,7 +128,7 @@ ${value}
|
|
|
137
128
|
);
|
|
138
129
|
}
|
|
139
130
|
|
|
140
|
-
// node/
|
|
131
|
+
// node/vite/extendConfig.ts
|
|
141
132
|
import { join as join3 } from "node:path";
|
|
142
133
|
import { mergeConfig as mergeConfig2 } from "vite";
|
|
143
134
|
import isInstalledGlobally from "is-installed-globally";
|
|
@@ -181,7 +172,7 @@ var dependencies = {
|
|
|
181
172
|
"vue-router": "^4.3.0"
|
|
182
173
|
};
|
|
183
174
|
|
|
184
|
-
// node/
|
|
175
|
+
// node/vite/extendConfig.ts
|
|
185
176
|
var INCLUDE = [
|
|
186
177
|
...Object.keys(dependencies),
|
|
187
178
|
// CodeMirror
|
|
@@ -322,864 +313,560 @@ function getDefine(options) {
|
|
|
322
313
|
};
|
|
323
314
|
}
|
|
324
315
|
|
|
325
|
-
// node/
|
|
326
|
-
import { basename as basename2
|
|
327
|
-
import {
|
|
328
|
-
import
|
|
329
|
-
import
|
|
330
|
-
import
|
|
331
|
-
import Markdown2 from "markdown-it";
|
|
316
|
+
// node/vite/loaders.ts
|
|
317
|
+
import { basename as basename2 } from "node:path";
|
|
318
|
+
import { isString as isString2, isTruthy as isTruthy2, notNullish, range } from "@antfu/utils";
|
|
319
|
+
import fg3 from "fast-glob";
|
|
320
|
+
import fs4 from "fs-extra";
|
|
321
|
+
import Markdown from "markdown-it";
|
|
332
322
|
import { bold, gray, red, yellow } from "kolorist";
|
|
333
|
-
import
|
|
323
|
+
import mila from "markdown-it-link-attributes";
|
|
334
324
|
import * as parser from "@slidev/parser/fs";
|
|
335
325
|
import equal from "fast-deep-equal";
|
|
336
326
|
|
|
337
|
-
// node/
|
|
338
|
-
import
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
(
|
|
345
|
-
|
|
346
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
|
|
347
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
|
|
348
|
-
SpecialCharacters2[SpecialCharacters2["WHITESPACE"] = 32] = "WHITESPACE";
|
|
349
|
-
SpecialCharacters2[SpecialCharacters2["NEW_LINE"] = 10] = "NEW_LINE";
|
|
350
|
-
SpecialCharacters2[SpecialCharacters2["EQUALS"] = 61] = "EQUALS";
|
|
351
|
-
SpecialCharacters2[SpecialCharacters2["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
|
|
352
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
|
|
353
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_NINE"] = 57] = "NUMBER_NINE";
|
|
354
|
-
SpecialCharacters2[SpecialCharacters2["PERCENTAGE"] = 37] = "PERCENTAGE";
|
|
355
|
-
SpecialCharacters2[SpecialCharacters2["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
|
|
356
|
-
})(SpecialCharacters || (SpecialCharacters = {}));
|
|
357
|
-
|
|
358
|
-
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
|
|
359
|
-
import Token from "markdown-it/lib/token.mjs";
|
|
360
|
-
var checkboxRegex = /^ *\[([\sx])] /i;
|
|
361
|
-
function taskLists(md2, options = { enabled: false, label: false, lineNumber: false }) {
|
|
362
|
-
md2.core.ruler.after("inline", "task-lists", (state) => processToken(state, options));
|
|
363
|
-
md2.renderer.rules.taskListItemCheckbox = (tokens) => {
|
|
364
|
-
const token = tokens[0];
|
|
365
|
-
const checkedAttribute = token.attrGet("checked") ? 'checked="" ' : "";
|
|
366
|
-
const disabledAttribute = token.attrGet("disabled") ? 'disabled="" ' : "";
|
|
367
|
-
const line = token.attrGet("line");
|
|
368
|
-
const idAttribute = `id="${token.attrGet("id")}" `;
|
|
369
|
-
const dataLineAttribute = line && options.lineNumber ? `data-line="${line}" ` : "";
|
|
370
|
-
return `<input class="task-list-item-checkbox" type="checkbox" ${checkedAttribute}${disabledAttribute}${dataLineAttribute}${idAttribute}/>`;
|
|
371
|
-
};
|
|
372
|
-
md2.renderer.rules.taskListItemLabel_close = () => {
|
|
373
|
-
return "</label>";
|
|
374
|
-
};
|
|
375
|
-
md2.renderer.rules.taskListItemLabel_open = (tokens) => {
|
|
376
|
-
const token = tokens[0];
|
|
377
|
-
const id = token.attrGet("id");
|
|
378
|
-
return `<label for="${id}">`;
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
function processToken(state, options) {
|
|
382
|
-
const allTokens = state.tokens;
|
|
383
|
-
for (let i = 2; i < allTokens.length; i++) {
|
|
384
|
-
if (!isTodoItem(allTokens, i)) {
|
|
385
|
-
continue;
|
|
386
|
-
}
|
|
387
|
-
todoify(allTokens[i], options);
|
|
388
|
-
allTokens[i - 2].attrJoin("class", `task-list-item ${options.enabled ? " enabled" : ""}`);
|
|
389
|
-
const parentToken = findParentToken(allTokens, i - 2);
|
|
390
|
-
if (parentToken) {
|
|
391
|
-
const classes = parentToken.attrGet("class") ?? "";
|
|
392
|
-
if (!classes.match(/(^| )contains-task-list/)) {
|
|
393
|
-
parentToken.attrJoin("class", "contains-task-list");
|
|
327
|
+
// node/virtual/configs.ts
|
|
328
|
+
import { isString } from "@antfu/utils";
|
|
329
|
+
var templateConfigs = {
|
|
330
|
+
id: "/@slidev/configs",
|
|
331
|
+
getContent: async ({ data, remote }, { md: md2 }) => {
|
|
332
|
+
function getTitle() {
|
|
333
|
+
if (isString(data.config.title)) {
|
|
334
|
+
const tokens = md2.parseInline(data.config.title, {});
|
|
335
|
+
return stringifyMarkdownTokens(tokens);
|
|
394
336
|
}
|
|
337
|
+
return data.config.title;
|
|
395
338
|
}
|
|
339
|
+
const config = {
|
|
340
|
+
...data.config,
|
|
341
|
+
remote,
|
|
342
|
+
title: getTitle()
|
|
343
|
+
};
|
|
344
|
+
if (isString(config.info))
|
|
345
|
+
config.info = md2.render(config.info);
|
|
346
|
+
return `export default ${JSON.stringify(config)}`;
|
|
396
347
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
function isTodoItem(tokens, index) {
|
|
409
|
-
return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);
|
|
410
|
-
}
|
|
411
|
-
function todoify(token, options) {
|
|
412
|
-
if (token.children == null) {
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
const id = generateIdForToken(token);
|
|
416
|
-
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
417
|
-
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
418
|
-
if (options.label) {
|
|
419
|
-
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
420
|
-
token.children.push(createLabelEndToken());
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// node/virtual/deprecated.ts
|
|
351
|
+
var templateLegacyRoutes = {
|
|
352
|
+
id: "/@slidev/routes",
|
|
353
|
+
getContent() {
|
|
354
|
+
return [
|
|
355
|
+
`export { slides } from '#slidev/slides'`,
|
|
356
|
+
`console.warn('[slidev] #slidev/routes is deprecated, use #slidev/slides instead')`
|
|
357
|
+
].join("\n");
|
|
421
358
|
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
359
|
+
};
|
|
360
|
+
var templateLegacyTitles = {
|
|
361
|
+
id: "/@slidev/titles.md",
|
|
362
|
+
async getContent() {
|
|
363
|
+
return `
|
|
364
|
+
<script setup lang="ts">
|
|
365
|
+
import TitleRenderer from '#slidev/title-renderer'
|
|
366
|
+
defineProps<{ no: number | string }>()
|
|
367
|
+
console.warn('/@slidev/titles.md is deprecated, import from #slidev/title-renderer instead')
|
|
368
|
+
</script>
|
|
369
|
+
|
|
370
|
+
<TitleRenderer :no="no" />
|
|
371
|
+
`;
|
|
428
372
|
}
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
// node/virtual/global-components.ts
|
|
376
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
377
|
+
import { join as join4 } from "node:path";
|
|
378
|
+
function createGlobalComponentTemplate(layer) {
|
|
379
|
+
return {
|
|
380
|
+
id: `/@slidev/global-components/${layer}`,
|
|
381
|
+
getContent({ roots }) {
|
|
382
|
+
const components = roots.flatMap((root) => {
|
|
383
|
+
if (layer === "top") {
|
|
384
|
+
return [
|
|
385
|
+
join4(root, "global.vue"),
|
|
386
|
+
join4(root, "global-top.vue"),
|
|
387
|
+
join4(root, "GlobalTop.vue")
|
|
388
|
+
];
|
|
389
|
+
} else {
|
|
390
|
+
return [
|
|
391
|
+
join4(root, "global-bottom.vue"),
|
|
392
|
+
join4(root, "GlobalBottom.vue")
|
|
393
|
+
];
|
|
394
|
+
}
|
|
395
|
+
}).filter((i) => existsSync2(i));
|
|
396
|
+
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
397
|
+
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
398
|
+
return `
|
|
399
|
+
${imports}
|
|
400
|
+
import { h } from 'vue'
|
|
401
|
+
export default {
|
|
402
|
+
render() {
|
|
403
|
+
return [${render}]
|
|
429
404
|
}
|
|
430
|
-
function createCheckboxToken(token, enabled, id) {
|
|
431
|
-
const checkbox = new Token("taskListItemCheckbox", "", 0);
|
|
432
|
-
if (!enabled) {
|
|
433
|
-
checkbox.attrSet("disabled", "true");
|
|
434
|
-
}
|
|
435
|
-
if (token.map) {
|
|
436
|
-
checkbox.attrSet("line", token.map[0].toString());
|
|
437
|
-
}
|
|
438
|
-
checkbox.attrSet("id", id);
|
|
439
|
-
const checkboxRegexResult = checkboxRegex.exec(token.content);
|
|
440
|
-
const isChecked = checkboxRegexResult?.[1].toLowerCase() === "x";
|
|
441
|
-
if (isChecked) {
|
|
442
|
-
checkbox.attrSet("checked", "true");
|
|
443
|
-
}
|
|
444
|
-
return checkbox;
|
|
445
405
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
return labelBeginToken;
|
|
406
|
+
`;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
450
409
|
}
|
|
451
|
-
|
|
452
|
-
|
|
410
|
+
var templateNavControls = {
|
|
411
|
+
id: "/@slidev/custom-nav-controls",
|
|
412
|
+
getContent({ roots }) {
|
|
413
|
+
const components = roots.flatMap((root) => {
|
|
414
|
+
return [
|
|
415
|
+
join4(root, "custom-nav-controls.vue"),
|
|
416
|
+
join4(root, "CustomNavControls.vue")
|
|
417
|
+
];
|
|
418
|
+
}).filter((i) => existsSync2(i));
|
|
419
|
+
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
420
|
+
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
421
|
+
return `
|
|
422
|
+
${imports}
|
|
423
|
+
import { h } from 'vue'
|
|
424
|
+
export default {
|
|
425
|
+
render() {
|
|
426
|
+
return [${render}]
|
|
453
427
|
}
|
|
454
|
-
function isInline(token) {
|
|
455
|
-
return token.type === "inline";
|
|
456
428
|
}
|
|
457
|
-
|
|
458
|
-
|
|
429
|
+
`;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
var templateGlobalTop = createGlobalComponentTemplate("top");
|
|
433
|
+
var templateGlobalBottom = createGlobalComponentTemplate("bottom");
|
|
434
|
+
|
|
435
|
+
// node/virtual/layouts.ts
|
|
436
|
+
import { objectMap } from "@antfu/utils";
|
|
437
|
+
var templateLayouts = {
|
|
438
|
+
id: "/@slidev/layouts",
|
|
439
|
+
async getContent(_, { getLayouts }) {
|
|
440
|
+
const imports = [];
|
|
441
|
+
const layouts = objectMap(
|
|
442
|
+
await getLayouts(),
|
|
443
|
+
(k, v) => {
|
|
444
|
+
imports.push(`import __layout_${k} from "${toAtFS(v)}"`);
|
|
445
|
+
return [k, `__layout_${k}`];
|
|
446
|
+
}
|
|
447
|
+
);
|
|
448
|
+
return [
|
|
449
|
+
imports.join("\n"),
|
|
450
|
+
`export default {
|
|
451
|
+
${Object.entries(layouts).map(([k, v]) => `"${k}": ${v}`).join(",\n")}
|
|
452
|
+
}`
|
|
453
|
+
].join("\n\n");
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
// node/virtual/monaco-types.ts
|
|
458
|
+
import { builtinModules } from "node:module";
|
|
459
|
+
import { join as join5, resolve as resolve2 } from "node:path";
|
|
460
|
+
import fg2 from "fast-glob";
|
|
461
|
+
import { uniq as uniq2 } from "@antfu/utils";
|
|
462
|
+
|
|
463
|
+
// node/syntax/transform/monaco.ts
|
|
464
|
+
import { isTruthy } from "@antfu/utils";
|
|
465
|
+
import lz from "lz-string";
|
|
466
|
+
function transformMonaco(md2, enabled = true) {
|
|
467
|
+
if (!enabled)
|
|
468
|
+
return truncateMancoMark(md2);
|
|
469
|
+
md2 = md2.replace(
|
|
470
|
+
/^```(\w+?)\s*{monaco-diff}\s*?({.*?})?\s*?\n([\s\S]+?)^~~~\s*?\n([\s\S]+?)^```/mg,
|
|
471
|
+
(full, lang = "ts", options = "{}", code, diff) => {
|
|
472
|
+
lang = lang.trim();
|
|
473
|
+
options = options.trim() || "{}";
|
|
474
|
+
const encoded = lz.compressToBase64(code);
|
|
475
|
+
const encodedDiff = lz.compressToBase64(diff);
|
|
476
|
+
return `<Monaco code-lz="${encoded}" diff-lz="${encodedDiff}" lang="${lang}" v-bind="${options}" />`;
|
|
477
|
+
}
|
|
478
|
+
);
|
|
479
|
+
md2 = md2.replace(
|
|
480
|
+
/^```(\w+?)\s*{monaco}\s*?({.*?})?\s*?\n([\s\S]+?)^```/mg,
|
|
481
|
+
(full, lang = "ts", options = "{}", code) => {
|
|
482
|
+
lang = lang.trim();
|
|
483
|
+
options = options.trim() || "{}";
|
|
484
|
+
const encoded = lz.compressToBase64(code);
|
|
485
|
+
return `<Monaco code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
486
|
+
}
|
|
487
|
+
);
|
|
488
|
+
md2 = md2.replace(
|
|
489
|
+
/^```(\w+?)\s*{monaco-run}\s*?({.*?})?\s*?\n([\s\S]+?)^```/mg,
|
|
490
|
+
(full, lang = "ts", options = "{}", code) => {
|
|
491
|
+
lang = lang.trim();
|
|
492
|
+
options = options.trim() || "{}";
|
|
493
|
+
const encoded = lz.compressToBase64(code);
|
|
494
|
+
return `<Monaco runnable code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
return md2;
|
|
459
498
|
}
|
|
460
|
-
function
|
|
461
|
-
|
|
499
|
+
function scanMonacoModules(md2) {
|
|
500
|
+
const typeModules = /* @__PURE__ */ new Set();
|
|
501
|
+
md2.replace(
|
|
502
|
+
/^```(\w+?)\s*{monaco([\w:,-]*)}[\s\n]*([\s\S]+?)^```/mg,
|
|
503
|
+
(full, lang = "ts", options, code) => {
|
|
504
|
+
options = options || "";
|
|
505
|
+
lang = lang.trim();
|
|
506
|
+
if (lang === "ts" || lang === "typescript") {
|
|
507
|
+
Array.from(code.matchAll(/\s+from\s+(["'])([\/\w@-]+)\1/g)).map((i) => i[2]).filter(isTruthy).map((i) => typeModules.add(i));
|
|
508
|
+
}
|
|
509
|
+
return "";
|
|
510
|
+
}
|
|
511
|
+
);
|
|
512
|
+
return Array.from(typeModules);
|
|
462
513
|
}
|
|
463
|
-
function
|
|
464
|
-
return
|
|
514
|
+
function truncateMancoMark(md2) {
|
|
515
|
+
return md2.replace(/{monaco([\w:,-]*)}/g, "");
|
|
465
516
|
}
|
|
466
517
|
|
|
467
|
-
// node/
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
import
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const max = state.posMax;
|
|
479
|
-
let can_open = true;
|
|
480
|
-
let can_close = true;
|
|
481
|
-
const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;
|
|
482
|
-
const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1;
|
|
483
|
-
if (prevChar === 32 || prevChar === 9 || /* \t */
|
|
484
|
-
nextChar >= 48 && nextChar <= 57)
|
|
485
|
-
can_close = false;
|
|
486
|
-
if (nextChar === 32 || nextChar === 9)
|
|
487
|
-
can_open = false;
|
|
488
|
-
return {
|
|
489
|
-
can_open,
|
|
490
|
-
can_close
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
function math_inline(state, silent) {
|
|
494
|
-
let match, token, res, pos;
|
|
495
|
-
if (state.src[state.pos] !== "$")
|
|
496
|
-
return false;
|
|
497
|
-
res = isValidDelim(state, state.pos);
|
|
498
|
-
if (!res.can_open) {
|
|
499
|
-
if (!silent)
|
|
500
|
-
state.pending += "$";
|
|
501
|
-
state.pos += 1;
|
|
502
|
-
return true;
|
|
503
|
-
}
|
|
504
|
-
const start = state.pos + 1;
|
|
505
|
-
match = start;
|
|
506
|
-
while ((match = state.src.indexOf("$", match)) !== -1) {
|
|
507
|
-
pos = match - 1;
|
|
508
|
-
while (state.src[pos] === "\\")
|
|
509
|
-
pos -= 1;
|
|
510
|
-
if ((match - pos) % 2 === 1)
|
|
511
|
-
break;
|
|
512
|
-
match += 1;
|
|
513
|
-
}
|
|
514
|
-
if (match === -1) {
|
|
515
|
-
if (!silent)
|
|
516
|
-
state.pending += "$";
|
|
517
|
-
state.pos = start;
|
|
518
|
-
return true;
|
|
519
|
-
}
|
|
520
|
-
if (match - start === 0) {
|
|
521
|
-
if (!silent)
|
|
522
|
-
state.pending += "$$";
|
|
523
|
-
state.pos = start + 1;
|
|
524
|
-
return true;
|
|
525
|
-
}
|
|
526
|
-
res = isValidDelim(state, match);
|
|
527
|
-
if (!res.can_close) {
|
|
528
|
-
if (!silent)
|
|
529
|
-
state.pending += "$";
|
|
530
|
-
state.pos = start;
|
|
531
|
-
return true;
|
|
532
|
-
}
|
|
533
|
-
if (!silent) {
|
|
534
|
-
token = state.push("math_inline", "math", 0);
|
|
535
|
-
token.markup = "$";
|
|
536
|
-
token.content = state.src.slice(start, match);
|
|
537
|
-
}
|
|
538
|
-
state.pos = match + 1;
|
|
539
|
-
return true;
|
|
540
|
-
}
|
|
541
|
-
function math_block(state, start, end, silent) {
|
|
542
|
-
let firstLine;
|
|
543
|
-
let lastLine;
|
|
544
|
-
let next;
|
|
545
|
-
let lastPos;
|
|
546
|
-
let found = false;
|
|
547
|
-
let pos = state.bMarks[start] + state.tShift[start];
|
|
548
|
-
let max = state.eMarks[start];
|
|
549
|
-
if (pos + 2 > max)
|
|
550
|
-
return false;
|
|
551
|
-
if (state.src.slice(pos, pos + 2) !== "$$")
|
|
552
|
-
return false;
|
|
553
|
-
pos += 2;
|
|
554
|
-
firstLine = state.src.slice(pos, max);
|
|
555
|
-
if (silent)
|
|
556
|
-
return true;
|
|
557
|
-
if (firstLine.trim().slice(-2) === "$$") {
|
|
558
|
-
firstLine = firstLine.trim().slice(0, -2);
|
|
559
|
-
found = true;
|
|
560
|
-
}
|
|
561
|
-
for (next = start; !found; ) {
|
|
562
|
-
next++;
|
|
563
|
-
if (next >= end)
|
|
564
|
-
break;
|
|
565
|
-
pos = state.bMarks[next] + state.tShift[next];
|
|
566
|
-
max = state.eMarks[next];
|
|
567
|
-
if (pos < max && state.tShift[next] < state.blkIndent) {
|
|
568
|
-
break;
|
|
518
|
+
// node/virtual/monaco-types.ts
|
|
519
|
+
var templateMonacoTypes = {
|
|
520
|
+
id: "/@slidev/monaco-types",
|
|
521
|
+
getContent: async ({ userRoot, data }) => {
|
|
522
|
+
const typesRoot = join5(userRoot, "snippets");
|
|
523
|
+
const files = await fg2(["**/*.ts", "**/*.mts", "**/*.cts"], { cwd: typesRoot });
|
|
524
|
+
let result = 'import { addFile } from "@slidev/client/setup/monaco.ts"\n';
|
|
525
|
+
for (const file of files) {
|
|
526
|
+
const url = `${toAtFS(resolve2(typesRoot, file))}?monaco-types&raw`;
|
|
527
|
+
result += `addFile(import(${JSON.stringify(url)}), ${JSON.stringify(file)})
|
|
528
|
+
`;
|
|
569
529
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
530
|
+
const deps = [...data.config.monacoTypesAdditionalPackages];
|
|
531
|
+
if (data.config.monacoTypesSource === "local")
|
|
532
|
+
deps.push(...scanMonacoModules(data.slides.map((s) => s.source.raw).join()));
|
|
533
|
+
function mapModuleNameToModule(moduleSpecifier) {
|
|
534
|
+
if (moduleSpecifier.startsWith("node:"))
|
|
535
|
+
return "node";
|
|
536
|
+
if (builtinModules.includes(moduleSpecifier))
|
|
537
|
+
return "node";
|
|
538
|
+
const mainPackageName = moduleSpecifier.split("/")[0];
|
|
539
|
+
if (builtinModules.includes(mainPackageName) && !mainPackageName.startsWith("@"))
|
|
540
|
+
return "node";
|
|
541
|
+
const [a = "", b = ""] = moduleSpecifier.split("/");
|
|
542
|
+
const moduleName = a.startsWith("@") ? `${a}/${b}` : a;
|
|
543
|
+
return moduleName;
|
|
574
544
|
}
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
token.map = [start, state.line];
|
|
582
|
-
token.markup = "$$";
|
|
583
|
-
return true;
|
|
584
|
-
}
|
|
585
|
-
function math_plugin(md2, options) {
|
|
586
|
-
options = options || {};
|
|
587
|
-
const katexInline = function(latex) {
|
|
588
|
-
options.displayMode = false;
|
|
589
|
-
try {
|
|
590
|
-
return katex.renderToString(latex, options);
|
|
591
|
-
} catch (error) {
|
|
592
|
-
if (options.throwOnError)
|
|
593
|
-
console.warn(error);
|
|
594
|
-
return latex;
|
|
545
|
+
for (const specifier of uniq2(deps)) {
|
|
546
|
+
if (specifier[0] === ".")
|
|
547
|
+
continue;
|
|
548
|
+
const moduleName = mapModuleNameToModule(specifier);
|
|
549
|
+
result += `import(${JSON.stringify(`/@slidev-monaco-types/resolve?pkg=${moduleName}`)})
|
|
550
|
+
`;
|
|
595
551
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
552
|
+
return result;
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// node/virtual/setups.ts
|
|
557
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
558
|
+
import { join as join6 } from "node:path";
|
|
559
|
+
function createSetupTemplate(name) {
|
|
560
|
+
return {
|
|
561
|
+
id: `/@slidev/setups/${name}`,
|
|
562
|
+
getContent({ roots }) {
|
|
563
|
+
const setups = roots.flatMap((i) => {
|
|
564
|
+
const path2 = join6(i, "setup", name);
|
|
565
|
+
return [".ts", ".mts", ".js", ".mjs"].map((ext) => path2 + ext);
|
|
566
|
+
}).filter((i) => existsSync3(i));
|
|
567
|
+
const imports = [];
|
|
568
|
+
setups.forEach((path2, idx) => {
|
|
569
|
+
imports.push(`import __n${idx} from '${toAtFS(path2)}'`);
|
|
570
|
+
});
|
|
571
|
+
imports.push(`export default [${setups.map((_, idx) => `__n${idx}`).join(",")}]`);
|
|
572
|
+
return imports.join("\n");
|
|
608
573
|
}
|
|
609
574
|
};
|
|
610
|
-
const blockRenderer = function(tokens, idx) {
|
|
611
|
-
return `${katexBlock(tokens[idx].content)}
|
|
612
|
-
`;
|
|
613
|
-
};
|
|
614
|
-
md2.inline.ruler.after("escape", "math_inline", math_inline);
|
|
615
|
-
md2.block.ruler.after("blockquote", "math_block", math_block, {
|
|
616
|
-
alt: ["paragraph", "reference", "blockquote", "list"]
|
|
617
|
-
});
|
|
618
|
-
md2.renderer.rules.math_inline = inlineRenderer;
|
|
619
|
-
md2.renderer.rules.math_block = blockRenderer;
|
|
620
575
|
}
|
|
576
|
+
var setupModules = ["shiki", "code-runners", "monaco", "mermaid", "main", "root", "shortcuts"];
|
|
577
|
+
var templateSetups = setupModules.map(createSetupTemplate);
|
|
621
578
|
|
|
622
|
-
// node/
|
|
623
|
-
import
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
579
|
+
// node/setups/shiki.ts
|
|
580
|
+
import fs3 from "node:fs/promises";
|
|
581
|
+
async function loadShikiSetups(clientRoot, roots) {
|
|
582
|
+
const result = await loadSetups(
|
|
583
|
+
clientRoot,
|
|
584
|
+
roots,
|
|
585
|
+
"shiki.ts",
|
|
586
|
+
{
|
|
587
|
+
/** @deprecated */
|
|
588
|
+
async loadTheme(path2) {
|
|
589
|
+
console.warn("[slidev] `loadTheme` in `setup/shiki.ts` is deprecated. Pass directly the theme name it's supported by Shiki. For custom themes, load it manually via `JSON.parse(fs.readFileSync(path, 'utf-8'))` and pass the raw JSON object instead.");
|
|
590
|
+
return JSON.parse(await fs3.readFile(path2, "utf-8"));
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
{},
|
|
594
|
+
false
|
|
595
|
+
);
|
|
596
|
+
if ("theme" in result && "themes" in result)
|
|
597
|
+
delete result.theme;
|
|
598
|
+
if (result.theme && typeof result.theme !== "string" && !result.theme.name && !result.theme.tokenColors) {
|
|
599
|
+
result.themes = result.theme;
|
|
600
|
+
delete result.theme;
|
|
634
601
|
}
|
|
635
|
-
|
|
636
|
-
|
|
602
|
+
if (!result.theme && !result.themes) {
|
|
603
|
+
result.themes = {
|
|
604
|
+
dark: "vitesse-dark",
|
|
605
|
+
light: "vitesse-light"
|
|
606
|
+
};
|
|
637
607
|
}
|
|
638
|
-
|
|
639
|
-
|
|
608
|
+
if (result.themes)
|
|
609
|
+
result.defaultColor = false;
|
|
610
|
+
return result;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// node/virtual/shiki.ts
|
|
614
|
+
var templateShiki = {
|
|
615
|
+
id: "/@slidev/shiki",
|
|
616
|
+
getContent: async ({ clientRoot, roots }) => {
|
|
617
|
+
const options = await loadShikiSetups(clientRoot, roots);
|
|
618
|
+
const langs = await resolveLangs(options.langs || ["javascript", "typescript", "html", "css"]);
|
|
619
|
+
const resolvedThemeOptions = "themes" in options ? {
|
|
620
|
+
themes: Object.fromEntries(await Promise.all(
|
|
621
|
+
Object.entries(options.themes).map(async ([name, value]) => [name, await resolveTheme(value)])
|
|
622
|
+
))
|
|
623
|
+
} : {
|
|
624
|
+
theme: await resolveTheme(options.theme || "vitesse-dark")
|
|
625
|
+
};
|
|
626
|
+
const themes = resolvedThemeOptions.themes ? Object.values(resolvedThemeOptions.themes) : [resolvedThemeOptions.theme];
|
|
627
|
+
const themeOptionsNames = resolvedThemeOptions.themes ? { themes: Object.fromEntries(Object.entries(resolvedThemeOptions.themes).map(([name, value]) => [name, typeof value === "string" ? value : value.name])) } : { theme: typeof resolvedThemeOptions.theme === "string" ? resolvedThemeOptions.theme : resolvedThemeOptions.theme.name };
|
|
628
|
+
async function normalizeGetter(p) {
|
|
629
|
+
return Promise.resolve(typeof p === "function" ? p() : p).then((r) => r.default || r);
|
|
630
|
+
}
|
|
631
|
+
async function resolveLangs(langs2) {
|
|
632
|
+
return Array.from(new Set((await Promise.all(
|
|
633
|
+
langs2.map(async (lang) => await normalizeGetter(lang).then((r) => Array.isArray(r) ? r : [r]))
|
|
634
|
+
)).flat()));
|
|
635
|
+
}
|
|
636
|
+
async function resolveTheme(theme) {
|
|
637
|
+
return typeof theme === "string" ? theme : await normalizeGetter(theme);
|
|
638
|
+
}
|
|
639
|
+
const langsInit = await Promise.all(
|
|
640
|
+
langs.map(async (lang) => typeof lang === "string" ? `import('${await resolveImportUrl(`shiki/langs/${lang}.mjs`)}')` : JSON.stringify(lang))
|
|
641
|
+
);
|
|
642
|
+
const themesInit = await Promise.all(themes.map(async (theme) => typeof theme === "string" ? `import('${await resolveImportUrl(`shiki/themes/${theme}.mjs`)}')` : JSON.stringify(theme)));
|
|
643
|
+
const langNames = langs.flatMap((lang) => typeof lang === "string" ? lang : lang.name);
|
|
644
|
+
const lines = [];
|
|
645
|
+
lines.push(
|
|
646
|
+
`import { getHighlighterCore } from "${await resolveImportUrl("shiki/core")}"`,
|
|
647
|
+
`export { shikiToMonaco } from "${await resolveImportUrl("@shikijs/monaco")}"`,
|
|
648
|
+
`export const languages = ${JSON.stringify(langNames)}`,
|
|
649
|
+
`export const themes = ${JSON.stringify(themeOptionsNames.themes || themeOptionsNames.theme)}`,
|
|
650
|
+
"export const shiki = getHighlighterCore({",
|
|
651
|
+
` themes: [${themesInit.join(",")}],`,
|
|
652
|
+
` langs: [${langsInit.join(",")}],`,
|
|
653
|
+
` loadWasm: import('${await resolveImportUrl("shiki/wasm")}'),`,
|
|
654
|
+
"})"
|
|
655
|
+
);
|
|
656
|
+
return lines.join("\n");
|
|
640
657
|
}
|
|
641
658
|
};
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
659
|
+
|
|
660
|
+
// node/virtual/slides.ts
|
|
661
|
+
var VIRTUAL_SLIDE_PREFIX = "/@slidev/slides/";
|
|
662
|
+
var templateSlides = {
|
|
663
|
+
id: "/@slidev/slides",
|
|
664
|
+
async getContent({ data }, { getLayouts }) {
|
|
665
|
+
const layouts = await getLayouts();
|
|
666
|
+
const imports = [
|
|
667
|
+
`import { shallowRef } from 'vue'`,
|
|
668
|
+
`import * as __layout__error from '${layouts.error}'`
|
|
669
|
+
];
|
|
670
|
+
const slides = data.slides.map((_, idx) => {
|
|
671
|
+
const no = idx + 1;
|
|
672
|
+
imports.push(`import { meta as f${no} } from '${VIRTUAL_SLIDE_PREFIX}${no}.frontmatter'`);
|
|
673
|
+
return `{
|
|
674
|
+
no: ${no},
|
|
675
|
+
meta: f${no},
|
|
676
|
+
component: async () => {
|
|
677
|
+
try {
|
|
678
|
+
return await import('${VIRTUAL_SLIDE_PREFIX}${no}.md')
|
|
679
|
+
}
|
|
680
|
+
catch {
|
|
681
|
+
return __layout__error
|
|
682
|
+
}
|
|
683
|
+
},
|
|
684
|
+
}`;
|
|
685
|
+
});
|
|
686
|
+
return [
|
|
687
|
+
...imports,
|
|
688
|
+
`const data = [
|
|
689
|
+
${slides.join(",\n")}
|
|
690
|
+
]`,
|
|
691
|
+
`if (import.meta.hot) {`,
|
|
692
|
+
` import.meta.hot.data.slides ??= shallowRef()`,
|
|
693
|
+
` import.meta.hot.data.slides.value = data`,
|
|
694
|
+
` import.meta.hot.accept()`,
|
|
695
|
+
`}`,
|
|
696
|
+
`export const slides = import.meta.hot ? import.meta.hot.data.slides : shallowRef(data)`
|
|
697
|
+
].join("\n");
|
|
675
698
|
}
|
|
676
|
-
|
|
677
|
-
}
|
|
678
|
-
function highlight(markdownit, options, text, lang) {
|
|
679
|
-
const [langToUse, prismLang] = selectLanguage(options, lang);
|
|
680
|
-
let code = text.trimEnd();
|
|
681
|
-
code = prismLang ? highlightPrism(code, prismLang, langToUse) : markdownit.utils.escapeHtml(code);
|
|
682
|
-
code = code.split(/\r?\n/g).map((line) => `<span class="line">${line}</span>`).join("\n");
|
|
683
|
-
const classAttribute = langToUse ? ` class="slidev-code ${markdownit.options.langPrefix}${markdownit.utils.escapeHtml(langToUse)}"` : "";
|
|
684
|
-
return escapeVueInCode(`<pre${classAttribute}><code>${code}</code></pre>`);
|
|
685
|
-
}
|
|
686
|
-
function highlightPrism(code, prismLang, langToUse) {
|
|
687
|
-
const openTags = [];
|
|
688
|
-
const parser2 = new htmlparser2.Parser({
|
|
689
|
-
onopentag(tagname, attributes) {
|
|
690
|
-
openTags.push(new Tag(tagname, attributes));
|
|
691
|
-
},
|
|
692
|
-
onclosetag() {
|
|
693
|
-
openTags.pop();
|
|
694
|
-
}
|
|
695
|
-
});
|
|
696
|
-
code = Prism.highlight(code, prismLang, langToUse);
|
|
697
|
-
code = code.split(/\r?\n/g).map((line) => {
|
|
698
|
-
const prefix = openTags.map((tag) => tag.asOpen()).join("");
|
|
699
|
-
parser2.write(line);
|
|
700
|
-
const postfix = openTags.reverse().map((tag) => tag.asClosed()).join("");
|
|
701
|
-
return prefix + line + postfix;
|
|
702
|
-
}).join("\n");
|
|
703
|
-
parser2.end();
|
|
704
|
-
return code;
|
|
705
|
-
}
|
|
706
|
-
function checkLanguageOption(options, optionName) {
|
|
707
|
-
const language = options[optionName];
|
|
708
|
-
if (language !== void 0 && loadPrismLang(language) === void 0)
|
|
709
|
-
throw new Error(`Bad option ${optionName}: There is no Prism language '${language}'.`);
|
|
710
|
-
}
|
|
711
|
-
function markdownItPrism(markdownit, useroptions) {
|
|
712
|
-
const options = Object.assign({}, DEFAULTS, useroptions);
|
|
713
|
-
checkLanguageOption(options, "defaultLanguage");
|
|
714
|
-
checkLanguageOption(options, "defaultLanguageForUnknown");
|
|
715
|
-
checkLanguageOption(options, "defaultLanguageForUnspecified");
|
|
716
|
-
options.defaultLanguageForUnknown = options.defaultLanguageForUnknown || options.defaultLanguage;
|
|
717
|
-
options.defaultLanguageForUnspecified = options.defaultLanguageForUnspecified || options.defaultLanguage;
|
|
718
|
-
options.plugins.forEach(loadPrismPlugin);
|
|
719
|
-
options.init(Prism);
|
|
720
|
-
markdownit.options.highlight = (text, lang) => highlight(markdownit, options, text, lang);
|
|
721
|
-
}
|
|
699
|
+
};
|
|
722
700
|
|
|
723
|
-
// node/
|
|
724
|
-
import
|
|
725
|
-
import
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
return Math.min(i, acc);
|
|
701
|
+
// node/virtual/styles.ts
|
|
702
|
+
import { join as join7 } from "node:path";
|
|
703
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
704
|
+
var templateStyle = {
|
|
705
|
+
id: "/@slidev/styles",
|
|
706
|
+
getContent: async ({ data, clientRoot, roots }) => {
|
|
707
|
+
function resolveUrlOfClient(name) {
|
|
708
|
+
return toAtFS(join7(clientRoot, name));
|
|
732
709
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
// HTML, markdown
|
|
753
|
-
/^#((?:End )Region) ([\w*-]+)$/,
|
|
754
|
-
// Visual Basic
|
|
755
|
-
/^::#((?:end)region) ([\w*-]+)$/,
|
|
756
|
-
// Bat
|
|
757
|
-
/^# ?((?:end)?region) ([\w*-]+)$/
|
|
758
|
-
// C#, PHP, Powershell, Python, perl & misc
|
|
759
|
-
];
|
|
760
|
-
let regexp = null;
|
|
761
|
-
let start = -1;
|
|
762
|
-
for (const [lineId, line] of lines.entries()) {
|
|
763
|
-
if (regexp === null) {
|
|
764
|
-
for (const reg of regionRegexps) {
|
|
765
|
-
if (testLine(line, reg, regionName)) {
|
|
766
|
-
start = lineId + 1;
|
|
767
|
-
regexp = reg;
|
|
768
|
-
break;
|
|
710
|
+
const imports = [
|
|
711
|
+
`import "${resolveUrlOfClient("styles/vars.css")}"`,
|
|
712
|
+
`import "${resolveUrlOfClient("styles/index.css")}"`,
|
|
713
|
+
`import "${resolveUrlOfClient("styles/code.css")}"`,
|
|
714
|
+
`import "${resolveUrlOfClient("styles/katex.css")}"`,
|
|
715
|
+
`import "${resolveUrlOfClient("styles/transitions.css")}"`
|
|
716
|
+
];
|
|
717
|
+
for (const root of roots) {
|
|
718
|
+
const styles = [
|
|
719
|
+
join7(root, "styles", "index.ts"),
|
|
720
|
+
join7(root, "styles", "index.js"),
|
|
721
|
+
join7(root, "styles", "index.css"),
|
|
722
|
+
join7(root, "styles.css"),
|
|
723
|
+
join7(root, "style.css")
|
|
724
|
+
];
|
|
725
|
+
for (const style of styles) {
|
|
726
|
+
if (existsSync4(style)) {
|
|
727
|
+
imports.push(`import "${toAtFS(style)}"`);
|
|
728
|
+
continue;
|
|
769
729
|
}
|
|
770
730
|
}
|
|
771
|
-
} else if (testLine(line, regexp, regionName, true)) {
|
|
772
|
-
return { start, end: lineId, regexp };
|
|
773
731
|
}
|
|
732
|
+
if (data.features.katex)
|
|
733
|
+
imports.push(`import "${await resolveImportUrl("katex/dist/katex.min.css")}"`);
|
|
734
|
+
if (data.config.highlighter === "shiki") {
|
|
735
|
+
imports.push(
|
|
736
|
+
`import "${await resolveImportUrl("@shikijs/vitepress-twoslash/style.css")}"`,
|
|
737
|
+
`import "${resolveUrlOfClient("styles/shiki-twoslash.css")}"`
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
if (data.config.css === "unocss") {
|
|
741
|
+
imports.unshift(
|
|
742
|
+
`import "${await resolveImportUrl("@unocss/reset/tailwind.css")}"`,
|
|
743
|
+
'import "uno:preflights.css"',
|
|
744
|
+
'import "uno:typography.css"',
|
|
745
|
+
'import "uno:shortcuts.css"'
|
|
746
|
+
);
|
|
747
|
+
imports.push('import "uno.css"');
|
|
748
|
+
}
|
|
749
|
+
return imports.join("\n");
|
|
774
750
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
(
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
// node/virtual/titles.ts
|
|
754
|
+
var templateTitleRendererMd = {
|
|
755
|
+
id: "/@slidev/title-renderer.md",
|
|
756
|
+
async getContent({ data }) {
|
|
757
|
+
const lines = data.slides.map(({ title }, i) => `<template ${i === 0 ? "v-if" : "v-else-if"}="+no === ${i + 1}">
|
|
758
|
+
|
|
759
|
+
${title}
|
|
760
|
+
|
|
761
|
+
</template>`);
|
|
762
|
+
lines.push(`<script setup lang="ts">defineProps<{ no: number | string }>()</script>`);
|
|
763
|
+
return lines.join("\n");
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
var templateTitleRenderer = {
|
|
767
|
+
id: "/@slidev/title-renderer",
|
|
768
|
+
async getContent() {
|
|
769
|
+
return 'export { default } from "/@slidev/title-renderer.md"';
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
// node/virtual/index.ts
|
|
774
|
+
var templates = [
|
|
775
|
+
templateShiki,
|
|
776
|
+
templateMonacoTypes,
|
|
777
|
+
templateConfigs,
|
|
778
|
+
templateStyle,
|
|
779
|
+
templateGlobalBottom,
|
|
780
|
+
templateGlobalTop,
|
|
781
|
+
templateNavControls,
|
|
782
|
+
templateSlides,
|
|
783
|
+
templateLayouts,
|
|
784
|
+
templateTitleRenderer,
|
|
785
|
+
templateTitleRendererMd,
|
|
786
|
+
...templateSetups,
|
|
787
|
+
// Deprecated
|
|
788
|
+
templateLegacyRoutes,
|
|
789
|
+
templateLegacyTitles
|
|
790
|
+
];
|
|
791
|
+
|
|
792
|
+
// node/vite/loaders.ts
|
|
793
|
+
var regexId = /^\/\@slidev\/slide\/(\d+)\.(md|json)(?:\?import)?$/;
|
|
794
|
+
var regexIdQuery = /(\d+?)\.(md|json|frontmatter)$/;
|
|
795
|
+
var templateInjectionMarker = "/* @slidev-injection */";
|
|
796
|
+
var templateImportContextUtils = `import {
|
|
797
|
+
useSlideContext,
|
|
798
|
+
provideFrontmatter as _provideFrontmatter,
|
|
799
|
+
frontmatterToProps as _frontmatterToProps,
|
|
800
|
+
} from "@slidev/client/context.ts"`.replace(/\n\s*/g, " ");
|
|
801
|
+
var templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = useSlideContext()`;
|
|
802
|
+
function getBodyJson(req) {
|
|
803
|
+
return new Promise((resolve4, reject) => {
|
|
804
|
+
let body = "";
|
|
805
|
+
req.on("data", (chunk) => body += chunk);
|
|
806
|
+
req.on("error", reject);
|
|
807
|
+
req.on("end", () => {
|
|
808
|
+
try {
|
|
809
|
+
resolve4(JSON.parse(body) || {});
|
|
810
|
+
} catch (e) {
|
|
811
|
+
reject(e);
|
|
793
812
|
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
813
|
+
});
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
var md = Markdown({ html: true });
|
|
817
|
+
md.use(mila, {
|
|
818
|
+
attrs: {
|
|
819
|
+
target: "_blank",
|
|
820
|
+
rel: "noopener"
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
function renderNote(text = "") {
|
|
824
|
+
let clickCount = 0;
|
|
825
|
+
const html = md.render(
|
|
826
|
+
text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
827
|
+
clickCount += Number(count);
|
|
828
|
+
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
829
|
+
})
|
|
830
|
+
);
|
|
831
|
+
return html;
|
|
832
|
+
}
|
|
833
|
+
function withRenderedNote(data) {
|
|
834
|
+
return {
|
|
835
|
+
...data,
|
|
836
|
+
noteHTML: renderNote(data?.note)
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
function createSlidesLoader(options, pluginOptions, serverOptions) {
|
|
840
|
+
const hmrPages = /* @__PURE__ */ new Set();
|
|
841
|
+
let server;
|
|
842
|
+
let _layouts_cache_time = 0;
|
|
843
|
+
let _layouts_cache = {};
|
|
844
|
+
const { data, clientRoot, roots, mode } = options;
|
|
845
|
+
const templateCtx = {
|
|
846
|
+
md,
|
|
847
|
+
async getLayouts() {
|
|
848
|
+
const now = Date.now();
|
|
849
|
+
if (now - _layouts_cache_time < 2e3)
|
|
850
|
+
return _layouts_cache;
|
|
851
|
+
const layouts = {};
|
|
852
|
+
for (const root of [...roots, clientRoot]) {
|
|
853
|
+
const layoutPaths = await fg3("layouts/**/*.{vue,ts}", {
|
|
854
|
+
cwd: root,
|
|
855
|
+
absolute: true,
|
|
856
|
+
suppressErrors: true
|
|
857
|
+
});
|
|
858
|
+
for (const layoutPath of layoutPaths) {
|
|
859
|
+
const layout = basename2(layoutPath).replace(/\.\w+$/, "");
|
|
860
|
+
if (layouts[layout])
|
|
861
|
+
continue;
|
|
862
|
+
layouts[layout] = layoutPath;
|
|
804
863
|
}
|
|
805
864
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
865
|
+
_layouts_cache_time = now;
|
|
866
|
+
_layouts_cache = layouts;
|
|
867
|
+
return layouts;
|
|
809
868
|
}
|
|
810
|
-
);
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
// node/plugins/markdown.ts
|
|
814
|
-
var shiki;
|
|
815
|
-
var shikiOptions;
|
|
816
|
-
async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
817
|
-
const { data: { config }, roots, mode, entry, clientRoot } = options;
|
|
818
|
-
const setups = [];
|
|
819
|
-
const entryPath = slash(entry);
|
|
820
|
-
if (config.highlighter === "shiki") {
|
|
821
|
-
const [
|
|
822
|
-
options2,
|
|
823
|
-
{ getHighlighter, bundledLanguages },
|
|
824
|
-
markdownItShiki,
|
|
825
|
-
transformerTwoslash
|
|
826
|
-
] = await Promise.all([
|
|
827
|
-
loadShikiSetups(clientRoot, roots),
|
|
828
|
-
import("shiki").then(({ getHighlighter: getHighlighter2, bundledLanguages: bundledLanguages2 }) => ({ bundledLanguages: bundledLanguages2, getHighlighter: getHighlighter2 })),
|
|
829
|
-
import("@shikijs/markdown-it/core").then(({ fromHighlighter }) => fromHighlighter),
|
|
830
|
-
import("@shikijs/vitepress-twoslash").then(({ transformerTwoslash: transformerTwoslash2 }) => transformerTwoslash2)
|
|
831
|
-
]);
|
|
832
|
-
shikiOptions = options2;
|
|
833
|
-
shiki = await getHighlighter({
|
|
834
|
-
...options2,
|
|
835
|
-
langs: options2.langs ?? Object.keys(bundledLanguages),
|
|
836
|
-
themes: "themes" in options2 ? Object.values(options2.themes) : [options2.theme]
|
|
837
|
-
});
|
|
838
|
-
const transformers = [
|
|
839
|
-
...options2.transformers || [],
|
|
840
|
-
transformerTwoslash({
|
|
841
|
-
explicitTrigger: true,
|
|
842
|
-
twoslashOptions: {
|
|
843
|
-
handbookOptions: {
|
|
844
|
-
noErrorValidation: true
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
}),
|
|
848
|
-
{
|
|
849
|
-
pre(pre) {
|
|
850
|
-
this.addClassToHast(pre, "slidev-code");
|
|
851
|
-
delete pre.properties.tabindex;
|
|
852
|
-
},
|
|
853
|
-
postprocess(code) {
|
|
854
|
-
return escapeVueInCode(code);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
];
|
|
858
|
-
const plugin = markdownItShiki(shiki, {
|
|
859
|
-
...options2,
|
|
860
|
-
transformers
|
|
861
|
-
});
|
|
862
|
-
setups.push((md2) => md2.use(plugin));
|
|
863
|
-
} else {
|
|
864
|
-
setups.push((md2) => md2.use(markdownItPrism));
|
|
865
|
-
}
|
|
866
|
-
if (config.mdc)
|
|
867
|
-
setups.push((md2) => md2.use(Mdc));
|
|
868
|
-
const KatexOptions = await loadSetups(options.clientRoot, roots, "katex.ts", {}, { strict: false }, false);
|
|
869
|
-
return Markdown({
|
|
870
|
-
include: [/\.md$/],
|
|
871
|
-
wrapperClasses: "",
|
|
872
|
-
headEnabled: false,
|
|
873
|
-
frontmatter: false,
|
|
874
|
-
escapeCodeTagInterpolation: false,
|
|
875
|
-
markdownItOptions: {
|
|
876
|
-
quotes: `""''`,
|
|
877
|
-
html: true,
|
|
878
|
-
xhtmlOut: true,
|
|
879
|
-
linkify: true,
|
|
880
|
-
...mdOptions?.markdownItOptions
|
|
881
|
-
},
|
|
882
|
-
...mdOptions,
|
|
883
|
-
markdownItSetup(md2) {
|
|
884
|
-
md2.use(mila, {
|
|
885
|
-
attrs: {
|
|
886
|
-
target: "_blank",
|
|
887
|
-
rel: "noopener"
|
|
888
|
-
}
|
|
889
|
-
});
|
|
890
|
-
md2.use(mif);
|
|
891
|
-
md2.use(taskLists, { enabled: true, lineNumber: true, label: true });
|
|
892
|
-
md2.use(math_plugin, KatexOptions);
|
|
893
|
-
setups.forEach((i) => i(md2));
|
|
894
|
-
mdOptions?.markdownItSetup?.(md2);
|
|
895
|
-
},
|
|
896
|
-
transforms: {
|
|
897
|
-
before(code, id) {
|
|
898
|
-
if (id === entryPath)
|
|
899
|
-
return "";
|
|
900
|
-
const monaco = config.monaco === true || config.monaco === mode ? transformMarkdownMonaco : truncateMancoMark;
|
|
901
|
-
if (config.highlighter === "shiki")
|
|
902
|
-
code = transformMagicMove(code, shiki, shikiOptions);
|
|
903
|
-
code = transformSlotSugar(code);
|
|
904
|
-
code = transformSnippet(code, options, id);
|
|
905
|
-
code = transformMermaid(code);
|
|
906
|
-
code = transformPlantUml(code, config.plantUmlServer);
|
|
907
|
-
code = monaco(code);
|
|
908
|
-
code = transformHighlighter(code);
|
|
909
|
-
code = transformPageCSS(code, id);
|
|
910
|
-
code = transformKaTex(code);
|
|
911
|
-
return code;
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
function transformKaTex(md2) {
|
|
917
|
-
return md2.replace(
|
|
918
|
-
/^\$\$(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?\s*?)?\n([\s\S]+?)^\$\$/mg,
|
|
919
|
-
(full, rangeStr = "", options = "", code) => {
|
|
920
|
-
const ranges = !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
921
|
-
code = code.trimEnd();
|
|
922
|
-
options = options.trim() || "{}";
|
|
923
|
-
return `<KaTexBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
924
|
-
|
|
925
|
-
$$
|
|
926
|
-
${code}
|
|
927
|
-
$$
|
|
928
|
-
</KaTexBlockWrapper>
|
|
929
|
-
`;
|
|
930
|
-
}
|
|
931
|
-
);
|
|
932
|
-
}
|
|
933
|
-
function transformMarkdownMonaco(md2) {
|
|
934
|
-
md2 = md2.replace(
|
|
935
|
-
/^```(\w+?)\s*{monaco-diff}\s*?({.*?})?\s*?\n([\s\S]+?)^~~~\s*?\n([\s\S]+?)^```/mg,
|
|
936
|
-
(full, lang = "ts", options = "{}", code, diff) => {
|
|
937
|
-
lang = lang.trim();
|
|
938
|
-
options = options.trim() || "{}";
|
|
939
|
-
const encoded = lz.compressToBase64(code);
|
|
940
|
-
const encodedDiff = lz.compressToBase64(diff);
|
|
941
|
-
return `<Monaco code-lz="${encoded}" diff-lz="${encodedDiff}" lang="${lang}" v-bind="${options}" />`;
|
|
942
|
-
}
|
|
943
|
-
);
|
|
944
|
-
md2 = md2.replace(
|
|
945
|
-
/^```(\w+?)\s*{monaco}\s*?({.*?})?\s*?\n([\s\S]+?)^```/mg,
|
|
946
|
-
(full, lang = "ts", options = "{}", code) => {
|
|
947
|
-
lang = lang.trim();
|
|
948
|
-
options = options.trim() || "{}";
|
|
949
|
-
const encoded = lz.compressToBase64(code);
|
|
950
|
-
return `<Monaco code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
951
|
-
}
|
|
952
|
-
);
|
|
953
|
-
md2 = md2.replace(
|
|
954
|
-
/^```(\w+?)\s*{monaco-run}\s*?({.*?})?\s*?\n([\s\S]+?)^```/mg,
|
|
955
|
-
(full, lang = "ts", options = "{}", code) => {
|
|
956
|
-
lang = lang.trim();
|
|
957
|
-
options = options.trim() || "{}";
|
|
958
|
-
const encoded = lz.compressToBase64(code);
|
|
959
|
-
return `<Monaco runnable code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
960
|
-
}
|
|
961
|
-
);
|
|
962
|
-
return md2;
|
|
963
|
-
}
|
|
964
|
-
function scanMonacoModules(md2) {
|
|
965
|
-
const typeModules = /* @__PURE__ */ new Set();
|
|
966
|
-
md2.replace(
|
|
967
|
-
/^```(\w+?)\s*{monaco([\w:,-]*)}[\s\n]*([\s\S]+?)^```/mg,
|
|
968
|
-
(full, lang = "ts", options, code) => {
|
|
969
|
-
options = options || "";
|
|
970
|
-
lang = lang.trim();
|
|
971
|
-
if (lang === "ts" || lang === "typescript") {
|
|
972
|
-
Array.from(code.matchAll(/\s+from\s+(["'])([\/\w@-]+)\1/g)).map((i) => i[2]).filter(isTruthy).map((i) => typeModules.add(i));
|
|
973
|
-
}
|
|
974
|
-
return "";
|
|
975
|
-
}
|
|
976
|
-
);
|
|
977
|
-
return Array.from(typeModules);
|
|
978
|
-
}
|
|
979
|
-
function truncateMancoMark(md2) {
|
|
980
|
-
return md2.replace(/{monaco.*?}/g, "");
|
|
981
|
-
}
|
|
982
|
-
function transformSlotSugar(md2) {
|
|
983
|
-
const lines = md2.split(/\r?\n/g);
|
|
984
|
-
let prevSlot = false;
|
|
985
|
-
const { isLineInsideCodeblocks } = getCodeBlocks(md2);
|
|
986
|
-
lines.forEach((line, idx) => {
|
|
987
|
-
if (isLineInsideCodeblocks(idx))
|
|
988
|
-
return;
|
|
989
|
-
const match = line.trimEnd().match(/^::\s*([\w\.\-\:]+)\s*::$/);
|
|
990
|
-
if (match) {
|
|
991
|
-
lines[idx] = `${prevSlot ? "\n\n</template>\n" : "\n"}<template v-slot:${match[1]}="slotProps">
|
|
992
|
-
`;
|
|
993
|
-
prevSlot = true;
|
|
994
|
-
}
|
|
995
|
-
});
|
|
996
|
-
if (prevSlot)
|
|
997
|
-
lines[lines.length - 1] += "\n\n</template>";
|
|
998
|
-
return lines.join("\n");
|
|
999
|
-
}
|
|
1000
|
-
var reMagicMoveBlock = /^````(?:md|markdown) magic-move(?:[ ]*(\{.*?\})?([^\n]*?))?\n([\s\S]+?)^````$/mg;
|
|
1001
|
-
var reCodeBlock = /^```(\w+?)(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?(.*?))?\n([\s\S]+?)^```$/mg;
|
|
1002
|
-
function transformMagicMove(md2, shiki2, shikiOptions2) {
|
|
1003
|
-
return md2.replace(
|
|
1004
|
-
reMagicMoveBlock,
|
|
1005
|
-
(full, options = "{}", _attrs = "", body) => {
|
|
1006
|
-
if (!shiki2 || !shikiOptions2)
|
|
1007
|
-
throw new Error("Shiki is required for Magic Move. You may need to set `highlighter: shiki` in your Slidev config.");
|
|
1008
|
-
const matches = Array.from(body.matchAll(reCodeBlock));
|
|
1009
|
-
if (!matches.length)
|
|
1010
|
-
throw new Error("Magic Move block must contain at least one code block");
|
|
1011
|
-
const ranges = matches.map((i) => normalizeRangeStr(i[2]));
|
|
1012
|
-
const steps = matches.map(
|
|
1013
|
-
(i) => codeToKeyedTokens(shiki2, i[5].trimEnd(), {
|
|
1014
|
-
...shikiOptions2,
|
|
1015
|
-
lang: i[1]
|
|
1016
|
-
})
|
|
1017
|
-
);
|
|
1018
|
-
const compressed = lz.compressToBase64(JSON.stringify(steps));
|
|
1019
|
-
return `<ShikiMagicMove v-bind="${options}" steps-lz="${compressed}" :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
1020
|
-
}
|
|
1021
|
-
);
|
|
1022
|
-
}
|
|
1023
|
-
function transformHighlighter(md2) {
|
|
1024
|
-
return md2.replace(
|
|
1025
|
-
reCodeBlock,
|
|
1026
|
-
(full, lang = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
1027
|
-
const ranges = normalizeRangeStr(rangeStr);
|
|
1028
|
-
code = code.trimEnd();
|
|
1029
|
-
options = options.trim() || "{}";
|
|
1030
|
-
return `
|
|
1031
|
-
<CodeBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1032
|
-
|
|
1033
|
-
\`\`\`${lang}${attrs}
|
|
1034
|
-
${code}
|
|
1035
|
-
\`\`\`
|
|
1036
|
-
|
|
1037
|
-
</CodeBlockWrapper>`;
|
|
1038
|
-
}
|
|
1039
|
-
);
|
|
1040
|
-
}
|
|
1041
|
-
function normalizeRangeStr(rangeStr = "") {
|
|
1042
|
-
return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1043
|
-
}
|
|
1044
|
-
function getCodeBlocks(md2) {
|
|
1045
|
-
const codeblocks = Array.from(md2.matchAll(/^```[\s\S]*?^```/mg)).map((m) => {
|
|
1046
|
-
const start = m.index;
|
|
1047
|
-
const end = m.index + m[0].length;
|
|
1048
|
-
const startLine = md2.slice(0, start).match(/\n/g)?.length || 0;
|
|
1049
|
-
const endLine = md2.slice(0, end).match(/\n/g)?.length || 0;
|
|
1050
|
-
return [start, end, startLine, endLine];
|
|
1051
|
-
});
|
|
1052
|
-
return {
|
|
1053
|
-
codeblocks,
|
|
1054
|
-
isInsideCodeblocks(idx) {
|
|
1055
|
-
return codeblocks.some(([s, e]) => s <= idx && idx <= e);
|
|
1056
|
-
},
|
|
1057
|
-
isLineInsideCodeblocks(line) {
|
|
1058
|
-
return codeblocks.some(([, , s, e]) => s <= line && line <= e);
|
|
1059
|
-
}
|
|
1060
|
-
};
|
|
1061
|
-
}
|
|
1062
|
-
function transformPageCSS(md2, id) {
|
|
1063
|
-
const page = id.match(/(\d+)\.md$/)?.[1];
|
|
1064
|
-
if (!page)
|
|
1065
|
-
return md2;
|
|
1066
|
-
const { isInsideCodeblocks } = getCodeBlocks(md2);
|
|
1067
|
-
const result = md2.replace(
|
|
1068
|
-
/(\n<style[^>]*?>)([\s\S]+?)(<\/style>)/g,
|
|
1069
|
-
(full, start, css, end, index) => {
|
|
1070
|
-
if (index < 0 || isInsideCodeblocks(index))
|
|
1071
|
-
return full;
|
|
1072
|
-
if (!start.includes("scoped"))
|
|
1073
|
-
start = start.replace("<style", "<style scoped");
|
|
1074
|
-
return `${start}
|
|
1075
|
-
${css}${end}`;
|
|
1076
|
-
}
|
|
1077
|
-
);
|
|
1078
|
-
return result;
|
|
1079
|
-
}
|
|
1080
|
-
function transformMermaid(md2) {
|
|
1081
|
-
return md2.replace(/^```mermaid\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", code = "") => {
|
|
1082
|
-
code = code.trim();
|
|
1083
|
-
options = options.trim() || "{}";
|
|
1084
|
-
const encoded = lz.compressToBase64(code);
|
|
1085
|
-
return `<Mermaid code-lz="${encoded}" v-bind="${options}" />`;
|
|
1086
|
-
});
|
|
1087
|
-
}
|
|
1088
|
-
function transformPlantUml(md2, server) {
|
|
1089
|
-
return md2.replace(/^```plantuml\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", content = "") => {
|
|
1090
|
-
const code = encodePlantUml(content.trim());
|
|
1091
|
-
options = options.trim() || "{}";
|
|
1092
|
-
return `<PlantUml :code="'${code}'" :server="'${server}'" v-bind="${options}" />`;
|
|
1093
|
-
});
|
|
1094
|
-
}
|
|
1095
|
-
function escapeVueInCode(md2) {
|
|
1096
|
-
return md2.replace(/{{/g, "{{");
|
|
1097
|
-
}
|
|
1098
|
-
async function loadShikiSetups(clientRoot, roots) {
|
|
1099
|
-
const result = await loadSetups(
|
|
1100
|
-
clientRoot,
|
|
1101
|
-
roots,
|
|
1102
|
-
"shiki.ts",
|
|
1103
|
-
{
|
|
1104
|
-
/** @deprecated */
|
|
1105
|
-
async loadTheme(path2) {
|
|
1106
|
-
console.warn("[slidev] `loadTheme` in `setup/shiki.ts` is deprecated. Pass directly the theme name it's supported by Shiki. For custom themes, load it manually via `JSON.parse(fs.readFileSync(path, 'utf-8'))` and pass the raw JSON object instead.");
|
|
1107
|
-
return JSON.parse(await fs4.readFile(path2, "utf-8"));
|
|
1108
|
-
}
|
|
1109
|
-
},
|
|
1110
|
-
{},
|
|
1111
|
-
false
|
|
1112
|
-
);
|
|
1113
|
-
if ("theme" in result && "themes" in result)
|
|
1114
|
-
delete result.theme;
|
|
1115
|
-
if (result.theme && typeof result.theme !== "string" && !result.theme.name && !result.theme.tokenColors) {
|
|
1116
|
-
result.themes = result.theme;
|
|
1117
|
-
delete result.theme;
|
|
1118
|
-
}
|
|
1119
|
-
if (!result.theme && !result.themes) {
|
|
1120
|
-
result.themes = {
|
|
1121
|
-
dark: "vitesse-dark",
|
|
1122
|
-
light: "vitesse-light"
|
|
1123
|
-
};
|
|
1124
|
-
}
|
|
1125
|
-
if (result.themes)
|
|
1126
|
-
result.defaultColor = false;
|
|
1127
|
-
return result;
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
// node/plugins/loaders.ts
|
|
1131
|
-
var regexId = /^\/\@slidev\/slide\/(\d+)\.(md|json)(?:\?import)?$/;
|
|
1132
|
-
var regexIdQuery = /(\d+?)\.(md|json|frontmatter)$/;
|
|
1133
|
-
var templateInjectionMarker = "/* @slidev-injection */";
|
|
1134
|
-
var templateImportContextUtils = `import {
|
|
1135
|
-
useSlideContext,
|
|
1136
|
-
provideFrontmatter as _provideFrontmatter,
|
|
1137
|
-
frontmatterToProps as _frontmatterToProps,
|
|
1138
|
-
} from "@slidev/client/context.ts"`.replace(/\n\s*/g, " ");
|
|
1139
|
-
var templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = useSlideContext()`;
|
|
1140
|
-
function getBodyJson(req) {
|
|
1141
|
-
return new Promise((resolve5, reject) => {
|
|
1142
|
-
let body = "";
|
|
1143
|
-
req.on("data", (chunk) => body += chunk);
|
|
1144
|
-
req.on("error", reject);
|
|
1145
|
-
req.on("end", () => {
|
|
1146
|
-
try {
|
|
1147
|
-
resolve5(JSON.parse(body) || {});
|
|
1148
|
-
} catch (e) {
|
|
1149
|
-
reject(e);
|
|
1150
|
-
}
|
|
1151
|
-
});
|
|
1152
|
-
});
|
|
1153
|
-
}
|
|
1154
|
-
var md = Markdown2({ html: true });
|
|
1155
|
-
md.use(mila2, {
|
|
1156
|
-
attrs: {
|
|
1157
|
-
target: "_blank",
|
|
1158
|
-
rel: "noopener"
|
|
1159
|
-
}
|
|
1160
|
-
});
|
|
1161
|
-
function renderNote(text = "") {
|
|
1162
|
-
let clickCount = 0;
|
|
1163
|
-
const html = md.render(
|
|
1164
|
-
text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
1165
|
-
clickCount += Number(count);
|
|
1166
|
-
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
1167
|
-
})
|
|
1168
|
-
);
|
|
1169
|
-
return html;
|
|
1170
|
-
}
|
|
1171
|
-
function withRenderedNote(data) {
|
|
1172
|
-
return {
|
|
1173
|
-
...data,
|
|
1174
|
-
noteHTML: renderNote(data?.note)
|
|
1175
869
|
};
|
|
1176
|
-
}
|
|
1177
|
-
function createSlidesLoader({ data, clientRoot, roots, remote, mode, userRoot }, pluginOptions, serverOptions) {
|
|
1178
|
-
const slidePrefix = "/@slidev/slides/";
|
|
1179
|
-
const hmrPages = /* @__PURE__ */ new Set();
|
|
1180
|
-
let server;
|
|
1181
|
-
let _layouts_cache_time = 0;
|
|
1182
|
-
let _layouts_cache = {};
|
|
1183
870
|
return [
|
|
1184
871
|
{
|
|
1185
872
|
name: "slidev:loader",
|
|
@@ -1220,15 +907,15 @@ function createSlidesLoader({ data, clientRoot, roots, remote, mode, userRoot },
|
|
|
1220
907
|
return [];
|
|
1221
908
|
const moduleIds = /* @__PURE__ */ new Set();
|
|
1222
909
|
if (data.slides.length !== newData.slides.length) {
|
|
1223
|
-
moduleIds.add(
|
|
910
|
+
moduleIds.add(templateSlides.id);
|
|
1224
911
|
range(newData.slides.length).map((i) => hmrPages.add(i));
|
|
1225
912
|
}
|
|
1226
913
|
if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
|
|
1227
|
-
moduleIds.add(
|
|
914
|
+
moduleIds.add(templateSlides.id);
|
|
1228
915
|
range(data.slides.length).map((i) => hmrPages.add(i));
|
|
1229
916
|
}
|
|
1230
917
|
if (!equal(data.config, newData.config))
|
|
1231
|
-
moduleIds.add(
|
|
918
|
+
moduleIds.add(templateConfigs.id);
|
|
1232
919
|
if (!equal(data.features, newData.features)) {
|
|
1233
920
|
setTimeout(() => {
|
|
1234
921
|
ctx.server.hot.send({ type: "full-reload" });
|
|
@@ -1240,7 +927,7 @@ function createSlidesLoader({ data, clientRoot, roots, remote, mode, userRoot },
|
|
|
1240
927
|
const b = newData.slides[i];
|
|
1241
928
|
if (!hmrPages.has(i) && a.content.trim() === b.content.trim() && a.title?.trim() === b.title?.trim() && equal(a.frontmatter, b.frontmatter) && Object.entries(a.snippetsUsed ?? {}).every(([file, oldContent]) => {
|
|
1242
929
|
try {
|
|
1243
|
-
const newContent =
|
|
930
|
+
const newContent = fs4.readFileSync(file, "utf-8");
|
|
1244
931
|
return oldContent === newContent;
|
|
1245
932
|
} catch {
|
|
1246
933
|
return false;
|
|
@@ -1269,10 +956,10 @@ function createSlidesLoader({ data, clientRoot, roots, remote, mode, userRoot },
|
|
|
1269
956
|
}
|
|
1270
957
|
Object.assign(data, newData);
|
|
1271
958
|
if (hmrPages.size > 0)
|
|
1272
|
-
moduleIds.add(
|
|
959
|
+
moduleIds.add(templateTitleRendererMd.id);
|
|
1273
960
|
const vueModules = Array.from(hmrPages).flatMap((i) => [
|
|
1274
|
-
ctx.server.moduleGraph.getModuleById(`${
|
|
1275
|
-
ctx.server.moduleGraph.getModuleById(`${
|
|
961
|
+
ctx.server.moduleGraph.getModuleById(`${VIRTUAL_SLIDE_PREFIX}${i + 1}.frontmatter`),
|
|
962
|
+
ctx.server.moduleGraph.getModuleById(`${VIRTUAL_SLIDE_PREFIX}${i + 1}.md`)
|
|
1276
963
|
]);
|
|
1277
964
|
hmrPages.clear();
|
|
1278
965
|
const moduleEntries = [
|
|
@@ -1283,43 +970,20 @@ function createSlidesLoader({ data, clientRoot, roots, remote, mode, userRoot },
|
|
|
1283
970
|
return moduleEntries;
|
|
1284
971
|
},
|
|
1285
972
|
resolveId(id) {
|
|
1286
|
-
if (id.startsWith(
|
|
973
|
+
if (id.startsWith(VIRTUAL_SLIDE_PREFIX) || id.startsWith("/@slidev/"))
|
|
1287
974
|
return id;
|
|
1288
975
|
return null;
|
|
1289
976
|
},
|
|
1290
|
-
load(id) {
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
if (id === "/@slidev/routes")
|
|
1294
|
-
return generateDummyRoutes();
|
|
1295
|
-
if (id === "/@slidev/layouts")
|
|
1296
|
-
return generateLayouts();
|
|
1297
|
-
if (id === "/@slidev/styles")
|
|
1298
|
-
return generateUserStyles();
|
|
1299
|
-
if (id === "/@slidev/monaco-types")
|
|
1300
|
-
return generateMonacoTypes();
|
|
1301
|
-
if (id === "/@slidev/configs")
|
|
1302
|
-
return generateConfigs();
|
|
1303
|
-
if (id === "/@slidev/global-components/top")
|
|
1304
|
-
return generateGlobalComponents("top");
|
|
1305
|
-
if (id === "/@slidev/global-components/bottom")
|
|
1306
|
-
return generateGlobalComponents("bottom");
|
|
1307
|
-
if (id === "/@slidev/custom-nav-controls")
|
|
1308
|
-
return generateCustomNavControls();
|
|
1309
|
-
if (id === "/@slidev/shiki")
|
|
1310
|
-
return generteShikiBundle();
|
|
1311
|
-
if (id === "/@slidev/titles.md") {
|
|
977
|
+
async load(id) {
|
|
978
|
+
const template = templates.find((i) => i.id === id);
|
|
979
|
+
if (template) {
|
|
1312
980
|
return {
|
|
1313
|
-
code:
|
|
1314
|
-
|
|
1315
|
-
${title}
|
|
1316
|
-
|
|
1317
|
-
</template>`).join(""),
|
|
981
|
+
code: await template.getContent(options, templateCtx),
|
|
1318
982
|
map: { mappings: "" }
|
|
1319
983
|
};
|
|
1320
984
|
}
|
|
1321
|
-
if (id.startsWith(
|
|
1322
|
-
const remaning = id.slice(
|
|
985
|
+
if (id.startsWith(VIRTUAL_SLIDE_PREFIX)) {
|
|
986
|
+
const remaning = id.slice(VIRTUAL_SLIDE_PREFIX.length);
|
|
1323
987
|
const match = remaning.match(regexIdQuery);
|
|
1324
988
|
if (match) {
|
|
1325
989
|
const [, no, type] = match;
|
|
@@ -1391,9 +1055,9 @@ ${title}
|
|
|
1391
1055
|
name: "slidev:layout-transform:pre",
|
|
1392
1056
|
enforce: "pre",
|
|
1393
1057
|
async transform(code, id) {
|
|
1394
|
-
if (!id.startsWith(
|
|
1058
|
+
if (!id.startsWith(VIRTUAL_SLIDE_PREFIX))
|
|
1395
1059
|
return;
|
|
1396
|
-
const remaning = id.slice(
|
|
1060
|
+
const remaning = id.slice(VIRTUAL_SLIDE_PREFIX.length);
|
|
1397
1061
|
const match = remaning.match(regexIdQuery);
|
|
1398
1062
|
if (!match)
|
|
1399
1063
|
return;
|
|
@@ -1413,15 +1077,6 @@ ${title}
|
|
|
1413
1077
|
return transformVue(code);
|
|
1414
1078
|
}
|
|
1415
1079
|
},
|
|
1416
|
-
{
|
|
1417
|
-
name: "slidev:title-transform:pre",
|
|
1418
|
-
enforce: "pre",
|
|
1419
|
-
transform(code, id) {
|
|
1420
|
-
if (id !== "/@slidev/titles.md")
|
|
1421
|
-
return;
|
|
1422
|
-
return transformTitles(code);
|
|
1423
|
-
}
|
|
1424
|
-
},
|
|
1425
1080
|
{
|
|
1426
1081
|
name: "slidev:slide-transform:post",
|
|
1427
1082
|
enforce: "post",
|
|
@@ -1479,7 +1134,7 @@ ${title}
|
|
|
1479
1134
|
};
|
|
1480
1135
|
}
|
|
1481
1136
|
async function transformMarkdown(code, pageNo) {
|
|
1482
|
-
const layouts = await getLayouts();
|
|
1137
|
+
const layouts = await templateCtx.getLayouts();
|
|
1483
1138
|
const frontmatter = getFrontmatter(pageNo);
|
|
1484
1139
|
let layoutName = frontmatter?.layout || (pageNo === 0 ? "cover" : "default");
|
|
1485
1140
|
if (!layouts[layoutName]) {
|
|
@@ -1491,7 +1146,7 @@ Unknown layout "${bold(layoutName)}".${yellow(" Available layouts are:")}`) + Ob
|
|
|
1491
1146
|
delete frontmatter.title;
|
|
1492
1147
|
const imports = [
|
|
1493
1148
|
`import InjectedLayout from "${toAtFS(layouts[layoutName])}"`,
|
|
1494
|
-
`import frontmatter from "${toAtFS(`${
|
|
1149
|
+
`import frontmatter from "${toAtFS(`${VIRTUAL_SLIDE_PREFIX + (pageNo + 1)}.frontmatter`)}"`,
|
|
1495
1150
|
templateImportContextUtils,
|
|
1496
1151
|
"_provideFrontmatter(frontmatter)",
|
|
1497
1152
|
templateInitContext,
|
|
@@ -1512,387 +1167,800 @@ ${body}
|
|
|
1512
1167
|
${code.slice(injectB)}`;
|
|
1513
1168
|
return code;
|
|
1514
1169
|
}
|
|
1515
|
-
function transformVue(code) {
|
|
1516
|
-
if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
|
|
1517
|
-
return code;
|
|
1518
|
-
const imports = [
|
|
1519
|
-
templateImportContextUtils,
|
|
1520
|
-
templateInitContext,
|
|
1521
|
-
templateInjectionMarker
|
|
1522
|
-
];
|
|
1523
|
-
const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
|
|
1524
|
-
if (matchScript && matchScript[2]) {
|
|
1525
|
-
return code.replace(/(<script.*>)/g, `$1
|
|
1526
|
-
${imports.join("\n")}
|
|
1527
|
-
`);
|
|
1528
|
-
} else if (matchScript && !matchScript[2]) {
|
|
1529
|
-
const matchExport = code.match(/export\s+default\s+{/);
|
|
1530
|
-
if (matchExport) {
|
|
1531
|
-
const exportIndex = (matchExport.index || 0) + matchExport[0].length;
|
|
1532
|
-
let component = code.slice(exportIndex);
|
|
1533
|
-
component = component.slice(0, component.indexOf("</script>"));
|
|
1534
|
-
const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
|
|
1535
|
-
const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
|
|
1536
|
-
code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
|
|
1537
|
-
let injectIndex = exportIndex + provideImport.length;
|
|
1538
|
-
let injectObject = "$slidev: { from: injectionSlidevContext },";
|
|
1539
|
-
const matchInject = component.match(/.*inject\s*:\s*([\[{])/);
|
|
1540
|
-
if (matchInject) {
|
|
1541
|
-
injectIndex += (matchInject.index || 0) + matchInject[0].length;
|
|
1542
|
-
if (matchInject[1] === "[") {
|
|
1543
|
-
let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
|
|
1544
|
-
const injectEndIndex = injects.indexOf("]");
|
|
1545
|
-
injects = injects.slice(0, injectEndIndex);
|
|
1546
|
-
injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
|
|
1547
|
-
return `${code.slice(0, injectIndex - 1)}{
|
|
1548
|
-
${injectObject}
|
|
1549
|
-
}${code.slice(injectIndex + injectEndIndex + 1)}`;
|
|
1550
|
-
} else {
|
|
1551
|
-
return `${code.slice(0, injectIndex)}
|
|
1552
|
-
${injectObject}
|
|
1553
|
-
${code.slice(injectIndex)}`;
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
return `${code.slice(0, injectIndex)}
|
|
1557
|
-
inject: { ${injectObject} },
|
|
1558
|
-
${code.slice(injectIndex)}`;
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
return `<script setup>
|
|
1562
|
-
${imports.join("\n")}
|
|
1563
|
-
</script>
|
|
1564
|
-
${code}`;
|
|
1170
|
+
function transformVue(code) {
|
|
1171
|
+
if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
|
|
1172
|
+
return code;
|
|
1173
|
+
const imports = [
|
|
1174
|
+
templateImportContextUtils,
|
|
1175
|
+
templateInitContext,
|
|
1176
|
+
templateInjectionMarker
|
|
1177
|
+
];
|
|
1178
|
+
const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
|
|
1179
|
+
if (matchScript && matchScript[2]) {
|
|
1180
|
+
return code.replace(/(<script.*>)/g, `$1
|
|
1181
|
+
${imports.join("\n")}
|
|
1182
|
+
`);
|
|
1183
|
+
} else if (matchScript && !matchScript[2]) {
|
|
1184
|
+
const matchExport = code.match(/export\s+default\s+{/);
|
|
1185
|
+
if (matchExport) {
|
|
1186
|
+
const exportIndex = (matchExport.index || 0) + matchExport[0].length;
|
|
1187
|
+
let component = code.slice(exportIndex);
|
|
1188
|
+
component = component.slice(0, component.indexOf("</script>"));
|
|
1189
|
+
const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
|
|
1190
|
+
const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
|
|
1191
|
+
code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
|
|
1192
|
+
let injectIndex = exportIndex + provideImport.length;
|
|
1193
|
+
let injectObject = "$slidev: { from: injectionSlidevContext },";
|
|
1194
|
+
const matchInject = component.match(/.*inject\s*:\s*([\[{])/);
|
|
1195
|
+
if (matchInject) {
|
|
1196
|
+
injectIndex += (matchInject.index || 0) + matchInject[0].length;
|
|
1197
|
+
if (matchInject[1] === "[") {
|
|
1198
|
+
let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
|
|
1199
|
+
const injectEndIndex = injects.indexOf("]");
|
|
1200
|
+
injects = injects.slice(0, injectEndIndex);
|
|
1201
|
+
injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
|
|
1202
|
+
return `${code.slice(0, injectIndex - 1)}{
|
|
1203
|
+
${injectObject}
|
|
1204
|
+
}${code.slice(injectIndex + injectEndIndex + 1)}`;
|
|
1205
|
+
} else {
|
|
1206
|
+
return `${code.slice(0, injectIndex)}
|
|
1207
|
+
${injectObject}
|
|
1208
|
+
${code.slice(injectIndex)}`;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
return `${code.slice(0, injectIndex)}
|
|
1212
|
+
inject: { ${injectObject} },
|
|
1213
|
+
${code.slice(injectIndex)}`;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
return `<script setup>
|
|
1217
|
+
${imports.join("\n")}
|
|
1218
|
+
</script>
|
|
1219
|
+
${code}`;
|
|
1220
|
+
}
|
|
1221
|
+
function getTitle() {
|
|
1222
|
+
if (isString2(data.config.title)) {
|
|
1223
|
+
const tokens = md.parseInline(data.config.title, {});
|
|
1224
|
+
return stringifyMarkdownTokens(tokens);
|
|
1225
|
+
}
|
|
1226
|
+
return data.config.title;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// node/vite/markdown.ts
|
|
1231
|
+
import Markdown2 from "unplugin-vue-markdown/vite";
|
|
1232
|
+
import { slash } from "@antfu/utils";
|
|
1233
|
+
|
|
1234
|
+
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
|
|
1235
|
+
var SpecialCharacters;
|
|
1236
|
+
(function(SpecialCharacters2) {
|
|
1237
|
+
SpecialCharacters2[SpecialCharacters2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
|
|
1238
|
+
SpecialCharacters2[SpecialCharacters2["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
|
|
1239
|
+
SpecialCharacters2[SpecialCharacters2["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
|
|
1240
|
+
SpecialCharacters2[SpecialCharacters2["WHITESPACE"] = 32] = "WHITESPACE";
|
|
1241
|
+
SpecialCharacters2[SpecialCharacters2["NEW_LINE"] = 10] = "NEW_LINE";
|
|
1242
|
+
SpecialCharacters2[SpecialCharacters2["EQUALS"] = 61] = "EQUALS";
|
|
1243
|
+
SpecialCharacters2[SpecialCharacters2["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
|
|
1244
|
+
SpecialCharacters2[SpecialCharacters2["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
|
|
1245
|
+
SpecialCharacters2[SpecialCharacters2["NUMBER_NINE"] = 57] = "NUMBER_NINE";
|
|
1246
|
+
SpecialCharacters2[SpecialCharacters2["PERCENTAGE"] = 37] = "PERCENTAGE";
|
|
1247
|
+
SpecialCharacters2[SpecialCharacters2["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
|
|
1248
|
+
})(SpecialCharacters || (SpecialCharacters = {}));
|
|
1249
|
+
|
|
1250
|
+
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.0.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
|
|
1251
|
+
import Token from "markdown-it/lib/token.mjs";
|
|
1252
|
+
var checkboxRegex = /^ *\[([\sx])] /i;
|
|
1253
|
+
function taskLists(md2, options = { enabled: false, label: false, lineNumber: false }) {
|
|
1254
|
+
md2.core.ruler.after("inline", "task-lists", (state) => processToken(state, options));
|
|
1255
|
+
md2.renderer.rules.taskListItemCheckbox = (tokens) => {
|
|
1256
|
+
const token = tokens[0];
|
|
1257
|
+
const checkedAttribute = token.attrGet("checked") ? 'checked="" ' : "";
|
|
1258
|
+
const disabledAttribute = token.attrGet("disabled") ? 'disabled="" ' : "";
|
|
1259
|
+
const line = token.attrGet("line");
|
|
1260
|
+
const idAttribute = `id="${token.attrGet("id")}" `;
|
|
1261
|
+
const dataLineAttribute = line && options.lineNumber ? `data-line="${line}" ` : "";
|
|
1262
|
+
return `<input class="task-list-item-checkbox" type="checkbox" ${checkedAttribute}${disabledAttribute}${dataLineAttribute}${idAttribute}/>`;
|
|
1263
|
+
};
|
|
1264
|
+
md2.renderer.rules.taskListItemLabel_close = () => {
|
|
1265
|
+
return "</label>";
|
|
1266
|
+
};
|
|
1267
|
+
md2.renderer.rules.taskListItemLabel_open = (tokens) => {
|
|
1268
|
+
const token = tokens[0];
|
|
1269
|
+
const id = token.attrGet("id");
|
|
1270
|
+
return `<label for="${id}">`;
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
function processToken(state, options) {
|
|
1274
|
+
const allTokens = state.tokens;
|
|
1275
|
+
for (let i = 2; i < allTokens.length; i++) {
|
|
1276
|
+
if (!isTodoItem(allTokens, i)) {
|
|
1277
|
+
continue;
|
|
1278
|
+
}
|
|
1279
|
+
todoify(allTokens[i], options);
|
|
1280
|
+
allTokens[i - 2].attrJoin("class", `task-list-item ${options.enabled ? " enabled" : ""}`);
|
|
1281
|
+
const parentToken = findParentToken(allTokens, i - 2);
|
|
1282
|
+
if (parentToken) {
|
|
1283
|
+
const classes = parentToken.attrGet("class") ?? "";
|
|
1284
|
+
if (!classes.match(/(^| )contains-task-list/)) {
|
|
1285
|
+
parentToken.attrJoin("class", "contains-task-list");
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
return false;
|
|
1290
|
+
}
|
|
1291
|
+
function findParentToken(tokens, index) {
|
|
1292
|
+
const targetLevel = tokens[index].level - 1;
|
|
1293
|
+
for (let currentTokenIndex = index - 1; currentTokenIndex >= 0; currentTokenIndex--) {
|
|
1294
|
+
if (tokens[currentTokenIndex].level === targetLevel) {
|
|
1295
|
+
return tokens[currentTokenIndex];
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
return void 0;
|
|
1299
|
+
}
|
|
1300
|
+
function isTodoItem(tokens, index) {
|
|
1301
|
+
return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);
|
|
1302
|
+
}
|
|
1303
|
+
function todoify(token, options) {
|
|
1304
|
+
if (token.children == null) {
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
const id = generateIdForToken(token);
|
|
1308
|
+
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
1309
|
+
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
1310
|
+
if (options.label) {
|
|
1311
|
+
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
1312
|
+
token.children.push(createLabelEndToken());
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
function generateIdForToken(token) {
|
|
1316
|
+
if (token.map) {
|
|
1317
|
+
return `task-item-${token.map[0]}`;
|
|
1318
|
+
} else {
|
|
1319
|
+
return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
function createCheckboxToken(token, enabled, id) {
|
|
1323
|
+
const checkbox = new Token("taskListItemCheckbox", "", 0);
|
|
1324
|
+
if (!enabled) {
|
|
1325
|
+
checkbox.attrSet("disabled", "true");
|
|
1326
|
+
}
|
|
1327
|
+
if (token.map) {
|
|
1328
|
+
checkbox.attrSet("line", token.map[0].toString());
|
|
1329
|
+
}
|
|
1330
|
+
checkbox.attrSet("id", id);
|
|
1331
|
+
const checkboxRegexResult = checkboxRegex.exec(token.content);
|
|
1332
|
+
const isChecked = checkboxRegexResult?.[1].toLowerCase() === "x";
|
|
1333
|
+
if (isChecked) {
|
|
1334
|
+
checkbox.attrSet("checked", "true");
|
|
1335
|
+
}
|
|
1336
|
+
return checkbox;
|
|
1337
|
+
}
|
|
1338
|
+
function createLabelBeginToken(id) {
|
|
1339
|
+
const labelBeginToken = new Token("taskListItemLabel_open", "", 1);
|
|
1340
|
+
labelBeginToken.attrSet("id", id);
|
|
1341
|
+
return labelBeginToken;
|
|
1342
|
+
}
|
|
1343
|
+
function createLabelEndToken() {
|
|
1344
|
+
return new Token("taskListItemLabel_close", "", -1);
|
|
1345
|
+
}
|
|
1346
|
+
function isInline(token) {
|
|
1347
|
+
return token.type === "inline";
|
|
1348
|
+
}
|
|
1349
|
+
function isParagraph(token) {
|
|
1350
|
+
return token.type === "paragraph_open";
|
|
1351
|
+
}
|
|
1352
|
+
function isListItem(token) {
|
|
1353
|
+
return token.type === "list_item_open";
|
|
1354
|
+
}
|
|
1355
|
+
function startsWithTodoMarkdown(token) {
|
|
1356
|
+
return checkboxRegex.test(token.content);
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
// node/vite/markdown.ts
|
|
1360
|
+
import MarkdownItMdc from "markdown-it-mdc";
|
|
1361
|
+
import MarkdownItAttrs from "markdown-it-link-attributes";
|
|
1362
|
+
import MarkdownItFootnote from "markdown-it-footnote";
|
|
1363
|
+
|
|
1364
|
+
// node/syntax/markdown-it/markdown-it-katex.ts
|
|
1365
|
+
import katex from "katex";
|
|
1366
|
+
function isValidDelim(state, pos) {
|
|
1367
|
+
const max = state.posMax;
|
|
1368
|
+
let can_open = true;
|
|
1369
|
+
let can_close = true;
|
|
1370
|
+
const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;
|
|
1371
|
+
const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1;
|
|
1372
|
+
if (prevChar === 32 || prevChar === 9 || /* \t */
|
|
1373
|
+
nextChar >= 48 && nextChar <= 57)
|
|
1374
|
+
can_close = false;
|
|
1375
|
+
if (nextChar === 32 || nextChar === 9)
|
|
1376
|
+
can_open = false;
|
|
1377
|
+
return {
|
|
1378
|
+
can_open,
|
|
1379
|
+
can_close
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
function math_inline(state, silent) {
|
|
1383
|
+
let match, token, res, pos;
|
|
1384
|
+
if (state.src[state.pos] !== "$")
|
|
1385
|
+
return false;
|
|
1386
|
+
res = isValidDelim(state, state.pos);
|
|
1387
|
+
if (!res.can_open) {
|
|
1388
|
+
if (!silent)
|
|
1389
|
+
state.pending += "$";
|
|
1390
|
+
state.pos += 1;
|
|
1391
|
+
return true;
|
|
1392
|
+
}
|
|
1393
|
+
const start = state.pos + 1;
|
|
1394
|
+
match = start;
|
|
1395
|
+
while ((match = state.src.indexOf("$", match)) !== -1) {
|
|
1396
|
+
pos = match - 1;
|
|
1397
|
+
while (state.src[pos] === "\\")
|
|
1398
|
+
pos -= 1;
|
|
1399
|
+
if ((match - pos) % 2 === 1)
|
|
1400
|
+
break;
|
|
1401
|
+
match += 1;
|
|
1402
|
+
}
|
|
1403
|
+
if (match === -1) {
|
|
1404
|
+
if (!silent)
|
|
1405
|
+
state.pending += "$";
|
|
1406
|
+
state.pos = start;
|
|
1407
|
+
return true;
|
|
1565
1408
|
}
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1409
|
+
if (match - start === 0) {
|
|
1410
|
+
if (!silent)
|
|
1411
|
+
state.pending += "$$";
|
|
1412
|
+
state.pos = start + 1;
|
|
1413
|
+
return true;
|
|
1569
1414
|
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
if (
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
const layoutPaths = await fg2("layouts/**/*.{vue,ts}", {
|
|
1577
|
-
cwd: root,
|
|
1578
|
-
absolute: true,
|
|
1579
|
-
suppressErrors: true
|
|
1580
|
-
});
|
|
1581
|
-
for (const layoutPath of layoutPaths) {
|
|
1582
|
-
const layout = basename2(layoutPath).replace(/\.\w+$/, "");
|
|
1583
|
-
if (layouts[layout])
|
|
1584
|
-
continue;
|
|
1585
|
-
layouts[layout] = layoutPath;
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
_layouts_cache_time = now;
|
|
1589
|
-
_layouts_cache = layouts;
|
|
1590
|
-
return layouts;
|
|
1415
|
+
res = isValidDelim(state, match);
|
|
1416
|
+
if (!res.can_close) {
|
|
1417
|
+
if (!silent)
|
|
1418
|
+
state.pending += "$";
|
|
1419
|
+
state.pos = start;
|
|
1420
|
+
return true;
|
|
1591
1421
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1422
|
+
if (!silent) {
|
|
1423
|
+
token = state.push("math_inline", "math", 0);
|
|
1424
|
+
token.markup = "$";
|
|
1425
|
+
token.content = state.src.slice(start, match);
|
|
1594
1426
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1427
|
+
state.pos = match + 1;
|
|
1428
|
+
return true;
|
|
1429
|
+
}
|
|
1430
|
+
function math_block(state, start, end, silent) {
|
|
1431
|
+
let firstLine;
|
|
1432
|
+
let lastLine;
|
|
1433
|
+
let next;
|
|
1434
|
+
let lastPos;
|
|
1435
|
+
let found = false;
|
|
1436
|
+
let pos = state.bMarks[start] + state.tShift[start];
|
|
1437
|
+
let max = state.eMarks[start];
|
|
1438
|
+
if (pos + 2 > max)
|
|
1439
|
+
return false;
|
|
1440
|
+
if (state.src.slice(pos, pos + 2) !== "$$")
|
|
1441
|
+
return false;
|
|
1442
|
+
pos += 2;
|
|
1443
|
+
firstLine = state.src.slice(pos, max);
|
|
1444
|
+
if (silent)
|
|
1445
|
+
return true;
|
|
1446
|
+
if (firstLine.trim().slice(-2) === "$$") {
|
|
1447
|
+
firstLine = firstLine.trim().slice(0, -2);
|
|
1448
|
+
found = true;
|
|
1597
1449
|
}
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
for (const root of roots) {
|
|
1607
|
-
const styles = [
|
|
1608
|
-
join4(root, "styles", "index.ts"),
|
|
1609
|
-
join4(root, "styles", "index.js"),
|
|
1610
|
-
join4(root, "styles", "index.css"),
|
|
1611
|
-
join4(root, "styles.css"),
|
|
1612
|
-
join4(root, "style.css")
|
|
1613
|
-
];
|
|
1614
|
-
for (const style of styles) {
|
|
1615
|
-
if (fs5.existsSync(style)) {
|
|
1616
|
-
imports.push(`import "${toAtFS(style)}"`);
|
|
1617
|
-
continue;
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
if (data.features.katex)
|
|
1622
|
-
imports.push(`import "${await resolveUrl("katex/dist/katex.min.css")}"`);
|
|
1623
|
-
if (data.config.highlighter === "shiki") {
|
|
1624
|
-
imports.push(
|
|
1625
|
-
`import "${await resolveUrl("@shikijs/vitepress-twoslash/style.css")}"`,
|
|
1626
|
-
`import "${resolveUrlOfClient("styles/shiki-twoslash.css")}"`
|
|
1627
|
-
);
|
|
1450
|
+
for (next = start; !found; ) {
|
|
1451
|
+
next++;
|
|
1452
|
+
if (next >= end)
|
|
1453
|
+
break;
|
|
1454
|
+
pos = state.bMarks[next] + state.tShift[next];
|
|
1455
|
+
max = state.eMarks[next];
|
|
1456
|
+
if (pos < max && state.tShift[next] < state.blkIndent) {
|
|
1457
|
+
break;
|
|
1628
1458
|
}
|
|
1629
|
-
if (
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
'import "uno:typography.css"',
|
|
1634
|
-
'import "uno:shortcuts.css"'
|
|
1635
|
-
);
|
|
1636
|
-
imports.push('import "uno.css"');
|
|
1459
|
+
if (state.src.slice(pos, max).trim().slice(-2) === "$$") {
|
|
1460
|
+
lastPos = state.src.slice(0, max).lastIndexOf("$$");
|
|
1461
|
+
lastLine = state.src.slice(pos, lastPos);
|
|
1462
|
+
found = true;
|
|
1637
1463
|
}
|
|
1638
|
-
return imports.join("\n");
|
|
1639
1464
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1465
|
+
state.line = next + 1;
|
|
1466
|
+
const token = state.push("math_block", "math", 0);
|
|
1467
|
+
token.block = true;
|
|
1468
|
+
token.content = (firstLine && firstLine.trim() ? `${firstLine}
|
|
1469
|
+
` : "") + state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : "");
|
|
1470
|
+
token.map = [start, state.line];
|
|
1471
|
+
token.markup = "$$";
|
|
1472
|
+
return true;
|
|
1473
|
+
}
|
|
1474
|
+
function math_plugin(md2, options) {
|
|
1475
|
+
options = options || {};
|
|
1476
|
+
const katexInline = function(latex) {
|
|
1477
|
+
options.displayMode = false;
|
|
1478
|
+
try {
|
|
1479
|
+
return katex.renderToString(latex, options);
|
|
1480
|
+
} catch (error) {
|
|
1481
|
+
if (options.throwOnError)
|
|
1482
|
+
console.warn(error);
|
|
1483
|
+
return latex;
|
|
1648
1484
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
if (
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
const moduleName = a.startsWith("@") ? `${a}/${b}` : a;
|
|
1662
|
-
return moduleName;
|
|
1485
|
+
};
|
|
1486
|
+
const inlineRenderer = function(tokens, idx) {
|
|
1487
|
+
return katexInline(tokens[idx].content);
|
|
1488
|
+
};
|
|
1489
|
+
const katexBlock = function(latex) {
|
|
1490
|
+
options.displayMode = true;
|
|
1491
|
+
try {
|
|
1492
|
+
return `<p>${katex.renderToString(latex, options)}</p>`;
|
|
1493
|
+
} catch (error) {
|
|
1494
|
+
if (options.throwOnError)
|
|
1495
|
+
console.warn(error);
|
|
1496
|
+
return latex;
|
|
1663
1497
|
}
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
const moduleName = mapModuleNameToModule(specifier);
|
|
1668
|
-
result += `import(${JSON.stringify(`/@slidev-monaco-types/resolve?pkg=${moduleName}`)})
|
|
1498
|
+
};
|
|
1499
|
+
const blockRenderer = function(tokens, idx) {
|
|
1500
|
+
return `${katexBlock(tokens[idx].content)}
|
|
1669
1501
|
`;
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
const
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
`if (import.meta.hot) {`,
|
|
1720
|
-
` import.meta.hot.accept()`,
|
|
1721
|
-
`}`
|
|
1722
|
-
].join("\n");
|
|
1502
|
+
};
|
|
1503
|
+
md2.inline.ruler.after("escape", "math_inline", math_inline);
|
|
1504
|
+
md2.block.ruler.after("blockquote", "math_block", math_block, {
|
|
1505
|
+
alt: ["paragraph", "reference", "blockquote", "list"]
|
|
1506
|
+
});
|
|
1507
|
+
md2.renderer.rules.math_inline = inlineRenderer;
|
|
1508
|
+
md2.renderer.rules.math_block = blockRenderer;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// node/syntax/markdown-it/markdown-it-prism.ts
|
|
1512
|
+
import { createRequire } from "node:module";
|
|
1513
|
+
import Prism from "prismjs";
|
|
1514
|
+
import loadLanguages from "prismjs/components/index.js";
|
|
1515
|
+
import * as htmlparser2 from "htmlparser2";
|
|
1516
|
+
|
|
1517
|
+
// node/syntax/transform/utils.ts
|
|
1518
|
+
function normalizeRangeStr(rangeStr = "") {
|
|
1519
|
+
return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1520
|
+
}
|
|
1521
|
+
function getCodeBlocks(md2) {
|
|
1522
|
+
const codeblocks = Array.from(md2.matchAll(/^```[\s\S]*?^```/mg)).map((m) => {
|
|
1523
|
+
const start = m.index;
|
|
1524
|
+
const end = m.index + m[0].length;
|
|
1525
|
+
const startLine = md2.slice(0, start).match(/\n/g)?.length || 0;
|
|
1526
|
+
const endLine = md2.slice(0, end).match(/\n/g)?.length || 0;
|
|
1527
|
+
return [start, end, startLine, endLine];
|
|
1528
|
+
});
|
|
1529
|
+
return {
|
|
1530
|
+
codeblocks,
|
|
1531
|
+
isInsideCodeblocks(idx) {
|
|
1532
|
+
return codeblocks.some(([s, e]) => s <= idx && idx <= e);
|
|
1533
|
+
},
|
|
1534
|
+
isLineInsideCodeblocks(line) {
|
|
1535
|
+
return codeblocks.some(([, , s, e]) => s <= line && line <= e);
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
function escapeVueInCode(md2) {
|
|
1540
|
+
return md2.replace(/{{/g, "{{");
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
// node/syntax/markdown-it/markdown-it-prism.ts
|
|
1544
|
+
var require2 = createRequire(import.meta.url);
|
|
1545
|
+
var Tag = class {
|
|
1546
|
+
tagname;
|
|
1547
|
+
attributes;
|
|
1548
|
+
constructor(tagname, attributes) {
|
|
1549
|
+
this.tagname = tagname;
|
|
1550
|
+
this.attributes = attributes;
|
|
1723
1551
|
}
|
|
1724
|
-
|
|
1725
|
-
return [
|
|
1726
|
-
`export { slides } from '#slidev/slides'`,
|
|
1727
|
-
`console.warn('[slidev] #slidev/routes is deprecated, use #slidev/slides instead')`
|
|
1728
|
-
].join("\n");
|
|
1552
|
+
asOpen() {
|
|
1553
|
+
return `<${this.tagname} ${Object.entries(this.attributes).map(([key, value]) => `${key}="${value}"`).join(" ")}>`;
|
|
1729
1554
|
}
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
const tokens = md.parseInline(data.config.title, {});
|
|
1733
|
-
return stringifyMarkdownTokens(tokens);
|
|
1734
|
-
}
|
|
1735
|
-
return data.config.title;
|
|
1555
|
+
asClosed() {
|
|
1556
|
+
return `</${this.tagname}>`;
|
|
1736
1557
|
}
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1558
|
+
};
|
|
1559
|
+
var DEFAULTS = {
|
|
1560
|
+
plugins: [],
|
|
1561
|
+
init: () => {
|
|
1562
|
+
},
|
|
1563
|
+
defaultLanguageForUnknown: void 0,
|
|
1564
|
+
defaultLanguageForUnspecified: void 0,
|
|
1565
|
+
defaultLanguage: void 0
|
|
1566
|
+
};
|
|
1567
|
+
function loadPrismLang(lang) {
|
|
1568
|
+
if (!lang)
|
|
1569
|
+
return void 0;
|
|
1570
|
+
let langObject = Prism.languages[lang];
|
|
1571
|
+
if (langObject === void 0) {
|
|
1572
|
+
loadLanguages([lang]);
|
|
1573
|
+
langObject = Prism.languages[lang];
|
|
1746
1574
|
}
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
];
|
|
1755
|
-
} else {
|
|
1756
|
-
return [
|
|
1757
|
-
join4(root, "global-bottom.vue"),
|
|
1758
|
-
join4(root, "GlobalBottom.vue")
|
|
1759
|
-
];
|
|
1760
|
-
}
|
|
1761
|
-
}).filter((i) => fs5.existsSync(i));
|
|
1762
|
-
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
1763
|
-
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
1764
|
-
return `
|
|
1765
|
-
${imports}
|
|
1766
|
-
import { h } from 'vue'
|
|
1767
|
-
export default {
|
|
1768
|
-
render() {
|
|
1769
|
-
return [${render}]
|
|
1575
|
+
return langObject;
|
|
1576
|
+
}
|
|
1577
|
+
function loadPrismPlugin(name) {
|
|
1578
|
+
try {
|
|
1579
|
+
require2(`prismjs/plugins/${name}/prism-${name}`);
|
|
1580
|
+
} catch (e) {
|
|
1581
|
+
throw new Error(`Cannot load Prism plugin "${name}". Please check the spelling.`);
|
|
1770
1582
|
}
|
|
1771
1583
|
}
|
|
1772
|
-
|
|
1584
|
+
function selectLanguage(options, lang) {
|
|
1585
|
+
let langToUse = lang;
|
|
1586
|
+
if (langToUse === "" && options.defaultLanguageForUnspecified !== void 0)
|
|
1587
|
+
langToUse = options.defaultLanguageForUnspecified;
|
|
1588
|
+
let prismLang = loadPrismLang(langToUse);
|
|
1589
|
+
if (prismLang === void 0 && options.defaultLanguageForUnknown !== void 0) {
|
|
1590
|
+
langToUse = options.defaultLanguageForUnknown;
|
|
1591
|
+
prismLang = loadPrismLang(langToUse);
|
|
1773
1592
|
}
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1593
|
+
return [langToUse, prismLang];
|
|
1594
|
+
}
|
|
1595
|
+
function highlight(markdownit, options, text, lang) {
|
|
1596
|
+
const [langToUse, prismLang] = selectLanguage(options, lang);
|
|
1597
|
+
let code = text.trimEnd();
|
|
1598
|
+
code = prismLang ? highlightPrism(code, prismLang, langToUse) : markdownit.utils.escapeHtml(code);
|
|
1599
|
+
code = code.split(/\r?\n/g).map((line) => `<span class="line">${line}</span>`).join("\n");
|
|
1600
|
+
const classAttribute = langToUse ? ` class="slidev-code ${markdownit.options.langPrefix}${markdownit.utils.escapeHtml(langToUse)}"` : "";
|
|
1601
|
+
return escapeVueInCode(`<pre${classAttribute}><code>${code}</code></pre>`);
|
|
1602
|
+
}
|
|
1603
|
+
function highlightPrism(code, prismLang, langToUse) {
|
|
1604
|
+
const openTags = [];
|
|
1605
|
+
const parser2 = new htmlparser2.Parser({
|
|
1606
|
+
onopentag(tagname, attributes) {
|
|
1607
|
+
openTags.push(new Tag(tagname, attributes));
|
|
1608
|
+
},
|
|
1609
|
+
onclosetag() {
|
|
1610
|
+
openTags.pop();
|
|
1611
|
+
}
|
|
1612
|
+
});
|
|
1613
|
+
code = Prism.highlight(code, prismLang, langToUse);
|
|
1614
|
+
code = code.split(/\r?\n/g).map((line) => {
|
|
1615
|
+
const prefix = openTags.map((tag) => tag.asOpen()).join("");
|
|
1616
|
+
parser2.write(line);
|
|
1617
|
+
const postfix = openTags.reverse().map((tag) => tag.asClosed()).join("");
|
|
1618
|
+
return prefix + line + postfix;
|
|
1619
|
+
}).join("\n");
|
|
1620
|
+
parser2.end();
|
|
1621
|
+
return code;
|
|
1622
|
+
}
|
|
1623
|
+
function checkLanguageOption(options, optionName) {
|
|
1624
|
+
const language = options[optionName];
|
|
1625
|
+
if (language !== void 0 && loadPrismLang(language) === void 0)
|
|
1626
|
+
throw new Error(`Bad option ${optionName}: There is no Prism language '${language}'.`);
|
|
1627
|
+
}
|
|
1628
|
+
function markdownItPrism(markdownit, useroptions) {
|
|
1629
|
+
const options = Object.assign({}, DEFAULTS, useroptions);
|
|
1630
|
+
checkLanguageOption(options, "defaultLanguage");
|
|
1631
|
+
checkLanguageOption(options, "defaultLanguageForUnknown");
|
|
1632
|
+
checkLanguageOption(options, "defaultLanguageForUnspecified");
|
|
1633
|
+
options.defaultLanguageForUnknown = options.defaultLanguageForUnknown || options.defaultLanguage;
|
|
1634
|
+
options.defaultLanguageForUnspecified = options.defaultLanguageForUnspecified || options.defaultLanguage;
|
|
1635
|
+
options.plugins.forEach(loadPrismPlugin);
|
|
1636
|
+
options.init(Prism);
|
|
1637
|
+
markdownit.options.highlight = (text, lang) => highlight(markdownit, options, text, lang);
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
// node/syntax/transform/code-wrapper.ts
|
|
1641
|
+
var reCodeBlock = /^```([\w'-]+?)(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?(.*?))?\n([\s\S]+?)^```$/mg;
|
|
1642
|
+
function transformCodeWrapper(md2) {
|
|
1643
|
+
return md2.replace(
|
|
1644
|
+
reCodeBlock,
|
|
1645
|
+
(full, lang = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
1646
|
+
const ranges = normalizeRangeStr(rangeStr);
|
|
1647
|
+
code = code.trimEnd();
|
|
1648
|
+
options = options.trim() || "{}";
|
|
1649
|
+
return `
|
|
1650
|
+
<CodeBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1651
|
+
|
|
1652
|
+
\`\`\`${lang}${attrs}
|
|
1653
|
+
${code}
|
|
1654
|
+
\`\`\`
|
|
1655
|
+
|
|
1656
|
+
</CodeBlockWrapper>`;
|
|
1657
|
+
}
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
// node/syntax/transform/magic-move.ts
|
|
1662
|
+
import { codeToKeyedTokens } from "shiki-magic-move/core";
|
|
1663
|
+
import lz2 from "lz-string";
|
|
1664
|
+
var reMagicMoveBlock = /^````(?:md|markdown) magic-move(?:[ ]*(\{.*?\})?([^\n]*?))?\n([\s\S]+?)^````$/mg;
|
|
1665
|
+
function transformMagicMove(md2, shiki2, shikiOptions2) {
|
|
1666
|
+
return md2.replace(
|
|
1667
|
+
reMagicMoveBlock,
|
|
1668
|
+
(full, options = "{}", _attrs = "", body) => {
|
|
1669
|
+
if (!shiki2 || !shikiOptions2)
|
|
1670
|
+
throw new Error("Shiki is required for Magic Move. You may need to set `highlighter: shiki` in your Slidev config.");
|
|
1671
|
+
const matches = Array.from(body.matchAll(reCodeBlock));
|
|
1672
|
+
if (!matches.length)
|
|
1673
|
+
throw new Error("Magic Move block must contain at least one code block");
|
|
1674
|
+
const ranges = matches.map((i) => normalizeRangeStr(i[2]));
|
|
1675
|
+
const steps = matches.map(
|
|
1676
|
+
(i) => codeToKeyedTokens(shiki2, i[5].trimEnd(), {
|
|
1677
|
+
...shikiOptions2,
|
|
1678
|
+
lang: i[1]
|
|
1679
|
+
})
|
|
1680
|
+
);
|
|
1681
|
+
const compressed = lz2.compressToBase64(JSON.stringify(steps));
|
|
1682
|
+
return `<ShikiMagicMove v-bind="${options}" steps-lz="${compressed}" :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
1683
|
+
}
|
|
1684
|
+
);
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
// node/syntax/transform/mermaid.ts
|
|
1688
|
+
import lz3 from "lz-string";
|
|
1689
|
+
function transformMermaid(md2) {
|
|
1690
|
+
return md2.replace(/^```mermaid\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", code = "") => {
|
|
1691
|
+
code = code.trim();
|
|
1692
|
+
options = options.trim() || "{}";
|
|
1693
|
+
const encoded = lz3.compressToBase64(code);
|
|
1694
|
+
return `<Mermaid code-lz="${encoded}" v-bind="${options}" />`;
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
// node/syntax/transform/plant-uml.ts
|
|
1699
|
+
import { encode as encodePlantUml } from "plantuml-encoder";
|
|
1700
|
+
function transformPlantUml(md2, server) {
|
|
1701
|
+
return md2.replace(/^```plantuml\s*?({.*?})?\n([\s\S]+?)\n```/mg, (full, options = "", content = "") => {
|
|
1702
|
+
const code = encodePlantUml(content.trim());
|
|
1703
|
+
options = options.trim() || "{}";
|
|
1704
|
+
return `<PlantUml :code="'${code}'" :server="'${server}'" v-bind="${options}" />`;
|
|
1705
|
+
});
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
// node/syntax/transform/snippet.ts
|
|
1709
|
+
import path from "node:path";
|
|
1710
|
+
import fs5 from "fs-extra";
|
|
1711
|
+
function dedent(text) {
|
|
1712
|
+
const lines = text.split("\n");
|
|
1713
|
+
const minIndentLength = lines.reduce((acc, line) => {
|
|
1714
|
+
for (let i = 0; i < line.length; i++) {
|
|
1715
|
+
if (line[i] !== " " && line[i] !== " ")
|
|
1716
|
+
return Math.min(i, acc);
|
|
1717
|
+
}
|
|
1718
|
+
return acc;
|
|
1719
|
+
}, Number.POSITIVE_INFINITY);
|
|
1720
|
+
if (minIndentLength < Number.POSITIVE_INFINITY)
|
|
1721
|
+
return lines.map((x) => x.slice(minIndentLength)).join("\n");
|
|
1722
|
+
return text;
|
|
1723
|
+
}
|
|
1724
|
+
function testLine(line, regexp, regionName, end = false) {
|
|
1725
|
+
const [full, tag, name] = regexp.exec(line.trim()) || [];
|
|
1726
|
+
return full && tag && name === regionName && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/);
|
|
1727
|
+
}
|
|
1728
|
+
function findRegion(lines, regionName) {
|
|
1729
|
+
const regionRegexps = [
|
|
1730
|
+
/^\/\/ ?#?((?:end)?region) ([\w*-]+)$/,
|
|
1731
|
+
// javascript, typescript, java
|
|
1732
|
+
/^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/,
|
|
1733
|
+
// css, less, scss
|
|
1734
|
+
/^#pragma ((?:end)?region) ([\w*-]+)$/,
|
|
1735
|
+
// C, C++
|
|
1736
|
+
/^<!-- #?((?:end)?region) ([\w*-]+) -->$/,
|
|
1737
|
+
// HTML, markdown
|
|
1738
|
+
/^#((?:End )Region) ([\w*-]+)$/,
|
|
1739
|
+
// Visual Basic
|
|
1740
|
+
/^::#((?:end)region) ([\w*-]+)$/,
|
|
1741
|
+
// Bat
|
|
1742
|
+
/^# ?((?:end)?region) ([\w*-]+)$/
|
|
1743
|
+
// C#, PHP, Powershell, Python, perl & misc
|
|
1744
|
+
];
|
|
1745
|
+
let regexp = null;
|
|
1746
|
+
let start = -1;
|
|
1747
|
+
for (const [lineId, line] of lines.entries()) {
|
|
1748
|
+
if (regexp === null) {
|
|
1749
|
+
for (const reg of regionRegexps) {
|
|
1750
|
+
if (testLine(line, reg, regionName)) {
|
|
1751
|
+
start = lineId + 1;
|
|
1752
|
+
regexp = reg;
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
} else if (testLine(line, regexp, regionName, true)) {
|
|
1757
|
+
return { start, end: lineId, regexp };
|
|
1758
|
+
}
|
|
1789
1759
|
}
|
|
1760
|
+
return null;
|
|
1761
|
+
}
|
|
1762
|
+
function transformSnippet(md2, options, id) {
|
|
1763
|
+
const slideId = id.match(/(\d+)\.md$/)?.[1];
|
|
1764
|
+
if (!slideId)
|
|
1765
|
+
return md2;
|
|
1766
|
+
const data = options.data;
|
|
1767
|
+
const slideInfo = data.slides[+slideId - 1];
|
|
1768
|
+
const dir = path.dirname(slideInfo.source?.filepath ?? options.entry ?? options.userRoot);
|
|
1769
|
+
return md2.replace(
|
|
1770
|
+
/^<<< *(.+?)(#[\w-]+)? *(?: (\S+?))? *(\{.*)?$/mg,
|
|
1771
|
+
(full, filepath = "", regionName = "", lang = "", meta = "") => {
|
|
1772
|
+
const firstLine = `\`\`\`${lang || path.extname(filepath).slice(1)} ${meta}`;
|
|
1773
|
+
const src = /^\@[\/]/.test(filepath) ? path.resolve(options.userRoot, filepath.slice(2)) : path.resolve(dir, filepath);
|
|
1774
|
+
data.watchFiles.push(src);
|
|
1775
|
+
const isAFile = fs5.statSync(src).isFile();
|
|
1776
|
+
if (!fs5.existsSync(src) || !isAFile) {
|
|
1777
|
+
throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
|
|
1778
|
+
}
|
|
1779
|
+
let content = fs5.readFileSync(src, "utf8");
|
|
1780
|
+
slideInfo.snippetsUsed ??= {};
|
|
1781
|
+
slideInfo.snippetsUsed[src] = content;
|
|
1782
|
+
if (regionName) {
|
|
1783
|
+
const lines = content.split(/\r?\n/);
|
|
1784
|
+
const region = findRegion(lines, regionName.slice(1));
|
|
1785
|
+
if (region) {
|
|
1786
|
+
content = dedent(
|
|
1787
|
+
lines.slice(region.start, region.end).filter((line) => !region.regexp.test(line.trim())).join("\n")
|
|
1788
|
+
);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
return `${firstLine}
|
|
1792
|
+
${content}
|
|
1793
|
+
\`\`\``;
|
|
1794
|
+
}
|
|
1795
|
+
);
|
|
1790
1796
|
}
|
|
1797
|
+
|
|
1798
|
+
// node/syntax/transform/slot-sugar.ts
|
|
1799
|
+
function transformSlotSugar(md2) {
|
|
1800
|
+
const lines = md2.split(/\r?\n/g);
|
|
1801
|
+
let prevSlot = false;
|
|
1802
|
+
const { isLineInsideCodeblocks } = getCodeBlocks(md2);
|
|
1803
|
+
lines.forEach((line, idx) => {
|
|
1804
|
+
if (isLineInsideCodeblocks(idx))
|
|
1805
|
+
return;
|
|
1806
|
+
const match = line.trimEnd().match(/^::\s*([\w\.\-\:]+)\s*::$/);
|
|
1807
|
+
if (match) {
|
|
1808
|
+
lines[idx] = `${prevSlot ? "\n\n</template>\n" : "\n"}<template v-slot:${match[1]}="slotProps">
|
|
1791
1809
|
`;
|
|
1792
|
-
|
|
1793
|
-
async function generteShikiBundle() {
|
|
1794
|
-
const options = await loadShikiSetups(clientRoot, roots);
|
|
1795
|
-
const langs = await resolveLangs(options.langs || ["javascript", "typescript", "html", "css"]);
|
|
1796
|
-
const resolvedThemeOptions = "themes" in options ? {
|
|
1797
|
-
themes: Object.fromEntries(await Promise.all(
|
|
1798
|
-
Object.entries(options.themes).map(async ([name, value]) => [name, await resolveTheme(value)])
|
|
1799
|
-
))
|
|
1800
|
-
} : {
|
|
1801
|
-
theme: await resolveTheme(options.theme || "vitesse-dark")
|
|
1802
|
-
};
|
|
1803
|
-
const themes = resolvedThemeOptions.themes ? Object.values(resolvedThemeOptions.themes) : [resolvedThemeOptions.theme];
|
|
1804
|
-
const themeOptionsNames = resolvedThemeOptions.themes ? { themes: Object.fromEntries(Object.entries(resolvedThemeOptions.themes).map(([name, value]) => [name, typeof value === "string" ? value : value.name])) } : { theme: typeof resolvedThemeOptions.theme === "string" ? resolvedThemeOptions.theme : resolvedThemeOptions.theme.name };
|
|
1805
|
-
async function normalizeGetter(p) {
|
|
1806
|
-
return Promise.resolve(typeof p === "function" ? p() : p).then((r) => r.default || r);
|
|
1810
|
+
prevSlot = true;
|
|
1807
1811
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
+
});
|
|
1813
|
+
if (prevSlot)
|
|
1814
|
+
lines[lines.length - 1] += "\n\n</template>";
|
|
1815
|
+
return lines.join("\n");
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
// node/syntax/transform/in-page-css.ts
|
|
1819
|
+
function transformPageCSS(md2, id) {
|
|
1820
|
+
const page = id.match(/(\d+)\.md$/)?.[1];
|
|
1821
|
+
if (!page)
|
|
1822
|
+
return md2;
|
|
1823
|
+
const { isInsideCodeblocks } = getCodeBlocks(md2);
|
|
1824
|
+
const result = md2.replace(
|
|
1825
|
+
/(\n<style[^>]*?>)([\s\S]+?)(<\/style>)/g,
|
|
1826
|
+
(full, start, css, end, index) => {
|
|
1827
|
+
if (index < 0 || isInsideCodeblocks(index))
|
|
1828
|
+
return full;
|
|
1829
|
+
if (!start.includes("scoped"))
|
|
1830
|
+
start = start.replace("<style", "<style scoped");
|
|
1831
|
+
return `${start}
|
|
1832
|
+
${css}${end}`;
|
|
1812
1833
|
}
|
|
1813
|
-
|
|
1814
|
-
|
|
1834
|
+
);
|
|
1835
|
+
return result;
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
// node/syntax/transform/katex-wrapper.ts
|
|
1839
|
+
function transformKaTexWrapper(md2) {
|
|
1840
|
+
return md2.replace(
|
|
1841
|
+
/^\$\$(?:\s*{([\d\w*,\|-]+)}\s*?({.*?})?\s*?)?\n([\s\S]+?)^\$\$/mg,
|
|
1842
|
+
(full, rangeStr = "", options = "", code) => {
|
|
1843
|
+
const ranges = !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1844
|
+
code = code.trimEnd();
|
|
1845
|
+
options = options.trim() || "{}";
|
|
1846
|
+
return `<KaTexBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1847
|
+
|
|
1848
|
+
$$
|
|
1849
|
+
${code}
|
|
1850
|
+
$$
|
|
1851
|
+
</KaTexBlockWrapper>
|
|
1852
|
+
`;
|
|
1815
1853
|
}
|
|
1816
|
-
|
|
1817
|
-
langs.map(async (lang) => typeof lang === "string" ? `import('${await resolveUrl(`shiki/langs/${lang}.mjs`)}')` : JSON.stringify(lang))
|
|
1818
|
-
);
|
|
1819
|
-
const themesInit = await Promise.all(themes.map(async (theme) => typeof theme === "string" ? `import('${await resolveUrl(`shiki/themes/${theme}.mjs`)}')` : JSON.stringify(theme)));
|
|
1820
|
-
const langNames = langs.flatMap((lang) => typeof lang === "string" ? lang : lang.name);
|
|
1821
|
-
const lines = [];
|
|
1822
|
-
lines.push(
|
|
1823
|
-
`import { getHighlighterCore } from "${await resolveUrl("shiki/core")}"`,
|
|
1824
|
-
`export { shikiToMonaco } from "${await resolveUrl("@shikijs/monaco")}"`,
|
|
1825
|
-
`export const languages = ${JSON.stringify(langNames)}`,
|
|
1826
|
-
`export const themes = ${JSON.stringify(themeOptionsNames.themes || themeOptionsNames.theme)}`,
|
|
1827
|
-
"export const shiki = getHighlighterCore({",
|
|
1828
|
-
` themes: [${themesInit.join(",")}],`,
|
|
1829
|
-
` langs: [${langsInit.join(",")}],`,
|
|
1830
|
-
` loadWasm: import('${await resolveUrl("shiki/wasm")}'),`,
|
|
1831
|
-
"})"
|
|
1832
|
-
);
|
|
1833
|
-
return lines.join("\n");
|
|
1834
|
-
}
|
|
1854
|
+
);
|
|
1835
1855
|
}
|
|
1836
1856
|
|
|
1837
|
-
// node/
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
const matches = Array.from(code.matchAll(/\binjection_arg(_\d+)?\b/g));
|
|
1870
|
-
const dedupedMatches = Array.from(new Set(matches.map((m) => m[0])));
|
|
1871
|
-
fn += dedupedMatches.join(", ");
|
|
1872
|
-
fn += ", :LAST:)";
|
|
1873
|
-
} else {
|
|
1874
|
-
fn += "(:LAST:)";
|
|
1857
|
+
// node/vite/markdown.ts
|
|
1858
|
+
var shiki;
|
|
1859
|
+
var shikiOptions;
|
|
1860
|
+
async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
1861
|
+
const { data: { config }, roots, mode, entry, clientRoot } = options;
|
|
1862
|
+
const setups = [];
|
|
1863
|
+
const entryPath = slash(entry);
|
|
1864
|
+
if (config.highlighter === "shiki") {
|
|
1865
|
+
const [
|
|
1866
|
+
options2,
|
|
1867
|
+
{ getHighlighter, bundledLanguages },
|
|
1868
|
+
markdownItShiki,
|
|
1869
|
+
transformerTwoslash
|
|
1870
|
+
] = await Promise.all([
|
|
1871
|
+
loadShikiSetups(clientRoot, roots),
|
|
1872
|
+
import("shiki").then(({ getHighlighter: getHighlighter2, bundledLanguages: bundledLanguages2 }) => ({ bundledLanguages: bundledLanguages2, getHighlighter: getHighlighter2 })),
|
|
1873
|
+
import("@shikijs/markdown-it/core").then(({ fromHighlighter }) => fromHighlighter),
|
|
1874
|
+
import("@shikijs/vitepress-twoslash").then(({ transformerTwoslash: transformerTwoslash2 }) => transformerTwoslash2)
|
|
1875
|
+
]);
|
|
1876
|
+
shikiOptions = options2;
|
|
1877
|
+
shiki = await getHighlighter({
|
|
1878
|
+
...options2,
|
|
1879
|
+
langs: options2.langs ?? Object.keys(bundledLanguages),
|
|
1880
|
+
themes: "themes" in options2 ? Object.values(options2.themes) : [options2.theme]
|
|
1881
|
+
});
|
|
1882
|
+
const transformers = [
|
|
1883
|
+
...options2.transformers || [],
|
|
1884
|
+
transformerTwoslash({
|
|
1885
|
+
explicitTrigger: true,
|
|
1886
|
+
twoslashOptions: {
|
|
1887
|
+
handbookOptions: {
|
|
1888
|
+
noErrorValidation: true
|
|
1875
1889
|
}
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
code
|
|
1884
|
-
|
|
1885
|
-
|
|
1890
|
+
}
|
|
1891
|
+
}),
|
|
1892
|
+
{
|
|
1893
|
+
pre(pre) {
|
|
1894
|
+
this.addClassToHast(pre, "slidev-code");
|
|
1895
|
+
delete pre.properties.tabindex;
|
|
1896
|
+
},
|
|
1897
|
+
postprocess(code) {
|
|
1898
|
+
return escapeVueInCode(code);
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
];
|
|
1902
|
+
const plugin = markdownItShiki(shiki, {
|
|
1903
|
+
...options2,
|
|
1904
|
+
transformers
|
|
1905
|
+
});
|
|
1906
|
+
setups.push((md2) => md2.use(plugin));
|
|
1907
|
+
} else {
|
|
1908
|
+
setups.push((md2) => md2.use(markdownItPrism));
|
|
1909
|
+
}
|
|
1910
|
+
if (config.mdc)
|
|
1911
|
+
setups.push((md2) => md2.use(MarkdownItMdc));
|
|
1912
|
+
const KatexOptions = await loadSetups(options.clientRoot, roots, "katex.ts", {}, { strict: false }, false);
|
|
1913
|
+
return Markdown2({
|
|
1914
|
+
include: [/\.md$/],
|
|
1915
|
+
wrapperClasses: "",
|
|
1916
|
+
headEnabled: false,
|
|
1917
|
+
frontmatter: false,
|
|
1918
|
+
escapeCodeTagInterpolation: false,
|
|
1919
|
+
markdownItOptions: {
|
|
1920
|
+
quotes: `""''`,
|
|
1921
|
+
html: true,
|
|
1922
|
+
xhtmlOut: true,
|
|
1923
|
+
linkify: true,
|
|
1924
|
+
...mdOptions?.markdownItOptions
|
|
1925
|
+
},
|
|
1926
|
+
...mdOptions,
|
|
1927
|
+
markdownItSetup(md2) {
|
|
1928
|
+
md2.use(MarkdownItAttrs, {
|
|
1929
|
+
attrs: {
|
|
1930
|
+
target: "_blank",
|
|
1931
|
+
rel: "noopener"
|
|
1932
|
+
}
|
|
1933
|
+
});
|
|
1934
|
+
md2.use(MarkdownItFootnote);
|
|
1935
|
+
md2.use(taskLists, { enabled: true, lineNumber: true, label: true });
|
|
1936
|
+
md2.use(math_plugin, KatexOptions);
|
|
1937
|
+
setups.forEach((i) => i(md2));
|
|
1938
|
+
mdOptions?.markdownItSetup?.(md2);
|
|
1939
|
+
},
|
|
1940
|
+
transforms: {
|
|
1941
|
+
before(code, id) {
|
|
1942
|
+
if (id === entryPath)
|
|
1943
|
+
return "";
|
|
1944
|
+
const monacoEnabled = config.monaco === true || config.monaco === mode;
|
|
1945
|
+
if (config.highlighter === "shiki")
|
|
1946
|
+
code = transformMagicMove(code, shiki, shikiOptions);
|
|
1947
|
+
code = transformSlotSugar(code);
|
|
1948
|
+
code = transformSnippet(code, options, id);
|
|
1949
|
+
code = transformMermaid(code);
|
|
1950
|
+
code = transformPlantUml(code, config.plantUmlServer);
|
|
1951
|
+
code = transformMonaco(code, monacoEnabled);
|
|
1952
|
+
code = transformCodeWrapper(code);
|
|
1953
|
+
code = transformPageCSS(code, id);
|
|
1954
|
+
code = transformKaTexWrapper(code);
|
|
1886
1955
|
return code;
|
|
1887
1956
|
}
|
|
1888
|
-
return null;
|
|
1889
1957
|
}
|
|
1890
|
-
};
|
|
1958
|
+
});
|
|
1891
1959
|
}
|
|
1892
1960
|
|
|
1893
|
-
// node/
|
|
1961
|
+
// node/vite/compilerFlagsVue.ts
|
|
1894
1962
|
import { objectEntries } from "@antfu/utils";
|
|
1895
|
-
function
|
|
1963
|
+
function createVueCompilerFlagsPlugin(options) {
|
|
1896
1964
|
const define = objectEntries(getDefine(options));
|
|
1897
1965
|
return [
|
|
1898
1966
|
{
|
|
@@ -1912,11 +1980,11 @@ function createFixPlugins(options) {
|
|
|
1912
1980
|
];
|
|
1913
1981
|
}
|
|
1914
1982
|
|
|
1915
|
-
// node/
|
|
1983
|
+
// node/vite/monacoTypes.ts
|
|
1916
1984
|
import fs6 from "node:fs/promises";
|
|
1917
|
-
import { dirname as dirname2, resolve as
|
|
1918
|
-
import { slash as
|
|
1919
|
-
import
|
|
1985
|
+
import { dirname as dirname2, resolve as resolve3 } from "node:path";
|
|
1986
|
+
import { slash as slash2 } from "@antfu/utils";
|
|
1987
|
+
import fg4 from "fast-glob";
|
|
1920
1988
|
import { findDepPkgJsonPath } from "vitefu";
|
|
1921
1989
|
function createMonacoTypesLoader({ userRoot }) {
|
|
1922
1990
|
const resolvedDepsMap = {};
|
|
@@ -1942,14 +2010,14 @@ function createMonacoTypesLoader({ userRoot }) {
|
|
|
1942
2010
|
const pkgJson = JSON.parse(await fs6.readFile(pkgJsonPath, "utf-8"));
|
|
1943
2011
|
const deps = pkgJson.dependencies ?? {};
|
|
1944
2012
|
return [
|
|
1945
|
-
`import "/@slidev-monaco-types/load?root=${
|
|
1946
|
-
...Object.keys(deps).map((dep) => `import "/@slidev-monaco-types/resolve?pkg=${dep}&importer=${
|
|
2013
|
+
`import "/@slidev-monaco-types/load?root=${slash2(root)}&name=${pkgJson.name}"`,
|
|
2014
|
+
...Object.keys(deps).map((dep) => `import "/@slidev-monaco-types/resolve?pkg=${dep}&importer=${slash2(root)}"`)
|
|
1947
2015
|
].join("\n");
|
|
1948
2016
|
}
|
|
1949
2017
|
const matchLoad = id.match(/^\/\@slidev-monaco-types\/load\?root=(.*?)&name=(.*)$/);
|
|
1950
2018
|
if (matchLoad) {
|
|
1951
2019
|
const [_, root, name] = matchLoad;
|
|
1952
|
-
const files = await
|
|
2020
|
+
const files = await fg4(
|
|
1953
2021
|
[
|
|
1954
2022
|
"**/*.ts",
|
|
1955
2023
|
"**/*.mts",
|
|
@@ -1966,14 +2034,16 @@ function createMonacoTypesLoader({ userRoot }) {
|
|
|
1966
2034
|
return "";
|
|
1967
2035
|
return [
|
|
1968
2036
|
'import { addFile } from "@slidev/client/setup/monaco.ts"',
|
|
1969
|
-
...files.map((file) => `addFile(import(${JSON.stringify(`${toAtFS(
|
|
2037
|
+
...files.map((file) => `addFile(import(${JSON.stringify(`${toAtFS(resolve3(root, file))}?monaco-types&raw`)}), ${JSON.stringify(`node_modules/${name}/${file}`)})`)
|
|
1970
2038
|
].join("\n");
|
|
1971
2039
|
}
|
|
1972
2040
|
}
|
|
1973
2041
|
};
|
|
1974
2042
|
}
|
|
1975
2043
|
|
|
1976
|
-
// node/
|
|
2044
|
+
// node/vite/vue.ts
|
|
2045
|
+
import Vue from "@vitejs/plugin-vue";
|
|
2046
|
+
import VueJsx from "@vitejs/plugin-vue-jsx";
|
|
1977
2047
|
var customElements = /* @__PURE__ */ new Set([
|
|
1978
2048
|
// katex
|
|
1979
2049
|
"annotation",
|
|
@@ -2004,22 +2074,11 @@ var customElements = /* @__PURE__ */ new Set([
|
|
|
2004
2074
|
"munderover",
|
|
2005
2075
|
"semantics"
|
|
2006
2076
|
]);
|
|
2007
|
-
async function
|
|
2077
|
+
async function createVuePlugin(options, pluginOptions) {
|
|
2008
2078
|
const {
|
|
2009
2079
|
vue: vueOptions = {},
|
|
2010
|
-
vuejsx: vuejsxOptions = {}
|
|
2011
|
-
components: componentsOptions = {},
|
|
2012
|
-
icons: iconsOptions = {},
|
|
2013
|
-
remoteAssets: remoteAssetsOptions = {},
|
|
2014
|
-
serverRef: serverRefOptions = {}
|
|
2080
|
+
vuejsx: vuejsxOptions = {}
|
|
2015
2081
|
} = pluginOptions;
|
|
2016
|
-
const {
|
|
2017
|
-
mode,
|
|
2018
|
-
themeRoots,
|
|
2019
|
-
addonRoots,
|
|
2020
|
-
roots,
|
|
2021
|
-
data: { config }
|
|
2022
|
-
} = options;
|
|
2023
2082
|
const VuePlugin = Vue({
|
|
2024
2083
|
include: [/\.vue$/, /\.md$/],
|
|
2025
2084
|
exclude: [],
|
|
@@ -2034,22 +2093,41 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
|
2034
2093
|
...vueOptions
|
|
2035
2094
|
});
|
|
2036
2095
|
const VueJsxPlugin = VueJsx(vuejsxOptions);
|
|
2037
|
-
|
|
2096
|
+
return [
|
|
2097
|
+
VueJsxPlugin,
|
|
2098
|
+
VuePlugin
|
|
2099
|
+
];
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
// node/vite/index.ts
|
|
2103
|
+
async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
2104
|
+
const {
|
|
2105
|
+
components: componentsOptions = {},
|
|
2106
|
+
icons: iconsOptions = {},
|
|
2107
|
+
remoteAssets: remoteAssetsOptions = {},
|
|
2108
|
+
serverRef: serverRefOptions = {}
|
|
2109
|
+
} = pluginOptions;
|
|
2110
|
+
const {
|
|
2111
|
+
mode,
|
|
2112
|
+
themeRoots,
|
|
2113
|
+
addonRoots,
|
|
2114
|
+
roots,
|
|
2115
|
+
data: { config }
|
|
2116
|
+
} = options;
|
|
2038
2117
|
const drawingData = await loadDrawings(options);
|
|
2039
|
-
const publicRoots = [...themeRoots, ...addonRoots].map((i) =>
|
|
2118
|
+
const publicRoots = [...themeRoots, ...addonRoots].map((i) => join8(i, "public")).filter(existsSync5);
|
|
2040
2119
|
const plugins = [
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
VuePlugin,
|
|
2120
|
+
createMarkdownPlugin(options, pluginOptions),
|
|
2121
|
+
createVuePlugin(options, pluginOptions),
|
|
2044
2122
|
createSlidesLoader(options, pluginOptions, serverOptions),
|
|
2045
2123
|
Components({
|
|
2046
2124
|
extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
|
|
2047
2125
|
dirs: [
|
|
2048
|
-
|
|
2049
|
-
...roots.map((i) =>
|
|
2126
|
+
join8(options.clientRoot, "builtin"),
|
|
2127
|
+
...roots.map((i) => join8(i, "components")),
|
|
2050
2128
|
"src/components",
|
|
2051
2129
|
"components",
|
|
2052
|
-
|
|
2130
|
+
join8(process.cwd(), "components")
|
|
2053
2131
|
],
|
|
2054
2132
|
include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
|
|
2055
2133
|
exclude: [],
|
|
@@ -2100,9 +2178,8 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
|
2100
2178
|
}
|
|
2101
2179
|
}),
|
|
2102
2180
|
createConfigPlugin(options),
|
|
2103
|
-
createClientSetupPlugin(options),
|
|
2104
2181
|
createMonacoTypesLoader(options),
|
|
2105
|
-
|
|
2182
|
+
createVueCompilerFlagsPlugin(options),
|
|
2106
2183
|
publicRoots.length ? import("vite-plugin-static-copy").then((r) => r.viteStaticCopy({
|
|
2107
2184
|
silent: true,
|
|
2108
2185
|
targets: publicRoots.map((r2) => ({
|
|
@@ -2114,14 +2191,12 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
|
|
|
2114
2191
|
dev: true,
|
|
2115
2192
|
build: true
|
|
2116
2193
|
})) : null,
|
|
2117
|
-
config.css === "none" ? null : import("./unocss-
|
|
2194
|
+
config.css === "none" ? null : import("./unocss-AGKZGMYO.mjs").then((r) => r.createUnocssPlugin(options, pluginOptions))
|
|
2118
2195
|
];
|
|
2119
2196
|
return (await Promise.all(plugins)).flat().filter(notNullish2);
|
|
2120
2197
|
}
|
|
2121
2198
|
|
|
2122
2199
|
export {
|
|
2123
|
-
version,
|
|
2124
|
-
checkEngine,
|
|
2125
2200
|
getIndexHtml,
|
|
2126
2201
|
mergeViteConfigs,
|
|
2127
2202
|
ViteSlidevPlugin
|