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