@slidev/cli 0.49.29 → 0.50.0-beta.2
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-2WDSCT4J.js → build-EZGSYF7Q.js} +6 -7
- package/dist/{chunk-IVWMFGB5.js → chunk-DB2KJXEE.js} +1 -1
- package/dist/{chunk-YP37OZJY.js → chunk-TEOA76MP.js} +967 -928
- package/dist/cli.js +18 -20
- package/dist/{export-FTRUCBWA.js → export-WMRLKOJP.js} +7 -7
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -4
- package/package.json +27 -28
- package/template.md +0 -2
- package/dist/chunk-6DS3IPOB.js +0 -31
- package/dist/markdown-it-prism-P475G4NP.js +0 -107
- package/dist/{chunk-HOVIRHCR.js → chunk-UNQ5DBLZ.js} +6 -6
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
escapeVueInCode,
|
|
3
|
-
getCodeBlocks,
|
|
4
|
-
normalizeRangeStr
|
|
5
|
-
} from "./chunk-6DS3IPOB.js";
|
|
6
1
|
import {
|
|
7
2
|
createResolver,
|
|
8
3
|
getRoots,
|
|
@@ -11,10 +6,79 @@ import {
|
|
|
11
6
|
resolveImportPath,
|
|
12
7
|
resolveImportUrl,
|
|
13
8
|
toAtFS
|
|
14
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-UNQ5DBLZ.js";
|
|
10
|
+
|
|
11
|
+
// package.json
|
|
12
|
+
var version = "0.50.0-beta.2";
|
|
13
|
+
|
|
14
|
+
// node/integrations/themes.ts
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import fs from "fs-extra";
|
|
17
|
+
import { satisfies } from "semver";
|
|
18
|
+
var officialThemes = {
|
|
19
|
+
"none": "",
|
|
20
|
+
"default": "@slidev/theme-default",
|
|
21
|
+
"seriph": "@slidev/theme-seriph",
|
|
22
|
+
"apple-basic": "@slidev/theme-apple-basic",
|
|
23
|
+
"shibainu": "@slidev/theme-shibainu",
|
|
24
|
+
"bricks": "@slidev/theme-bricks"
|
|
25
|
+
};
|
|
26
|
+
var resolveTheme = createResolver("theme", officialThemes);
|
|
27
|
+
async function getThemeMeta(name, root) {
|
|
28
|
+
const path4 = join(root, "package.json");
|
|
29
|
+
if (!fs.existsSync(path4))
|
|
30
|
+
return {};
|
|
31
|
+
const { slidev = {}, engines = {} } = await fs.readJSON(path4);
|
|
32
|
+
if (engines.slidev && !satisfies(version, engines.slidev, { includePrerelease: true }))
|
|
33
|
+
throw new Error(`[slidev] theme "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
|
|
34
|
+
return slidev;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// node/parser.ts
|
|
38
|
+
import * as parser from "@slidev/parser/fs";
|
|
39
|
+
|
|
40
|
+
// node/options.ts
|
|
41
|
+
import path3 from "node:path";
|
|
42
|
+
import { uniq as uniq5 } from "@antfu/utils";
|
|
43
|
+
import Debug from "debug";
|
|
44
|
+
import fg4 from "fast-glob";
|
|
45
|
+
import mm from "micromatch";
|
|
46
|
+
|
|
47
|
+
// node/integrations/addons.ts
|
|
48
|
+
import { resolve } from "node:path";
|
|
49
|
+
import fs2 from "fs-extra";
|
|
50
|
+
import { satisfies as satisfies2 } from "semver";
|
|
51
|
+
async function resolveAddons(addonsInConfig) {
|
|
52
|
+
const { userRoot, userPkgJson } = await getRoots();
|
|
53
|
+
const resolved = [];
|
|
54
|
+
const resolveAddonNameAndRoot = createResolver("addon", {});
|
|
55
|
+
async function resolveAddon(name, parent) {
|
|
56
|
+
const [, pkgRoot] = await resolveAddonNameAndRoot(name, parent);
|
|
57
|
+
if (!pkgRoot)
|
|
58
|
+
return;
|
|
59
|
+
resolved.push(pkgRoot);
|
|
60
|
+
const { slidev = {}, engines = {} } = await fs2.readJSON(resolve(pkgRoot, "package.json"));
|
|
61
|
+
if (engines.slidev && !satisfies2(version, engines.slidev, { includePrerelease: true }))
|
|
62
|
+
throw new Error(`[slidev] addon "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
|
|
63
|
+
if (Array.isArray(slidev.addons))
|
|
64
|
+
await Promise.all(slidev.addons.map((addon) => resolveAddon(addon, pkgRoot)));
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(addonsInConfig))
|
|
67
|
+
await Promise.all(addonsInConfig.map((addon) => resolveAddon(addon, userRoot)));
|
|
68
|
+
if (Array.isArray(userPkgJson.slidev?.addons))
|
|
69
|
+
await Promise.all(userPkgJson.slidev.addons.map((addon) => resolveAddon(addon, userRoot)));
|
|
70
|
+
return resolved;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// node/setups/indexHtml.ts
|
|
74
|
+
import { existsSync as existsSync8, readFileSync as readFileSync2 } from "node:fs";
|
|
75
|
+
import { join as join13 } from "node:path";
|
|
76
|
+
import { slash as slash4 } from "@antfu/utils";
|
|
77
|
+
import { white, yellow as yellow2 } from "kolorist";
|
|
78
|
+
import { escapeHtml } from "markdown-it/lib/common/utils.mjs";
|
|
15
79
|
|
|
16
80
|
// node/commands/shared.ts
|
|
17
|
-
import { existsSync as
|
|
81
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
18
82
|
import { join as join12 } from "node:path";
|
|
19
83
|
import MarkdownIt from "markdown-it";
|
|
20
84
|
import { loadConfigFromFile, mergeConfig as mergeConfig2 } from "vite";
|
|
@@ -45,12 +109,12 @@ function MarkdownItLink(md) {
|
|
|
45
109
|
|
|
46
110
|
// node/utils.ts
|
|
47
111
|
import { fileURLToPath } from "node:url";
|
|
112
|
+
import { createJiti } from "jiti";
|
|
48
113
|
import YAML from "yaml";
|
|
49
|
-
import createJiti from "jiti";
|
|
50
114
|
var jiti;
|
|
51
115
|
function loadModule(absolutePath) {
|
|
52
116
|
jiti ??= createJiti(fileURLToPath(import.meta.url));
|
|
53
|
-
return jiti(absolutePath);
|
|
117
|
+
return jiti.import(absolutePath);
|
|
54
118
|
}
|
|
55
119
|
function stringifyMarkdownTokens(tokens) {
|
|
56
120
|
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(" ");
|
|
@@ -94,13 +158,13 @@ function updateFrontmatterPatch(slide, frontmatter) {
|
|
|
94
158
|
}
|
|
95
159
|
}
|
|
96
160
|
function getBodyJson(req) {
|
|
97
|
-
return new Promise((
|
|
161
|
+
return new Promise((resolve9, reject) => {
|
|
98
162
|
let body = "";
|
|
99
163
|
req.on("data", (chunk) => body += chunk);
|
|
100
164
|
req.on("error", reject);
|
|
101
165
|
req.on("end", () => {
|
|
102
166
|
try {
|
|
103
|
-
|
|
167
|
+
resolve9(JSON.parse(body) || {});
|
|
104
168
|
} catch (e) {
|
|
105
169
|
reject(e);
|
|
106
170
|
}
|
|
@@ -112,11 +176,11 @@ function getBodyJson(req) {
|
|
|
112
176
|
import { objectEntries } from "@antfu/utils";
|
|
113
177
|
|
|
114
178
|
// node/vite/extendConfig.ts
|
|
115
|
-
import { join } from "node:path";
|
|
179
|
+
import { join as join2 } from "node:path";
|
|
116
180
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
117
|
-
import { mergeConfig } from "vite";
|
|
118
181
|
import { slash, uniq } from "@antfu/utils";
|
|
119
182
|
import { createResolve } from "mlly";
|
|
183
|
+
import { mergeConfig } from "vite";
|
|
120
184
|
var INCLUDE_GLOBAL = [
|
|
121
185
|
"@typescript/ata",
|
|
122
186
|
"file-saver",
|
|
@@ -124,7 +188,8 @@ var INCLUDE_GLOBAL = [
|
|
|
124
188
|
"prettier",
|
|
125
189
|
"recordrtc",
|
|
126
190
|
"typescript",
|
|
127
|
-
"yaml"
|
|
191
|
+
"yaml",
|
|
192
|
+
"html-to-image"
|
|
128
193
|
];
|
|
129
194
|
var INCLUDE_LOCAL = INCLUDE_GLOBAL.map((i) => `@slidev/cli > @slidev/client > ${i}`);
|
|
130
195
|
var EXCLUDE_GLOBAL = [
|
|
@@ -226,7 +291,7 @@ function createConfigPlugin(options) {
|
|
|
226
291
|
])
|
|
227
292
|
}
|
|
228
293
|
},
|
|
229
|
-
publicDir:
|
|
294
|
+
publicDir: join2(options.userRoot, "public"),
|
|
230
295
|
build: {
|
|
231
296
|
rollupOptions: {
|
|
232
297
|
output: {
|
|
@@ -259,7 +324,7 @@ function createConfigPlugin(options) {
|
|
|
259
324
|
return id.includes("/@slidev/") || id.includes("/slidev/packages/client/") || id.includes("/@vueuse/");
|
|
260
325
|
}
|
|
261
326
|
if (isInstalledGlobally.value) {
|
|
262
|
-
injection.cacheDir =
|
|
327
|
+
injection.cacheDir = join2(options.cliRoot, "node_modules/.vite");
|
|
263
328
|
injection.root = options.cliRoot;
|
|
264
329
|
}
|
|
265
330
|
return mergeConfig(injection, config);
|
|
@@ -317,15 +382,15 @@ function createVueCompilerFlagsPlugin(options) {
|
|
|
317
382
|
}
|
|
318
383
|
|
|
319
384
|
// node/vite/components.ts
|
|
320
|
-
import { join as
|
|
385
|
+
import { join as join3 } from "node:path";
|
|
321
386
|
import IconsResolver from "unplugin-icons/resolver";
|
|
322
387
|
import Components from "unplugin-vue-components/vite";
|
|
323
388
|
function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
|
|
324
389
|
return Components({
|
|
325
390
|
extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
|
|
326
391
|
dirs: [
|
|
327
|
-
|
|
328
|
-
...roots.map((i) =>
|
|
392
|
+
join3(clientRoot, "builtin"),
|
|
393
|
+
...roots.map((i) => join3(i, "components"))
|
|
329
394
|
],
|
|
330
395
|
include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
|
|
331
396
|
exclude: [],
|
|
@@ -541,14 +606,14 @@ console.warn('/@slidev/titles.md is deprecated, import from #slidev/title-render
|
|
|
541
606
|
|
|
542
607
|
// node/virtual/global-layers.ts
|
|
543
608
|
import { existsSync } from "node:fs";
|
|
544
|
-
import { join as
|
|
609
|
+
import { join as join4 } from "node:path";
|
|
545
610
|
var templateGlobalLayers = {
|
|
546
611
|
id: `/@slidev/global-layers`,
|
|
547
612
|
getContent({ roots }) {
|
|
548
613
|
const imports = [];
|
|
549
614
|
let n = 0;
|
|
550
615
|
function getComponent(names) {
|
|
551
|
-
const components = roots.flatMap((root) => names.map((name) =>
|
|
616
|
+
const components = roots.flatMap((root) => names.map((name) => join4(root, name))).filter((i) => existsSync(i));
|
|
552
617
|
imports.push(components.map((path4, i) => `import __n${n}_${i} from '${toAtFS(path4)}'`).join("\n"));
|
|
553
618
|
const render = components.map((_, i) => `h(__n${n}_${i})`).join(",");
|
|
554
619
|
n++;
|
|
@@ -569,28 +634,6 @@ var templateGlobalLayers = {
|
|
|
569
634
|
}
|
|
570
635
|
};
|
|
571
636
|
|
|
572
|
-
// node/virtual/nav-controls.ts
|
|
573
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
574
|
-
import { join as join4 } from "node:path";
|
|
575
|
-
var templateNavControls = {
|
|
576
|
-
id: "/@slidev/custom-nav-controls",
|
|
577
|
-
getContent({ roots }) {
|
|
578
|
-
const components = roots.flatMap((root) => {
|
|
579
|
-
return [
|
|
580
|
-
join4(root, "custom-nav-controls.vue"),
|
|
581
|
-
join4(root, "CustomNavControls.vue")
|
|
582
|
-
];
|
|
583
|
-
}).filter((i) => existsSync2(i));
|
|
584
|
-
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
585
|
-
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
586
|
-
return `${imports}
|
|
587
|
-
import { h } from 'vue'
|
|
588
|
-
export default {
|
|
589
|
-
render: () => [${render}],
|
|
590
|
-
}`;
|
|
591
|
-
}
|
|
592
|
-
};
|
|
593
|
-
|
|
594
637
|
// node/virtual/layouts.ts
|
|
595
638
|
import { objectMap } from "@antfu/utils";
|
|
596
639
|
var templateLayouts = {
|
|
@@ -614,7 +657,7 @@ ${Object.entries(layouts).map(([k, v]) => `"${k}": ${v}`).join(",\n")}
|
|
|
614
657
|
};
|
|
615
658
|
|
|
616
659
|
// node/virtual/monaco-deps.ts
|
|
617
|
-
import { resolve } from "node:path";
|
|
660
|
+
import { resolve as resolve2 } from "node:path";
|
|
618
661
|
import { uniq as uniq2 } from "@antfu/utils";
|
|
619
662
|
var templateMonacoRunDeps = {
|
|
620
663
|
id: "/@slidev/monaco-run-deps",
|
|
@@ -622,7 +665,7 @@ var templateMonacoRunDeps = {
|
|
|
622
665
|
if (!data.features.monaco)
|
|
623
666
|
return "";
|
|
624
667
|
const deps = uniq2(data.features.monaco.deps.concat(data.config.monacoTypesAdditionalPackages));
|
|
625
|
-
const importerPath =
|
|
668
|
+
const importerPath = resolve2(userRoot, "./snippets/__importer__.ts");
|
|
626
669
|
let result = "";
|
|
627
670
|
for (let i = 0; i < deps.length; i++) {
|
|
628
671
|
const specifier = deps[i];
|
|
@@ -643,9 +686,9 @@ var templateMonacoRunDeps = {
|
|
|
643
686
|
|
|
644
687
|
// node/virtual/monaco-types.ts
|
|
645
688
|
import { builtinModules } from "node:module";
|
|
646
|
-
import { join as join5, resolve as
|
|
647
|
-
import fg from "fast-glob";
|
|
689
|
+
import { join as join5, resolve as resolve3 } from "node:path";
|
|
648
690
|
import { uniq as uniq3 } from "@antfu/utils";
|
|
691
|
+
import fg from "fast-glob";
|
|
649
692
|
var templateMonacoTypes = {
|
|
650
693
|
id: "/@slidev/monaco-types",
|
|
651
694
|
getContent: async ({ userRoot, data, utils }) => {
|
|
@@ -655,7 +698,7 @@ var templateMonacoTypes = {
|
|
|
655
698
|
const files = await fg(["**/*.ts", "**/*.mts", "**/*.cts"], { cwd: typesRoot });
|
|
656
699
|
let result = 'import { addFile } from "@slidev/client/setup/monaco.ts"\n';
|
|
657
700
|
for (const file of files) {
|
|
658
|
-
const url = `${toAtFS(
|
|
701
|
+
const url = `${toAtFS(resolve3(typesRoot, file))}?monaco-types&raw`;
|
|
659
702
|
result += `addFile(() => import(${JSON.stringify(url)}), ${JSON.stringify(file)})
|
|
660
703
|
`;
|
|
661
704
|
}
|
|
@@ -688,15 +731,37 @@ var templateMonacoTypes = {
|
|
|
688
731
|
}
|
|
689
732
|
};
|
|
690
733
|
|
|
734
|
+
// node/virtual/nav-controls.ts
|
|
735
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
736
|
+
import { join as join6 } from "node:path";
|
|
737
|
+
var templateNavControls = {
|
|
738
|
+
id: "/@slidev/custom-nav-controls",
|
|
739
|
+
getContent({ roots }) {
|
|
740
|
+
const components = roots.flatMap((root) => {
|
|
741
|
+
return [
|
|
742
|
+
join6(root, "custom-nav-controls.vue"),
|
|
743
|
+
join6(root, "CustomNavControls.vue")
|
|
744
|
+
];
|
|
745
|
+
}).filter((i) => existsSync2(i));
|
|
746
|
+
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
747
|
+
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
748
|
+
return `${imports}
|
|
749
|
+
import { h } from 'vue'
|
|
750
|
+
export default {
|
|
751
|
+
render: () => [${render}],
|
|
752
|
+
}`;
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
|
|
691
756
|
// node/virtual/setups.ts
|
|
692
757
|
import { existsSync as existsSync3 } from "node:fs";
|
|
693
|
-
import { join as
|
|
758
|
+
import { join as join7 } from "node:path";
|
|
694
759
|
function createSetupTemplate(name) {
|
|
695
760
|
return {
|
|
696
761
|
id: `/@slidev/setups/${name}`,
|
|
697
762
|
getContent({ roots }) {
|
|
698
763
|
const setups = roots.flatMap((i) => {
|
|
699
|
-
const path4 =
|
|
764
|
+
const path4 = join7(i, "setup", name);
|
|
700
765
|
return [".ts", ".mts", ".js", ".mjs"].map((ext) => path4 + ext);
|
|
701
766
|
}).filter((i) => existsSync3(i));
|
|
702
767
|
const imports = [];
|
|
@@ -820,13 +885,13 @@ ${slides.join(",\n")}
|
|
|
820
885
|
};
|
|
821
886
|
|
|
822
887
|
// node/virtual/styles.ts
|
|
823
|
-
import { join as join7 } from "node:path";
|
|
824
888
|
import { existsSync as existsSync4 } from "node:fs";
|
|
889
|
+
import { join as join8 } from "node:path";
|
|
825
890
|
var templateStyle = {
|
|
826
891
|
id: "/@slidev/styles",
|
|
827
892
|
async getContent({ data, clientRoot, roots }) {
|
|
828
893
|
function resolveUrlOfClient(name) {
|
|
829
|
-
return toAtFS(
|
|
894
|
+
return toAtFS(join8(clientRoot, name));
|
|
830
895
|
}
|
|
831
896
|
const imports = [
|
|
832
897
|
`import "${resolveUrlOfClient("styles/vars.css")}"`,
|
|
@@ -837,11 +902,11 @@ var templateStyle = {
|
|
|
837
902
|
];
|
|
838
903
|
for (const root of roots) {
|
|
839
904
|
const styles = [
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
905
|
+
join8(root, "styles", "index.ts"),
|
|
906
|
+
join8(root, "styles", "index.js"),
|
|
907
|
+
join8(root, "styles", "index.css"),
|
|
908
|
+
join8(root, "styles.css"),
|
|
909
|
+
join8(root, "style.css")
|
|
845
910
|
];
|
|
846
911
|
for (const style of styles) {
|
|
847
912
|
if (existsSync4(style)) {
|
|
@@ -917,295 +982,35 @@ var templates = [
|
|
|
917
982
|
templateLegacyTitles
|
|
918
983
|
];
|
|
919
984
|
|
|
920
|
-
// node/
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
// node/integrations/themes.ts
|
|
931
|
-
import { join as join8 } from "node:path";
|
|
932
|
-
import fs from "fs-extra";
|
|
933
|
-
import { satisfies } from "semver";
|
|
934
|
-
|
|
935
|
-
// package.json
|
|
936
|
-
var version = "0.49.29";
|
|
937
|
-
|
|
938
|
-
// node/integrations/themes.ts
|
|
939
|
-
var officialThemes = {
|
|
940
|
-
"none": "",
|
|
941
|
-
"default": "@slidev/theme-default",
|
|
942
|
-
"seriph": "@slidev/theme-seriph",
|
|
943
|
-
"apple-basic": "@slidev/theme-apple-basic",
|
|
944
|
-
"shibainu": "@slidev/theme-shibainu",
|
|
945
|
-
"bricks": "@slidev/theme-bricks"
|
|
946
|
-
};
|
|
947
|
-
var resolveTheme = createResolver("theme", officialThemes);
|
|
948
|
-
async function getThemeMeta(name, root) {
|
|
949
|
-
const path4 = join8(root, "package.json");
|
|
950
|
-
if (!fs.existsSync(path4))
|
|
951
|
-
return {};
|
|
952
|
-
const { slidev = {}, engines = {} } = await fs.readJSON(path4);
|
|
953
|
-
if (engines.slidev && !satisfies(version, engines.slidev, { includePrerelease: true }))
|
|
954
|
-
throw new Error(`[slidev] theme "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
|
|
955
|
-
return slidev;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
// node/integrations/addons.ts
|
|
959
|
-
import { resolve as resolve3 } from "node:path";
|
|
960
|
-
import fs2 from "fs-extra";
|
|
961
|
-
import { satisfies as satisfies2 } from "semver";
|
|
962
|
-
async function resolveAddons(addonsInConfig) {
|
|
963
|
-
const { userRoot, userPkgJson } = await getRoots();
|
|
964
|
-
const resolved = [];
|
|
965
|
-
const resolveAddonNameAndRoot = createResolver("addon", {});
|
|
966
|
-
async function resolveAddon(name, parent) {
|
|
967
|
-
const [, pkgRoot] = await resolveAddonNameAndRoot(name, parent);
|
|
968
|
-
if (!pkgRoot)
|
|
969
|
-
return;
|
|
970
|
-
resolved.push(pkgRoot);
|
|
971
|
-
const { slidev = {}, engines = {} } = await fs2.readJSON(resolve3(pkgRoot, "package.json"));
|
|
972
|
-
if (engines.slidev && !satisfies2(version, engines.slidev, { includePrerelease: true }))
|
|
973
|
-
throw new Error(`[slidev] addon "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
|
|
974
|
-
if (Array.isArray(slidev.addons))
|
|
975
|
-
await Promise.all(slidev.addons.map((addon) => resolveAddon(addon, pkgRoot)));
|
|
976
|
-
}
|
|
977
|
-
if (Array.isArray(addonsInConfig))
|
|
978
|
-
await Promise.all(addonsInConfig.map((addon) => resolveAddon(addon, userRoot)));
|
|
979
|
-
if (Array.isArray(userPkgJson.slidev?.addons))
|
|
980
|
-
await Promise.all(userPkgJson.slidev.addons.map((addon) => resolveAddon(addon, userRoot)));
|
|
981
|
-
return resolved;
|
|
985
|
+
// node/vite/loaders.ts
|
|
986
|
+
function renderNote(text = "") {
|
|
987
|
+
let clickCount = 0;
|
|
988
|
+
const html = sharedMd.render(
|
|
989
|
+
text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
990
|
+
clickCount += Number(count);
|
|
991
|
+
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
992
|
+
})
|
|
993
|
+
);
|
|
994
|
+
return html;
|
|
982
995
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
// node/setups/load.ts
|
|
989
|
-
import { resolve as resolve4 } from "node:path";
|
|
990
|
-
import fs3 from "fs-extra";
|
|
991
|
-
import { deepMergeWithArray } from "@antfu/utils";
|
|
992
|
-
async function loadSetups(roots, filename, args, extraLoader) {
|
|
993
|
-
const returns = [];
|
|
994
|
-
for (const root of roots) {
|
|
995
|
-
const path4 = resolve4(root, "setup", filename);
|
|
996
|
-
if (fs3.existsSync(path4)) {
|
|
997
|
-
const { default: setup } = loadModule(path4);
|
|
998
|
-
const ret = await setup(...args);
|
|
999
|
-
if (ret)
|
|
1000
|
-
returns.push(ret);
|
|
1001
|
-
}
|
|
1002
|
-
if (extraLoader)
|
|
1003
|
-
returns.push(...extraLoader(root));
|
|
1004
|
-
}
|
|
1005
|
-
return returns;
|
|
996
|
+
function withRenderedNote(data) {
|
|
997
|
+
return {
|
|
998
|
+
...data,
|
|
999
|
+
noteHTML: renderNote(data?.note)
|
|
1000
|
+
};
|
|
1006
1001
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
return
|
|
1014
|
-
cachedShiki?.shiki.dispose();
|
|
1015
|
-
const options = await loadSetups(
|
|
1016
|
-
roots,
|
|
1017
|
-
"shiki.ts",
|
|
1018
|
-
[{
|
|
1019
|
-
/** @deprecated */
|
|
1020
|
-
async loadTheme(path4) {
|
|
1021
|
-
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.");
|
|
1022
|
-
return JSON.parse(await fs4.readFile(path4, "utf-8"));
|
|
1023
|
-
}
|
|
1024
|
-
}]
|
|
1025
|
-
);
|
|
1026
|
-
const mergedOptions = Object.assign({}, ...options);
|
|
1027
|
-
if ("theme" in mergedOptions && "themes" in mergedOptions)
|
|
1028
|
-
delete mergedOptions.theme;
|
|
1029
|
-
if (mergedOptions.theme && typeof mergedOptions.theme !== "string" && !mergedOptions.theme.name && !mergedOptions.theme.tokenColors) {
|
|
1030
|
-
mergedOptions.themes = mergedOptions.theme;
|
|
1031
|
-
delete mergedOptions.theme;
|
|
1002
|
+
function createSlidesLoader(options, serverOptions) {
|
|
1003
|
+
const hmrSlidesIndexes = /* @__PURE__ */ new Set();
|
|
1004
|
+
let server;
|
|
1005
|
+
let skipHmr = null;
|
|
1006
|
+
const { data, mode, utils } = options;
|
|
1007
|
+
function getSourceId(index, type) {
|
|
1008
|
+
return `${data.slides[index].source.filepath}__slidev_${index + 1}.${type}`;
|
|
1032
1009
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
if (mergedOptions.themes)
|
|
1040
|
-
mergedOptions.defaultColor = false;
|
|
1041
|
-
const shiki = await createHighlighter({
|
|
1042
|
-
...mergedOptions,
|
|
1043
|
-
langs: mergedOptions.langs ?? Object.keys(bundledLanguages),
|
|
1044
|
-
themes: "themes" in mergedOptions ? Object.values(mergedOptions.themes) : [mergedOptions.theme]
|
|
1045
|
-
});
|
|
1046
|
-
cachedRoots = roots;
|
|
1047
|
-
return cachedShiki = {
|
|
1048
|
-
shiki,
|
|
1049
|
-
shikiOptions: mergedOptions
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
// node/setups/indexHtml.ts
|
|
1054
|
-
import { existsSync as existsSync5, readFileSync } from "node:fs";
|
|
1055
|
-
import { join as join9 } from "node:path";
|
|
1056
|
-
import { slash as slash2 } from "@antfu/utils";
|
|
1057
|
-
import { white, yellow as yellow2 } from "kolorist";
|
|
1058
|
-
import { escapeHtml } from "markdown-it/lib/common/utils.mjs";
|
|
1059
|
-
function toAttrValue(unsafe) {
|
|
1060
|
-
return JSON.stringify(escapeHtml(String(unsafe)));
|
|
1061
|
-
}
|
|
1062
|
-
function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data }) {
|
|
1063
|
-
let main = readFileSync(join9(clientRoot, "index.html"), "utf-8");
|
|
1064
|
-
let head = "";
|
|
1065
|
-
let body = "";
|
|
1066
|
-
const { info, author, keywords } = data.headmatter;
|
|
1067
|
-
head += [
|
|
1068
|
-
`<meta name="slidev:version" content="${version}">`,
|
|
1069
|
-
mode === "dev" && `<meta charset="slidev:entry" content="${slash2(entry)}">`,
|
|
1070
|
-
`<link rel="icon" href="${data.config.favicon}">`,
|
|
1071
|
-
`<title>${getSlideTitle(data)}</title>`,
|
|
1072
|
-
info && `<meta name="description" content=${toAttrValue(info)}>`,
|
|
1073
|
-
author && `<meta name="author" content=${toAttrValue(author)}>`,
|
|
1074
|
-
keywords && `<meta name="keywords" content=${toAttrValue(Array.isArray(keywords) ? keywords.join(", ") : keywords)}>`
|
|
1075
|
-
].filter(Boolean).join("\n");
|
|
1076
|
-
for (const root of roots) {
|
|
1077
|
-
const path4 = join9(root, "index.html");
|
|
1078
|
-
if (!existsSync5(path4))
|
|
1079
|
-
continue;
|
|
1080
|
-
const index = readFileSync(path4, "utf-8");
|
|
1081
|
-
if (root === userRoot && index.includes("<!DOCTYPE")) {
|
|
1082
|
-
console.error(yellow2(`[Slidev] Ignored provided index.html with doctype declaration. (${white(path4)})`));
|
|
1083
|
-
console.error(yellow2("This file may be generated by Slidev, please remove it from your project."));
|
|
1084
|
-
continue;
|
|
1085
|
-
}
|
|
1086
|
-
head += `
|
|
1087
|
-
${(index.match(/<head>([\s\S]*?)<\/head>/i)?.[1] || "").trim()}`;
|
|
1088
|
-
body += `
|
|
1089
|
-
${(index.match(/<body>([\s\S]*?)<\/body>/i)?.[1] || "").trim()}`;
|
|
1090
|
-
}
|
|
1091
|
-
if (data.features.tweet)
|
|
1092
|
-
body += '\n<script async src="https://platform.twitter.com/widgets.js"></script>';
|
|
1093
|
-
if (data.config.fonts.webfonts.length && data.config.fonts.provider !== "none")
|
|
1094
|
-
head += `
|
|
1095
|
-
<link rel="stylesheet" href="${generateGoogleFontsUrl(data.config.fonts)}" type="text/css">`;
|
|
1096
|
-
main = main.replace("__ENTRY__", toAtFS(join9(clientRoot, "main.ts"))).replace("<!-- head -->", head).replace("<!-- body -->", body);
|
|
1097
|
-
return main;
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
// node/options.ts
|
|
1101
|
-
var debug = Debug("slidev:options");
|
|
1102
|
-
async function resolveOptions(entryOptions, mode) {
|
|
1103
|
-
const entry = await resolveEntry(entryOptions.entry);
|
|
1104
|
-
const rootsInfo = await getRoots(entry);
|
|
1105
|
-
const loaded = await parser.load(rootsInfo.userRoot, entry, void 0, mode);
|
|
1106
|
-
let themeRaw = entryOptions.theme || loaded.headmatter.theme;
|
|
1107
|
-
themeRaw = themeRaw === null ? "none" : themeRaw || "default";
|
|
1108
|
-
const [theme, themeRoot] = await resolveTheme(themeRaw, entry);
|
|
1109
|
-
const themeRoots = themeRoot ? [themeRoot] : [];
|
|
1110
|
-
const themeMeta = themeRoot ? await getThemeMeta(theme, themeRoot) : void 0;
|
|
1111
|
-
const config = parser.resolveConfig(loaded.headmatter, themeMeta, entryOptions.entry);
|
|
1112
|
-
const addonRoots = await resolveAddons(config.addons);
|
|
1113
|
-
const roots = uniq5([...themeRoots, ...addonRoots, rootsInfo.userRoot]);
|
|
1114
|
-
debug({
|
|
1115
|
-
...rootsInfo,
|
|
1116
|
-
...entryOptions,
|
|
1117
|
-
config,
|
|
1118
|
-
mode,
|
|
1119
|
-
entry,
|
|
1120
|
-
themeRaw,
|
|
1121
|
-
theme,
|
|
1122
|
-
themeRoots,
|
|
1123
|
-
addonRoots,
|
|
1124
|
-
roots
|
|
1125
|
-
});
|
|
1126
|
-
const data = {
|
|
1127
|
-
...loaded,
|
|
1128
|
-
config,
|
|
1129
|
-
themeMeta
|
|
1130
|
-
};
|
|
1131
|
-
const resolved = {
|
|
1132
|
-
...rootsInfo,
|
|
1133
|
-
...entryOptions,
|
|
1134
|
-
data,
|
|
1135
|
-
mode,
|
|
1136
|
-
entry,
|
|
1137
|
-
themeRaw,
|
|
1138
|
-
theme,
|
|
1139
|
-
themeRoots,
|
|
1140
|
-
addonRoots,
|
|
1141
|
-
roots
|
|
1142
|
-
};
|
|
1143
|
-
return {
|
|
1144
|
-
...resolved,
|
|
1145
|
-
utils: await createDataUtils(resolved)
|
|
1146
|
-
};
|
|
1147
|
-
}
|
|
1148
|
-
async function createDataUtils(resolved) {
|
|
1149
|
-
const monacoTypesIgnorePackagesMatches = (resolved.data.config.monacoTypesIgnorePackages || []).map((i) => mm.matcher(i));
|
|
1150
|
-
let _layouts_cache_time = 0;
|
|
1151
|
-
let _layouts_cache = {};
|
|
1152
|
-
return {
|
|
1153
|
-
...await setupShiki(resolved.roots),
|
|
1154
|
-
indexHtml: setupIndexHtml(resolved),
|
|
1155
|
-
iconsResolvePath: [resolved.clientRoot, ...resolved.roots].reverse(),
|
|
1156
|
-
isMonacoTypesIgnored: (pkg) => monacoTypesIgnorePackagesMatches.some((i) => i(pkg)),
|
|
1157
|
-
getLayouts: () => {
|
|
1158
|
-
const now = Date.now();
|
|
1159
|
-
if (now - _layouts_cache_time < 2e3)
|
|
1160
|
-
return _layouts_cache;
|
|
1161
|
-
const layouts = {};
|
|
1162
|
-
for (const root of [resolved.clientRoot, ...resolved.roots]) {
|
|
1163
|
-
const layoutPaths = fg2.sync("layouts/**/*.{vue,ts}", {
|
|
1164
|
-
cwd: root,
|
|
1165
|
-
absolute: true,
|
|
1166
|
-
suppressErrors: true
|
|
1167
|
-
});
|
|
1168
|
-
for (const layoutPath of layoutPaths) {
|
|
1169
|
-
const layoutName = path.basename(layoutPath).replace(/\.\w+$/, "");
|
|
1170
|
-
layouts[layoutName] = layoutPath;
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
_layouts_cache_time = now;
|
|
1174
|
-
_layouts_cache = layouts;
|
|
1175
|
-
return layouts;
|
|
1176
|
-
}
|
|
1177
|
-
};
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
// node/vite/loaders.ts
|
|
1181
|
-
function renderNote(text = "") {
|
|
1182
|
-
let clickCount = 0;
|
|
1183
|
-
const html = sharedMd.render(
|
|
1184
|
-
text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
1185
|
-
clickCount += Number(count);
|
|
1186
|
-
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
1187
|
-
})
|
|
1188
|
-
);
|
|
1189
|
-
return html;
|
|
1190
|
-
}
|
|
1191
|
-
function withRenderedNote(data) {
|
|
1192
|
-
return {
|
|
1193
|
-
...data,
|
|
1194
|
-
noteHTML: renderNote(data?.note)
|
|
1195
|
-
};
|
|
1196
|
-
}
|
|
1197
|
-
function createSlidesLoader(options, serverOptions) {
|
|
1198
|
-
const hmrSlidesIndexes = /* @__PURE__ */ new Set();
|
|
1199
|
-
let server;
|
|
1200
|
-
let skipHmr = null;
|
|
1201
|
-
const { data, mode, utils } = options;
|
|
1202
|
-
function getSourceId(index, type) {
|
|
1203
|
-
return `${data.slides[index].source.filepath}__slidev_${index + 1}.${type}`;
|
|
1204
|
-
}
|
|
1205
|
-
function updateServerWatcher() {
|
|
1206
|
-
if (!server)
|
|
1207
|
-
return;
|
|
1208
|
-
server.watcher.add(Object.keys(data.watchFiles));
|
|
1010
|
+
function updateServerWatcher() {
|
|
1011
|
+
if (!server)
|
|
1012
|
+
return;
|
|
1013
|
+
server.watcher.add(Object.keys(data.watchFiles));
|
|
1209
1014
|
}
|
|
1210
1015
|
function getFrontmatter(pageNo) {
|
|
1211
1016
|
return {
|
|
@@ -1453,495 +1258,158 @@ function createSlidesLoader(options, serverOptions) {
|
|
|
1453
1258
|
}
|
|
1454
1259
|
|
|
1455
1260
|
// node/vite/markdown.ts
|
|
1456
|
-
import Markdown from "unplugin-vue-markdown/vite";
|
|
1457
1261
|
import MagicString from "magic-string-stack";
|
|
1262
|
+
import Markdown from "unplugin-vue-markdown/vite";
|
|
1458
1263
|
|
|
1459
|
-
//
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1264
|
+
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.1.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
|
|
1265
|
+
var SpecialCharacters;
|
|
1266
|
+
(function(SpecialCharacters2) {
|
|
1267
|
+
SpecialCharacters2[SpecialCharacters2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
|
|
1268
|
+
SpecialCharacters2[SpecialCharacters2["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
|
|
1269
|
+
SpecialCharacters2[SpecialCharacters2["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
|
|
1270
|
+
SpecialCharacters2[SpecialCharacters2["WHITESPACE"] = 32] = "WHITESPACE";
|
|
1271
|
+
SpecialCharacters2[SpecialCharacters2["NEW_LINE"] = 10] = "NEW_LINE";
|
|
1272
|
+
SpecialCharacters2[SpecialCharacters2["EQUALS"] = 61] = "EQUALS";
|
|
1273
|
+
SpecialCharacters2[SpecialCharacters2["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
|
|
1274
|
+
SpecialCharacters2[SpecialCharacters2["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
|
|
1275
|
+
SpecialCharacters2[SpecialCharacters2["NUMBER_NINE"] = 57] = "NUMBER_NINE";
|
|
1276
|
+
SpecialCharacters2[SpecialCharacters2["PERCENTAGE"] = 37] = "PERCENTAGE";
|
|
1277
|
+
SpecialCharacters2[SpecialCharacters2["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
|
|
1278
|
+
})(SpecialCharacters || (SpecialCharacters = {}));
|
|
1279
|
+
|
|
1280
|
+
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.1.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
|
|
1281
|
+
import Token from "markdown-it/lib/token.mjs";
|
|
1282
|
+
var checkboxRegex = /^ *\[([\sx])] /i;
|
|
1283
|
+
function taskLists(md, options = { enabled: false, label: false, lineNumber: false }) {
|
|
1284
|
+
md.core.ruler.after("inline", "task-lists", (state) => processToken(state, options));
|
|
1285
|
+
md.renderer.rules.taskListItemCheckbox = (tokens) => {
|
|
1286
|
+
const token = tokens[0];
|
|
1287
|
+
const checkedAttribute = token.attrGet("checked") ? 'checked="" ' : "";
|
|
1288
|
+
const disabledAttribute = token.attrGet("disabled") ? 'disabled="" ' : "";
|
|
1289
|
+
const line = token.attrGet("line");
|
|
1290
|
+
const idAttribute = `id="${token.attrGet("id")}" `;
|
|
1291
|
+
const dataLineAttribute = line && options.lineNumber ? `data-line="${line}" ` : "";
|
|
1292
|
+
return `<input class="task-list-item-checkbox" type="checkbox" ${checkedAttribute}${disabledAttribute}${dataLineAttribute}${idAttribute}/>`;
|
|
1293
|
+
};
|
|
1294
|
+
md.renderer.rules.taskListItemLabel_close = () => {
|
|
1295
|
+
return "</label>";
|
|
1296
|
+
};
|
|
1297
|
+
md.renderer.rules.taskListItemLabel_open = (tokens) => {
|
|
1298
|
+
const token = tokens[0];
|
|
1299
|
+
const id = token.attrGet("id");
|
|
1300
|
+
return `<label for="${id}">`;
|
|
1467
1301
|
};
|
|
1468
|
-
for (const r of [...returns].reverse()) {
|
|
1469
|
-
if (r.pre)
|
|
1470
|
-
result.pre.push(...r.pre);
|
|
1471
|
-
if (r.preCodeblock)
|
|
1472
|
-
result.preCodeblock.push(...r.preCodeblock);
|
|
1473
|
-
}
|
|
1474
|
-
for (const r of returns) {
|
|
1475
|
-
if (r.postCodeblock)
|
|
1476
|
-
result.postCodeblock.push(...r.postCodeblock);
|
|
1477
|
-
if (r.post)
|
|
1478
|
-
result.post.push(...r.post);
|
|
1479
|
-
}
|
|
1480
|
-
return result;
|
|
1481
1302
|
}
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
reCodeBlock,
|
|
1488
|
-
(full, lang = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
1489
|
-
const ranges = normalizeRangeStr(rangeStr);
|
|
1490
|
-
code = code.trimEnd();
|
|
1491
|
-
options = options.trim() || "{}";
|
|
1492
|
-
return `
|
|
1493
|
-
<CodeBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1494
|
-
|
|
1495
|
-
\`\`\`${lang}${attrs}
|
|
1496
|
-
${code}
|
|
1497
|
-
\`\`\`
|
|
1498
|
-
|
|
1499
|
-
</CodeBlockWrapper>`;
|
|
1303
|
+
function processToken(state, options) {
|
|
1304
|
+
const allTokens = state.tokens;
|
|
1305
|
+
for (let i = 2; i < allTokens.length; i++) {
|
|
1306
|
+
if (!isTodoItem(allTokens, i)) {
|
|
1307
|
+
continue;
|
|
1500
1308
|
}
|
|
1501
|
-
|
|
1309
|
+
todoify(allTokens[i], options);
|
|
1310
|
+
allTokens[i - 2].attrJoin("class", `task-list-item ${options.enabled ? " enabled" : ""}`);
|
|
1311
|
+
const parentToken = findParentToken(allTokens, i - 2);
|
|
1312
|
+
if (parentToken) {
|
|
1313
|
+
const classes = parentToken.attrGet("class") ?? "";
|
|
1314
|
+
if (!classes.match(/(^| )contains-task-list/)) {
|
|
1315
|
+
parentToken.attrJoin("class", "contains-task-list");
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
return false;
|
|
1502
1320
|
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
/(\n<style[^>]*>)([\s\S]+?)(<\/style>)/g,
|
|
1509
|
-
(full, start, css, end, index) => {
|
|
1510
|
-
if (codeBlocks.isInsideCodeblocks(index))
|
|
1511
|
-
return full;
|
|
1512
|
-
if (!start.includes("scoped"))
|
|
1513
|
-
start = start.replace("<style", "<style scoped");
|
|
1514
|
-
return `${start}
|
|
1515
|
-
${css}${end}`;
|
|
1516
|
-
}
|
|
1517
|
-
);
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
// node/syntax/transform/katex-wrapper.ts
|
|
1521
|
-
function transformKaTexWrapper(ctx) {
|
|
1522
|
-
ctx.s.replace(
|
|
1523
|
-
/^\$\$(?:\s*\{([\w*,|-]+)\}\s*?(?:(\{[^}]*\})\s*?)?)?\n(\S[\s\S]*?)^\$\$/gm,
|
|
1524
|
-
(full, rangeStr = "", options = "", code) => {
|
|
1525
|
-
const ranges = !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1526
|
-
code = code.trimEnd();
|
|
1527
|
-
options = options.trim() || "{}";
|
|
1528
|
-
return `<KaTexBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1529
|
-
|
|
1530
|
-
$$
|
|
1531
|
-
${code}
|
|
1532
|
-
$$
|
|
1533
|
-
</KaTexBlockWrapper>
|
|
1534
|
-
`;
|
|
1321
|
+
function findParentToken(tokens, index) {
|
|
1322
|
+
const targetLevel = tokens[index].level - 1;
|
|
1323
|
+
for (let currentTokenIndex = index - 1; currentTokenIndex >= 0; currentTokenIndex--) {
|
|
1324
|
+
if (tokens[currentTokenIndex].level === targetLevel) {
|
|
1325
|
+
return tokens[currentTokenIndex];
|
|
1535
1326
|
}
|
|
1536
|
-
|
|
1327
|
+
}
|
|
1328
|
+
return void 0;
|
|
1537
1329
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
import { codeToKeyedTokens } from "shiki-magic-move/core";
|
|
1541
|
-
import lz from "lz-string";
|
|
1542
|
-
var reMagicMoveBlock = /^````(?:md|markdown) magic-move *(\{[^}]*\})?([^ \n]*)\n([\s\S]+?)^````$/gm;
|
|
1543
|
-
function parseLineNumbersOption(options) {
|
|
1544
|
-
return /lines: *true/.test(options) ? true : /lines: *false/.test(options) ? false : void 0;
|
|
1330
|
+
function isTodoItem(tokens, index) {
|
|
1331
|
+
return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);
|
|
1545
1332
|
}
|
|
1546
|
-
function
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
return codeToKeyedTokens(ctx.options.utils.shiki, i[5].trimEnd(), {
|
|
1558
|
-
...ctx.options.utils.shikiOptions,
|
|
1559
|
-
lang: i[1]
|
|
1560
|
-
}, lineNumbers);
|
|
1561
|
-
});
|
|
1562
|
-
const compressed = lz.compressToBase64(JSON.stringify(steps));
|
|
1563
|
-
return `<ShikiMagicMove v-bind="${options}" steps-lz="${compressed}" :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
1564
|
-
}
|
|
1565
|
-
);
|
|
1333
|
+
function todoify(token, options) {
|
|
1334
|
+
if (token.children == null) {
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
const id = generateIdForToken(token);
|
|
1338
|
+
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
1339
|
+
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
1340
|
+
if (options.label) {
|
|
1341
|
+
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
1342
|
+
token.children.push(createLabelEndToken());
|
|
1343
|
+
}
|
|
1566
1344
|
}
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
(full, options = "", code = "") => {
|
|
1574
|
-
code = code.trim();
|
|
1575
|
-
options = options.trim() || "{}";
|
|
1576
|
-
const encoded = lz2.compressToBase64(code);
|
|
1577
|
-
return `<Mermaid code-lz="${encoded}" v-bind="${options}" />`;
|
|
1578
|
-
}
|
|
1579
|
-
);
|
|
1345
|
+
function generateIdForToken(token) {
|
|
1346
|
+
if (token.map) {
|
|
1347
|
+
return `task-item-${token.map[0]}`;
|
|
1348
|
+
} else {
|
|
1349
|
+
return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
|
|
1350
|
+
}
|
|
1580
1351
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
import lz3 from "lz-string";
|
|
1584
|
-
function transformMonaco(ctx) {
|
|
1585
|
-
const enabled = ctx.options.data.config.monaco === true || ctx.options.data.config.monaco === ctx.options.mode;
|
|
1352
|
+
function createCheckboxToken(token, enabled, id) {
|
|
1353
|
+
const checkbox = new Token("taskListItemCheckbox", "", 0);
|
|
1586
1354
|
if (!enabled) {
|
|
1587
|
-
|
|
1588
|
-
return;
|
|
1355
|
+
checkbox.attrSet("disabled", "true");
|
|
1589
1356
|
}
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
ctx.s.replace(
|
|
1601
|
-
/^```(\w+) *\{monaco\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^```/gm,
|
|
1602
|
-
(full, lang = "ts", options = "{}", code) => {
|
|
1603
|
-
lang = lang.trim();
|
|
1604
|
-
options = options.trim() || "{}";
|
|
1605
|
-
const encoded = lz3.compressToBase64(code);
|
|
1606
|
-
return `<Monaco code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
1607
|
-
}
|
|
1608
|
-
);
|
|
1609
|
-
ctx.s.replace(
|
|
1610
|
-
/^```(\w+) *\{monaco-run\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^```/gm,
|
|
1611
|
-
(full, lang = "ts", options = "{}", code) => {
|
|
1612
|
-
lang = lang.trim();
|
|
1613
|
-
options = options.trim() || "{}";
|
|
1614
|
-
const encoded = lz3.compressToBase64(code);
|
|
1615
|
-
return `<Monaco runnable code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
1616
|
-
}
|
|
1617
|
-
);
|
|
1357
|
+
if (token.map) {
|
|
1358
|
+
checkbox.attrSet("line", token.map[0].toString());
|
|
1359
|
+
}
|
|
1360
|
+
checkbox.attrSet("id", id);
|
|
1361
|
+
const checkboxRegexResult = checkboxRegex.exec(token.content);
|
|
1362
|
+
const isChecked = checkboxRegexResult?.[1].toLowerCase() === "x";
|
|
1363
|
+
if (isChecked) {
|
|
1364
|
+
checkbox.attrSet("checked", "true");
|
|
1365
|
+
}
|
|
1366
|
+
return checkbox;
|
|
1618
1367
|
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
const server = ctx.options.data.config.plantUmlServer;
|
|
1624
|
-
ctx.s.replace(
|
|
1625
|
-
/^```plantuml[^\n{}]*(\{[^}\n]*\})?\n([\s\S]+?)\n```/gm,
|
|
1626
|
-
(full, options = "", content = "") => {
|
|
1627
|
-
const code = encodePlantUml(content.trim());
|
|
1628
|
-
options = options.trim() || "{}";
|
|
1629
|
-
return `<PlantUml :code="'${code}'" :server="'${server}'" v-bind="${options}" />`;
|
|
1630
|
-
}
|
|
1631
|
-
);
|
|
1368
|
+
function createLabelBeginToken(id) {
|
|
1369
|
+
const labelBeginToken = new Token("taskListItemLabel_open", "", 1);
|
|
1370
|
+
labelBeginToken.attrSet("id", id);
|
|
1371
|
+
return labelBeginToken;
|
|
1632
1372
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
const start = offset;
|
|
1648
|
-
offset += line.length;
|
|
1649
|
-
if (codeBlocks.isInsideCodeblocks(offset))
|
|
1650
|
-
return;
|
|
1651
|
-
const match = line.match(/^::\s*([\w.\-:]+)\s*::(\s*)$/);
|
|
1652
|
-
if (match) {
|
|
1653
|
-
ctx.s.overwrite(start, offset - match[2].length, `${prevSlot ? "\n\n</template>\n" : "\n"}<template v-slot:${match[1]}="slotProps">
|
|
1654
|
-
`);
|
|
1655
|
-
prevSlot = true;
|
|
1656
|
-
}
|
|
1657
|
-
});
|
|
1658
|
-
if (prevSlot)
|
|
1659
|
-
ctx.s.append("\n\n</template>");
|
|
1373
|
+
function createLabelEndToken() {
|
|
1374
|
+
return new Token("taskListItemLabel_close", "", -1);
|
|
1375
|
+
}
|
|
1376
|
+
function isInline(token) {
|
|
1377
|
+
return token.type === "inline";
|
|
1378
|
+
}
|
|
1379
|
+
function isParagraph(token) {
|
|
1380
|
+
return token.type === "paragraph_open";
|
|
1381
|
+
}
|
|
1382
|
+
function isListItem(token) {
|
|
1383
|
+
return token.type === "list_item_open";
|
|
1384
|
+
}
|
|
1385
|
+
function startsWithTodoMarkdown(token) {
|
|
1386
|
+
return checkboxRegex.test(token.content);
|
|
1660
1387
|
}
|
|
1661
1388
|
|
|
1662
|
-
// node/syntax/
|
|
1663
|
-
import
|
|
1664
|
-
import
|
|
1665
|
-
import fs6 from "fs-extra";
|
|
1666
|
-
import { slash as slash3 } from "@antfu/utils";
|
|
1389
|
+
// node/syntax/markdown-it/index.ts
|
|
1390
|
+
import MarkdownItMdc from "markdown-it-mdc";
|
|
1391
|
+
import MarkdownItFootnote from "markdown-it-footnote";
|
|
1667
1392
|
|
|
1668
|
-
// node/
|
|
1669
|
-
import
|
|
1670
|
-
import
|
|
1671
|
-
|
|
1672
|
-
function
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
json = JSON.parse(data.toString());
|
|
1682
|
-
} catch {
|
|
1683
|
-
return;
|
|
1684
|
-
}
|
|
1685
|
-
if (json.type === "custom" && json.event === "slidev:monaco-write") {
|
|
1686
|
-
const { file, content } = json.data;
|
|
1687
|
-
if (!monacoWriterWhitelist.has(file)) {
|
|
1688
|
-
console.error(`[Slidev] Unauthorized file write: ${file}`);
|
|
1689
|
-
return;
|
|
1690
|
-
}
|
|
1691
|
-
const filepath = path2.join(userRoot, file);
|
|
1692
|
-
console.log("[Slidev] Writing file:", filepath);
|
|
1693
|
-
await fs5.writeFile(filepath, content, "utf-8");
|
|
1694
|
-
}
|
|
1695
|
-
});
|
|
1696
|
-
});
|
|
1393
|
+
// node/setups/load.ts
|
|
1394
|
+
import { resolve as resolve4 } from "node:path";
|
|
1395
|
+
import { deepMergeWithArray } from "@antfu/utils";
|
|
1396
|
+
import fs3 from "fs-extra";
|
|
1397
|
+
async function loadSetups(roots, filename, args, extraLoader) {
|
|
1398
|
+
const returns = [];
|
|
1399
|
+
for (const root of roots) {
|
|
1400
|
+
const path4 = resolve4(root, "setup", filename);
|
|
1401
|
+
if (fs3.existsSync(path4)) {
|
|
1402
|
+
const { default: setup } = await loadModule(path4);
|
|
1403
|
+
const ret = await setup(...args);
|
|
1404
|
+
if (ret)
|
|
1405
|
+
returns.push(ret);
|
|
1697
1406
|
}
|
|
1698
|
-
|
|
1407
|
+
if (extraLoader)
|
|
1408
|
+
returns.push(...await extraLoader(root));
|
|
1409
|
+
}
|
|
1410
|
+
return returns;
|
|
1699
1411
|
}
|
|
1700
1412
|
|
|
1701
|
-
// node/syntax/transform/snippet.ts
|
|
1702
|
-
function dedent(text) {
|
|
1703
|
-
const lines = text.split("\n");
|
|
1704
|
-
const minIndentLength = lines.reduce((acc, line) => {
|
|
1705
|
-
for (let i = 0; i < line.length; i++) {
|
|
1706
|
-
if (line[i] !== " " && line[i] !== " ")
|
|
1707
|
-
return Math.min(i, acc);
|
|
1708
|
-
}
|
|
1709
|
-
return acc;
|
|
1710
|
-
}, Number.POSITIVE_INFINITY);
|
|
1711
|
-
if (minIndentLength < Number.POSITIVE_INFINITY)
|
|
1712
|
-
return lines.map((x) => x.slice(minIndentLength)).join("\n");
|
|
1713
|
-
return text;
|
|
1714
|
-
}
|
|
1715
|
-
function testLine(line, regexp, regionName, end = false) {
|
|
1716
|
-
const [full, tag, name] = regexp.exec(line.trim()) || [];
|
|
1717
|
-
return full && tag && name === regionName && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/);
|
|
1718
|
-
}
|
|
1719
|
-
function findRegion(lines, regionName) {
|
|
1720
|
-
const regionRegexps = [
|
|
1721
|
-
/^\/\/ ?#?((?:end)?region) ([\w*-]+)$/,
|
|
1722
|
-
// javascript, typescript, java
|
|
1723
|
-
/^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/,
|
|
1724
|
-
// css, less, scss
|
|
1725
|
-
/^#pragma ((?:end)?region) ([\w*-]+)$/,
|
|
1726
|
-
// C, C++
|
|
1727
|
-
/^<!-- #?((?:end)?region) ([\w*-]+) -->$/,
|
|
1728
|
-
// HTML, markdown
|
|
1729
|
-
/^#(End Region) ([\w*-]+)$/,
|
|
1730
|
-
// Visual Basic
|
|
1731
|
-
/^::#(endregion) ([\w*-]+)$/,
|
|
1732
|
-
// Bat
|
|
1733
|
-
/^# ?((?:end)?region) ([\w*-]+)$/
|
|
1734
|
-
// C#, PHP, Powershell, Python, perl & misc
|
|
1735
|
-
];
|
|
1736
|
-
let regexp = null;
|
|
1737
|
-
let start = -1;
|
|
1738
|
-
for (const [lineId, line] of lines.entries()) {
|
|
1739
|
-
if (regexp === null) {
|
|
1740
|
-
for (const reg of regionRegexps) {
|
|
1741
|
-
if (testLine(line, reg, regionName)) {
|
|
1742
|
-
start = lineId + 1;
|
|
1743
|
-
regexp = reg;
|
|
1744
|
-
break;
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
} else if (testLine(line, regexp, regionName, true)) {
|
|
1748
|
-
return { start, end: lineId, regexp };
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
return null;
|
|
1752
|
-
}
|
|
1753
|
-
function transformSnippet({ s, slide, options }) {
|
|
1754
|
-
const watchFiles = options.data.watchFiles;
|
|
1755
|
-
const dir = path3.dirname(slide.source?.filepath ?? options.entry ?? options.userRoot);
|
|
1756
|
-
s.replace(
|
|
1757
|
-
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
1758
|
-
/^<<<\s*(\S.*?)(#[\w-]+)?\s*(?:\s(\S+?))?\s*(\{.*)?$/gm,
|
|
1759
|
-
(full, filepath = "", regionName = "", lang = "", meta = "") => {
|
|
1760
|
-
const src = slash3(
|
|
1761
|
-
/^@\//.test(filepath) ? path3.resolve(options.userRoot, filepath.slice(2)) : path3.resolve(dir, filepath)
|
|
1762
|
-
);
|
|
1763
|
-
watchFiles[src] ??= /* @__PURE__ */ new Set();
|
|
1764
|
-
watchFiles[src].add(slide.index);
|
|
1765
|
-
const isAFile = fs6.statSync(src).isFile();
|
|
1766
|
-
if (!fs6.existsSync(src) || !isAFile) {
|
|
1767
|
-
throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
|
|
1768
|
-
}
|
|
1769
|
-
let content = fs6.readFileSync(src, "utf8");
|
|
1770
|
-
if (regionName) {
|
|
1771
|
-
const lines = content.split(/\r?\n/);
|
|
1772
|
-
const region = findRegion(lines, regionName.slice(1));
|
|
1773
|
-
if (region) {
|
|
1774
|
-
content = dedent(
|
|
1775
|
-
lines.slice(region.start, region.end).filter((line) => !region.regexp.test(line.trim())).join("\n")
|
|
1776
|
-
);
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
meta = meta.trim();
|
|
1780
|
-
lang = lang.trim();
|
|
1781
|
-
lang = lang || path3.extname(filepath).slice(1);
|
|
1782
|
-
if (meta.match(/^\{monaco-write\}/)) {
|
|
1783
|
-
monacoWriterWhitelist.add(filepath);
|
|
1784
|
-
lang = lang.trim();
|
|
1785
|
-
meta = meta.replace(/^\{monaco-write\}/, "").trim() || "{}";
|
|
1786
|
-
const encoded = lz4.compressToBase64(content);
|
|
1787
|
-
return `<Monaco writable=${JSON.stringify(filepath)} code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />`;
|
|
1788
|
-
}
|
|
1789
|
-
return `\`\`\`${lang} ${meta}
|
|
1790
|
-
${content}
|
|
1791
|
-
\`\`\``;
|
|
1792
|
-
}
|
|
1793
|
-
);
|
|
1794
|
-
}
|
|
1795
|
-
|
|
1796
|
-
// node/syntax/transform/index.ts
|
|
1797
|
-
async function getMarkdownTransformers(options) {
|
|
1798
|
-
const extras = await setupTransformers(options.roots);
|
|
1799
|
-
return [
|
|
1800
|
-
...extras.pre,
|
|
1801
|
-
transformSnippet,
|
|
1802
|
-
options.data.config.highlighter === "shiki" && transformMagicMove,
|
|
1803
|
-
...extras.preCodeblock,
|
|
1804
|
-
transformMermaid,
|
|
1805
|
-
transformPlantUml,
|
|
1806
|
-
options.data.features.monaco && transformMonaco,
|
|
1807
|
-
...extras.postCodeblock,
|
|
1808
|
-
transformCodeWrapper,
|
|
1809
|
-
options.data.features.katex && transformKaTexWrapper,
|
|
1810
|
-
transformPageCSS,
|
|
1811
|
-
transformSlotSugar,
|
|
1812
|
-
...extras.post
|
|
1813
|
-
];
|
|
1814
|
-
}
|
|
1815
|
-
|
|
1816
|
-
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.1.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
|
|
1817
|
-
var SpecialCharacters;
|
|
1818
|
-
(function(SpecialCharacters2) {
|
|
1819
|
-
SpecialCharacters2[SpecialCharacters2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
|
|
1820
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
|
|
1821
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
|
|
1822
|
-
SpecialCharacters2[SpecialCharacters2["WHITESPACE"] = 32] = "WHITESPACE";
|
|
1823
|
-
SpecialCharacters2[SpecialCharacters2["NEW_LINE"] = 10] = "NEW_LINE";
|
|
1824
|
-
SpecialCharacters2[SpecialCharacters2["EQUALS"] = 61] = "EQUALS";
|
|
1825
|
-
SpecialCharacters2[SpecialCharacters2["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
|
|
1826
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
|
|
1827
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_NINE"] = 57] = "NUMBER_NINE";
|
|
1828
|
-
SpecialCharacters2[SpecialCharacters2["PERCENTAGE"] = 37] = "PERCENTAGE";
|
|
1829
|
-
SpecialCharacters2[SpecialCharacters2["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
|
|
1830
|
-
})(SpecialCharacters || (SpecialCharacters = {}));
|
|
1831
|
-
|
|
1832
|
-
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=tuyuxytl56b2vxulpkzt2wf4o4_markdown-it@14.1.0/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
|
|
1833
|
-
import Token from "markdown-it/lib/token.mjs";
|
|
1834
|
-
var checkboxRegex = /^ *\[([\sx])] /i;
|
|
1835
|
-
function taskLists(md, options = { enabled: false, label: false, lineNumber: false }) {
|
|
1836
|
-
md.core.ruler.after("inline", "task-lists", (state) => processToken(state, options));
|
|
1837
|
-
md.renderer.rules.taskListItemCheckbox = (tokens) => {
|
|
1838
|
-
const token = tokens[0];
|
|
1839
|
-
const checkedAttribute = token.attrGet("checked") ? 'checked="" ' : "";
|
|
1840
|
-
const disabledAttribute = token.attrGet("disabled") ? 'disabled="" ' : "";
|
|
1841
|
-
const line = token.attrGet("line");
|
|
1842
|
-
const idAttribute = `id="${token.attrGet("id")}" `;
|
|
1843
|
-
const dataLineAttribute = line && options.lineNumber ? `data-line="${line}" ` : "";
|
|
1844
|
-
return `<input class="task-list-item-checkbox" type="checkbox" ${checkedAttribute}${disabledAttribute}${dataLineAttribute}${idAttribute}/>`;
|
|
1845
|
-
};
|
|
1846
|
-
md.renderer.rules.taskListItemLabel_close = () => {
|
|
1847
|
-
return "</label>";
|
|
1848
|
-
};
|
|
1849
|
-
md.renderer.rules.taskListItemLabel_open = (tokens) => {
|
|
1850
|
-
const token = tokens[0];
|
|
1851
|
-
const id = token.attrGet("id");
|
|
1852
|
-
return `<label for="${id}">`;
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
function processToken(state, options) {
|
|
1856
|
-
const allTokens = state.tokens;
|
|
1857
|
-
for (let i = 2; i < allTokens.length; i++) {
|
|
1858
|
-
if (!isTodoItem(allTokens, i)) {
|
|
1859
|
-
continue;
|
|
1860
|
-
}
|
|
1861
|
-
todoify(allTokens[i], options);
|
|
1862
|
-
allTokens[i - 2].attrJoin("class", `task-list-item ${options.enabled ? " enabled" : ""}`);
|
|
1863
|
-
const parentToken = findParentToken(allTokens, i - 2);
|
|
1864
|
-
if (parentToken) {
|
|
1865
|
-
const classes = parentToken.attrGet("class") ?? "";
|
|
1866
|
-
if (!classes.match(/(^| )contains-task-list/)) {
|
|
1867
|
-
parentToken.attrJoin("class", "contains-task-list");
|
|
1868
|
-
}
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
return false;
|
|
1872
|
-
}
|
|
1873
|
-
function findParentToken(tokens, index) {
|
|
1874
|
-
const targetLevel = tokens[index].level - 1;
|
|
1875
|
-
for (let currentTokenIndex = index - 1; currentTokenIndex >= 0; currentTokenIndex--) {
|
|
1876
|
-
if (tokens[currentTokenIndex].level === targetLevel) {
|
|
1877
|
-
return tokens[currentTokenIndex];
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
return void 0;
|
|
1881
|
-
}
|
|
1882
|
-
function isTodoItem(tokens, index) {
|
|
1883
|
-
return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);
|
|
1884
|
-
}
|
|
1885
|
-
function todoify(token, options) {
|
|
1886
|
-
if (token.children == null) {
|
|
1887
|
-
return;
|
|
1888
|
-
}
|
|
1889
|
-
const id = generateIdForToken(token);
|
|
1890
|
-
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
1891
|
-
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
1892
|
-
if (options.label) {
|
|
1893
|
-
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
1894
|
-
token.children.push(createLabelEndToken());
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
function generateIdForToken(token) {
|
|
1898
|
-
if (token.map) {
|
|
1899
|
-
return `task-item-${token.map[0]}`;
|
|
1900
|
-
} else {
|
|
1901
|
-
return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
function createCheckboxToken(token, enabled, id) {
|
|
1905
|
-
const checkbox = new Token("taskListItemCheckbox", "", 0);
|
|
1906
|
-
if (!enabled) {
|
|
1907
|
-
checkbox.attrSet("disabled", "true");
|
|
1908
|
-
}
|
|
1909
|
-
if (token.map) {
|
|
1910
|
-
checkbox.attrSet("line", token.map[0].toString());
|
|
1911
|
-
}
|
|
1912
|
-
checkbox.attrSet("id", id);
|
|
1913
|
-
const checkboxRegexResult = checkboxRegex.exec(token.content);
|
|
1914
|
-
const isChecked = checkboxRegexResult?.[1].toLowerCase() === "x";
|
|
1915
|
-
if (isChecked) {
|
|
1916
|
-
checkbox.attrSet("checked", "true");
|
|
1917
|
-
}
|
|
1918
|
-
return checkbox;
|
|
1919
|
-
}
|
|
1920
|
-
function createLabelBeginToken(id) {
|
|
1921
|
-
const labelBeginToken = new Token("taskListItemLabel_open", "", 1);
|
|
1922
|
-
labelBeginToken.attrSet("id", id);
|
|
1923
|
-
return labelBeginToken;
|
|
1924
|
-
}
|
|
1925
|
-
function createLabelEndToken() {
|
|
1926
|
-
return new Token("taskListItemLabel_close", "", -1);
|
|
1927
|
-
}
|
|
1928
|
-
function isInline(token) {
|
|
1929
|
-
return token.type === "inline";
|
|
1930
|
-
}
|
|
1931
|
-
function isParagraph(token) {
|
|
1932
|
-
return token.type === "paragraph_open";
|
|
1933
|
-
}
|
|
1934
|
-
function isListItem(token) {
|
|
1935
|
-
return token.type === "list_item_open";
|
|
1936
|
-
}
|
|
1937
|
-
function startsWithTodoMarkdown(token) {
|
|
1938
|
-
return checkboxRegex.test(token.content);
|
|
1939
|
-
}
|
|
1940
|
-
|
|
1941
|
-
// node/syntax/markdown-it/index.ts
|
|
1942
|
-
import MarkdownItMdc from "markdown-it-mdc";
|
|
1943
|
-
import MarkdownItFootnote from "markdown-it-footnote";
|
|
1944
|
-
|
|
1945
1413
|
// node/setups/katex.ts
|
|
1946
1414
|
async function setupKatex(roots) {
|
|
1947
1415
|
const options = await loadSetups(roots, "katex.ts", []);
|
|
@@ -1951,6 +1419,15 @@ async function setupKatex(roots) {
|
|
|
1951
1419
|
);
|
|
1952
1420
|
}
|
|
1953
1421
|
|
|
1422
|
+
// node/syntax/markdown-it/markdown-it-escape-code.ts
|
|
1423
|
+
function MarkdownItEscapeInlineCode(md) {
|
|
1424
|
+
const codeInline = md.renderer.rules.code_inline;
|
|
1425
|
+
md.renderer.rules.code_inline = (tokens, idx, options, env, self) => {
|
|
1426
|
+
const result = codeInline(tokens, idx, options, env, self);
|
|
1427
|
+
return result.replace(/^<code/, "<code v-pre");
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1954
1431
|
// node/syntax/markdown-it/markdown-it-katex.ts
|
|
1955
1432
|
import katex from "katex";
|
|
1956
1433
|
function isValidDelim(state, pos) {
|
|
@@ -2096,19 +1573,77 @@ function MarkdownItKatex(md, options) {
|
|
|
2096
1573
|
md.renderer.rules.math_block = blockRenderer;
|
|
2097
1574
|
}
|
|
2098
1575
|
|
|
2099
|
-
// node/syntax/markdown-it/markdown-it-
|
|
2100
|
-
import {
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
1576
|
+
// node/syntax/markdown-it/markdown-it-shiki.ts
|
|
1577
|
+
import { isTruthy } from "@antfu/utils";
|
|
1578
|
+
import { fromHighlighter } from "@shikijs/markdown-it/core";
|
|
1579
|
+
|
|
1580
|
+
// node/syntax/transform/utils.ts
|
|
1581
|
+
function normalizeRangeStr(rangeStr = "") {
|
|
1582
|
+
return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1583
|
+
}
|
|
1584
|
+
function getCodeBlocks(md) {
|
|
1585
|
+
const codeblocks = Array.from(md.matchAll(/^```[\s\S]*?^```/gm)).map((m) => {
|
|
1586
|
+
const start = m.index;
|
|
1587
|
+
const end = m.index + m[0].length;
|
|
1588
|
+
const startLine = md.slice(0, start).match(/\n/g)?.length || 0;
|
|
1589
|
+
const endLine = md.slice(0, end).match(/\n/g)?.length || 0;
|
|
1590
|
+
return [start, end, startLine, endLine];
|
|
1591
|
+
});
|
|
1592
|
+
return {
|
|
1593
|
+
codeblocks,
|
|
1594
|
+
isInsideCodeblocks(idx) {
|
|
1595
|
+
return codeblocks.some(([s, e]) => s <= idx && idx <= e);
|
|
1596
|
+
},
|
|
1597
|
+
isLineInsideCodeblocks(line) {
|
|
1598
|
+
return codeblocks.some(([, , s, e]) => s <= line && line <= e);
|
|
1599
|
+
}
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
function escapeVueInCode(md) {
|
|
1603
|
+
return md.replace(/\{\{/g, "{{");
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
// node/syntax/markdown-it/markdown-it-shiki.ts
|
|
1607
|
+
async function MarkdownItShiki({ data: { config }, mode, utils }) {
|
|
1608
|
+
const transformers = [
|
|
1609
|
+
...utils.shikiOptions.transformers || [],
|
|
1610
|
+
(config.twoslash === true || config.twoslash === mode) && (await import("@shikijs/vitepress-twoslash")).transformerTwoslash({
|
|
1611
|
+
explicitTrigger: true,
|
|
1612
|
+
twoslashOptions: {
|
|
1613
|
+
handbookOptions: {
|
|
1614
|
+
noErrorValidation: true
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
}),
|
|
1618
|
+
{
|
|
1619
|
+
pre(pre) {
|
|
1620
|
+
this.addClassToHast(pre, "slidev-code");
|
|
1621
|
+
delete pre.properties.tabindex;
|
|
1622
|
+
},
|
|
1623
|
+
postprocess(code) {
|
|
1624
|
+
return escapeVueInCode(code);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
].filter(isTruthy);
|
|
1628
|
+
return fromHighlighter(utils.shiki, {
|
|
1629
|
+
...utils.shikiOptions,
|
|
1630
|
+
transformers
|
|
1631
|
+
});
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
// node/syntax/markdown-it/markdown-it-v-drag.ts
|
|
1635
|
+
import { SourceMapConsumer } from "source-map-js";
|
|
1636
|
+
var dragComponentRegex = /<(v-?drag-?\w*)([\s>])/i;
|
|
1637
|
+
var dragDirectiveRegex = /(?<![</\w])v-drag(=".*?")?/i;
|
|
1638
|
+
function MarkdownItVDrag(md, markdownTransformMap) {
|
|
1639
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
1640
|
+
const sourceMapConsumers = /* @__PURE__ */ new WeakMap();
|
|
1641
|
+
function getSourceMapConsumer(id) {
|
|
1642
|
+
const s = markdownTransformMap.get(id);
|
|
1643
|
+
if (!s)
|
|
1644
|
+
return void 0;
|
|
1645
|
+
let smc = sourceMapConsumers.get(s);
|
|
1646
|
+
if (smc)
|
|
2112
1647
|
return smc;
|
|
2113
1648
|
const sourceMap = s.generateMap();
|
|
2114
1649
|
smc = new SourceMapConsumer({
|
|
@@ -2153,64 +1688,378 @@ function MarkdownItVDrag(md, markdownTransformMap) {
|
|
|
2153
1688
|
};
|
|
2154
1689
|
}
|
|
2155
1690
|
|
|
2156
|
-
// node/syntax/markdown-it/
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
1691
|
+
// node/syntax/markdown-it/index.ts
|
|
1692
|
+
async function useMarkdownItPlugins(md, options, markdownTransformMap) {
|
|
1693
|
+
const { roots, data: { features, config } } = options;
|
|
1694
|
+
if (config.highlighter === "shiki") {
|
|
1695
|
+
md.use(await MarkdownItShiki(options));
|
|
1696
|
+
}
|
|
1697
|
+
md.use(MarkdownItLink);
|
|
1698
|
+
md.use(MarkdownItEscapeInlineCode);
|
|
1699
|
+
md.use(MarkdownItFootnote);
|
|
1700
|
+
md.use(taskLists, { enabled: true, lineNumber: true, label: true });
|
|
1701
|
+
if (features.katex)
|
|
1702
|
+
md.use(MarkdownItKatex, await setupKatex(roots));
|
|
1703
|
+
md.use(MarkdownItVDrag, markdownTransformMap);
|
|
1704
|
+
if (config.mdc)
|
|
1705
|
+
md.use(MarkdownItMdc);
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
// node/setups/transformers.ts
|
|
1709
|
+
async function setupTransformers(roots) {
|
|
1710
|
+
const returns = await loadSetups(roots, "transformers.ts", []);
|
|
1711
|
+
const result = {
|
|
1712
|
+
pre: [],
|
|
1713
|
+
preCodeblock: [],
|
|
1714
|
+
postCodeblock: [],
|
|
1715
|
+
post: []
|
|
1716
|
+
};
|
|
1717
|
+
for (const r of [...returns].reverse()) {
|
|
1718
|
+
if (r.pre)
|
|
1719
|
+
result.pre.push(...r.pre);
|
|
1720
|
+
if (r.preCodeblock)
|
|
1721
|
+
result.preCodeblock.push(...r.preCodeblock);
|
|
1722
|
+
}
|
|
1723
|
+
for (const r of returns) {
|
|
1724
|
+
if (r.postCodeblock)
|
|
1725
|
+
result.postCodeblock.push(...r.postCodeblock);
|
|
1726
|
+
if (r.post)
|
|
1727
|
+
result.post.push(...r.post);
|
|
1728
|
+
}
|
|
1729
|
+
return result;
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
// node/syntax/transform/code-wrapper.ts
|
|
1733
|
+
var reCodeBlock = /^```([\w'-]+)?\s*(?:\{([\w*,|-]+)\}\s*?(\{[^}]*\})?([^\r\n]*))?\r?\n(\S[\s\S]*?)^```$/gm;
|
|
1734
|
+
function transformCodeWrapper(ctx) {
|
|
1735
|
+
ctx.s.replace(
|
|
1736
|
+
reCodeBlock,
|
|
1737
|
+
(full, lang = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
1738
|
+
const ranges = normalizeRangeStr(rangeStr);
|
|
1739
|
+
code = code.trimEnd();
|
|
1740
|
+
options = options.trim() || "{}";
|
|
1741
|
+
return `
|
|
1742
|
+
<CodeBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1743
|
+
|
|
1744
|
+
\`\`\`${lang}${attrs}
|
|
1745
|
+
${code}
|
|
1746
|
+
\`\`\`
|
|
1747
|
+
|
|
1748
|
+
</CodeBlockWrapper>`;
|
|
1749
|
+
}
|
|
1750
|
+
);
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
// node/syntax/transform/in-page-css.ts
|
|
1754
|
+
function transformPageCSS(ctx) {
|
|
1755
|
+
const codeBlocks = getCodeBlocks(ctx.s.original);
|
|
1756
|
+
ctx.s.replace(
|
|
1757
|
+
/(\n<style[^>]*>)([\s\S]+?)(<\/style>)/g,
|
|
1758
|
+
(full, start, css, end, index) => {
|
|
1759
|
+
if (codeBlocks.isInsideCodeblocks(index))
|
|
1760
|
+
return full;
|
|
1761
|
+
if (!start.includes("scoped"))
|
|
1762
|
+
start = start.replace("<style", "<style scoped");
|
|
1763
|
+
return `${start}
|
|
1764
|
+
${css}${end}`;
|
|
1765
|
+
}
|
|
1766
|
+
);
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
// node/syntax/transform/katex-wrapper.ts
|
|
1770
|
+
function transformKaTexWrapper(ctx) {
|
|
1771
|
+
ctx.s.replace(
|
|
1772
|
+
/^\$\$(?:\s*\{([\w*,|-]+)\}\s*?(?:(\{[^}]*\})\s*?)?)?\n(\S[\s\S]*?)^\$\$/gm,
|
|
1773
|
+
(full, rangeStr = "", options = "", code) => {
|
|
1774
|
+
const ranges = !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1775
|
+
code = code.trimEnd();
|
|
1776
|
+
options = options.trim() || "{}";
|
|
1777
|
+
return `<KaTexBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1778
|
+
|
|
1779
|
+
$$
|
|
1780
|
+
${code}
|
|
1781
|
+
$$
|
|
1782
|
+
</KaTexBlockWrapper>
|
|
1783
|
+
`;
|
|
1784
|
+
}
|
|
1785
|
+
);
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
// node/syntax/transform/magic-move.ts
|
|
1789
|
+
import lz from "lz-string";
|
|
1790
|
+
import { codeToKeyedTokens } from "shiki-magic-move/core";
|
|
1791
|
+
var reMagicMoveBlock = /^````(?:md|markdown) magic-move *(\{[^}]*\})?([^ \n]*)\n([\s\S]+?)^````$/gm;
|
|
1792
|
+
function parseLineNumbersOption(options) {
|
|
1793
|
+
return /lines: *true/.test(options) ? true : /lines: *false/.test(options) ? false : void 0;
|
|
1794
|
+
}
|
|
1795
|
+
function transformMagicMove(ctx) {
|
|
1796
|
+
ctx.s.replace(
|
|
1797
|
+
reMagicMoveBlock,
|
|
1798
|
+
(full, options = "{}", _attrs = "", body) => {
|
|
1799
|
+
const matches = Array.from(body.matchAll(reCodeBlock));
|
|
1800
|
+
if (!matches.length)
|
|
1801
|
+
throw new Error("Magic Move block must contain at least one code block");
|
|
1802
|
+
const defaultLineNumbers = parseLineNumbersOption(options) ?? ctx.options.data.config.lineNumbers;
|
|
1803
|
+
const ranges = matches.map((i) => normalizeRangeStr(i[2]));
|
|
1804
|
+
const steps = matches.map((i) => {
|
|
1805
|
+
const lineNumbers = parseLineNumbersOption(i[3]) ?? defaultLineNumbers;
|
|
1806
|
+
return codeToKeyedTokens(ctx.options.utils.shiki, i[5].trimEnd(), {
|
|
1807
|
+
...ctx.options.utils.shikiOptions,
|
|
1808
|
+
lang: i[1]
|
|
1809
|
+
}, lineNumbers);
|
|
1810
|
+
});
|
|
1811
|
+
const compressed = lz.compressToBase64(JSON.stringify(steps));
|
|
1812
|
+
return `<ShikiMagicMove v-bind="${options}" steps-lz="${compressed}" :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
1813
|
+
}
|
|
1814
|
+
);
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
// node/syntax/transform/mermaid.ts
|
|
1818
|
+
import lz2 from "lz-string";
|
|
1819
|
+
function transformMermaid(ctx) {
|
|
1820
|
+
ctx.s.replace(
|
|
1821
|
+
/^```mermaid *(\{[^\n]*\})?\n([\s\S]+?)\n```/gm,
|
|
1822
|
+
(full, options = "", code = "") => {
|
|
1823
|
+
code = code.trim();
|
|
1824
|
+
options = options.trim() || "{}";
|
|
1825
|
+
const encoded = lz2.compressToBase64(code);
|
|
1826
|
+
return `<Mermaid code-lz="${encoded}" v-bind="${options}" />`;
|
|
1827
|
+
}
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// node/syntax/transform/monaco.ts
|
|
1832
|
+
import lz3 from "lz-string";
|
|
1833
|
+
function transformMonaco(ctx) {
|
|
1834
|
+
const enabled = ctx.options.data.config.monaco === true || ctx.options.data.config.monaco === ctx.options.mode;
|
|
1835
|
+
if (!enabled) {
|
|
1836
|
+
ctx.s.replace(/\{monaco([\w:,-]*)\}/g, "");
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
ctx.s.replace(
|
|
1840
|
+
/^```(\w+) *\{monaco-diff\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^~~~ *\n([\s\S]+?)^```/gm,
|
|
1841
|
+
(full, lang = "ts", options = "{}", code, diff) => {
|
|
1842
|
+
lang = lang.trim();
|
|
1843
|
+
options = options.trim() || "{}";
|
|
1844
|
+
const encoded = lz3.compressToBase64(code);
|
|
1845
|
+
const encodedDiff = lz3.compressToBase64(diff);
|
|
1846
|
+
return `<Monaco code-lz="${encoded}" diff-lz="${encodedDiff}" lang="${lang}" v-bind="${options}" />`;
|
|
1847
|
+
}
|
|
1848
|
+
);
|
|
1849
|
+
ctx.s.replace(
|
|
1850
|
+
/^```(\w+) *\{monaco\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^```/gm,
|
|
1851
|
+
(full, lang = "ts", options = "{}", code) => {
|
|
1852
|
+
lang = lang.trim();
|
|
1853
|
+
options = options.trim() || "{}";
|
|
1854
|
+
const encoded = lz3.compressToBase64(code);
|
|
1855
|
+
return `<Monaco code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
1856
|
+
}
|
|
1857
|
+
);
|
|
1858
|
+
ctx.s.replace(
|
|
1859
|
+
/^```(\w+) *\{monaco-run\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^```/gm,
|
|
1860
|
+
(full, lang = "ts", options = "{}", code) => {
|
|
1861
|
+
lang = lang.trim();
|
|
1862
|
+
options = options.trim() || "{}";
|
|
1863
|
+
const encoded = lz3.compressToBase64(code);
|
|
1864
|
+
return `<Monaco runnable code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
1865
|
+
}
|
|
1866
|
+
);
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
// node/syntax/transform/plant-uml.ts
|
|
1870
|
+
import { encode as encodePlantUml } from "plantuml-encoder";
|
|
1871
|
+
function transformPlantUml(ctx) {
|
|
1872
|
+
const server = ctx.options.data.config.plantUmlServer;
|
|
1873
|
+
ctx.s.replace(
|
|
1874
|
+
/^```plantuml[^\n{}]*(\{[^}\n]*\})?\n([\s\S]+?)\n```/gm,
|
|
1875
|
+
(full, options = "", content = "") => {
|
|
1876
|
+
const code = encodePlantUml(content.trim());
|
|
1877
|
+
options = options.trim() || "{}";
|
|
1878
|
+
return `<PlantUml :code="'${code}'" :server="'${server}'" v-bind="${options}" />`;
|
|
1879
|
+
}
|
|
1880
|
+
);
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
// node/syntax/transform/slot-sugar.ts
|
|
1884
|
+
function transformSlotSugar(ctx) {
|
|
1885
|
+
const linesWithNewline = ctx.s.original.split(/(\r?\n)/g);
|
|
1886
|
+
const codeBlocks = getCodeBlocks(ctx.s.original);
|
|
1887
|
+
const lines = [];
|
|
1888
|
+
for (let i = 0; i < linesWithNewline.length; i += 2) {
|
|
1889
|
+
const line = linesWithNewline[i];
|
|
1890
|
+
const newline = linesWithNewline[i + 1] || "";
|
|
1891
|
+
lines.push(line + newline);
|
|
1892
|
+
}
|
|
1893
|
+
let prevSlot = false;
|
|
1894
|
+
let offset = 0;
|
|
1895
|
+
lines.forEach((line) => {
|
|
1896
|
+
const start = offset;
|
|
1897
|
+
offset += line.length;
|
|
1898
|
+
if (codeBlocks.isInsideCodeblocks(offset))
|
|
1899
|
+
return;
|
|
1900
|
+
const match = line.match(/^::\s*([\w.\-:]+)\s*::(\s*)$/);
|
|
1901
|
+
if (match) {
|
|
1902
|
+
ctx.s.overwrite(start, offset - match[2].length, `${prevSlot ? "\n\n</template>\n" : "\n"}<template v-slot:${match[1]}="slotProps">
|
|
1903
|
+
`);
|
|
1904
|
+
prevSlot = true;
|
|
2178
1905
|
}
|
|
2179
|
-
].filter(isTruthy);
|
|
2180
|
-
return fromHighlighter(utils.shiki, {
|
|
2181
|
-
...utils.shikiOptions,
|
|
2182
|
-
transformers
|
|
2183
1906
|
});
|
|
1907
|
+
if (prevSlot)
|
|
1908
|
+
ctx.s.append("\n\n</template>");
|
|
2184
1909
|
}
|
|
2185
1910
|
|
|
2186
|
-
// node/syntax/
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
1911
|
+
// node/syntax/transform/snippet.ts
|
|
1912
|
+
import path2 from "node:path";
|
|
1913
|
+
import { slash as slash2 } from "@antfu/utils";
|
|
1914
|
+
import fs5 from "fs-extra";
|
|
1915
|
+
import lz4 from "lz-string";
|
|
1916
|
+
|
|
1917
|
+
// node/vite/monacoWrite.ts
|
|
1918
|
+
import fs4 from "node:fs/promises";
|
|
1919
|
+
import path from "node:path";
|
|
1920
|
+
var monacoWriterWhitelist = /* @__PURE__ */ new Set();
|
|
1921
|
+
function createMonacoWriterPlugin({ userRoot }) {
|
|
1922
|
+
return {
|
|
1923
|
+
name: "slidev:monaco-write",
|
|
1924
|
+
apply: "serve",
|
|
1925
|
+
configureServer(server) {
|
|
1926
|
+
server.ws.on("connection", (socket) => {
|
|
1927
|
+
socket.on("message", async (data) => {
|
|
1928
|
+
let json;
|
|
1929
|
+
try {
|
|
1930
|
+
json = JSON.parse(data.toString());
|
|
1931
|
+
} catch {
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
if (json.type === "custom" && json.event === "slidev:monaco-write") {
|
|
1935
|
+
const { file, content } = json.data;
|
|
1936
|
+
if (!monacoWriterWhitelist.has(file)) {
|
|
1937
|
+
console.error(`[Slidev] Unauthorized file write: ${file}`);
|
|
1938
|
+
return;
|
|
1939
|
+
}
|
|
1940
|
+
const filepath = path.join(userRoot, file);
|
|
1941
|
+
console.log("[Slidev] Writing file:", filepath);
|
|
1942
|
+
await fs4.writeFile(filepath, content, "utf-8");
|
|
1943
|
+
}
|
|
1944
|
+
});
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
2192
1947
|
};
|
|
2193
1948
|
}
|
|
2194
1949
|
|
|
2195
|
-
// node/syntax/
|
|
2196
|
-
|
|
2197
|
-
const
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
}
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
1950
|
+
// node/syntax/transform/snippet.ts
|
|
1951
|
+
function dedent(text) {
|
|
1952
|
+
const lines = text.split("\n");
|
|
1953
|
+
const minIndentLength = lines.reduce((acc, line) => {
|
|
1954
|
+
for (let i = 0; i < line.length; i++) {
|
|
1955
|
+
if (line[i] !== " " && line[i] !== " ")
|
|
1956
|
+
return Math.min(i, acc);
|
|
1957
|
+
}
|
|
1958
|
+
return acc;
|
|
1959
|
+
}, Number.POSITIVE_INFINITY);
|
|
1960
|
+
if (minIndentLength < Number.POSITIVE_INFINITY)
|
|
1961
|
+
return lines.map((x) => x.slice(minIndentLength)).join("\n");
|
|
1962
|
+
return text;
|
|
1963
|
+
}
|
|
1964
|
+
function testLine(line, regexp, regionName, end = false) {
|
|
1965
|
+
const [full, tag, name] = regexp.exec(line.trim()) || [];
|
|
1966
|
+
return full && tag && name === regionName && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/);
|
|
1967
|
+
}
|
|
1968
|
+
function findRegion(lines, regionName) {
|
|
1969
|
+
const regionRegexps = [
|
|
1970
|
+
/^\/\/ ?#?((?:end)?region) ([\w*-]+)$/,
|
|
1971
|
+
// javascript, typescript, java
|
|
1972
|
+
/^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/,
|
|
1973
|
+
// css, less, scss
|
|
1974
|
+
/^#pragma ((?:end)?region) ([\w*-]+)$/,
|
|
1975
|
+
// C, C++
|
|
1976
|
+
/^<!-- #?((?:end)?region) ([\w*-]+) -->$/,
|
|
1977
|
+
// HTML, markdown
|
|
1978
|
+
/^#(End Region) ([\w*-]+)$/,
|
|
1979
|
+
// Visual Basic
|
|
1980
|
+
/^::#(endregion) ([\w*-]+)$/,
|
|
1981
|
+
// Bat
|
|
1982
|
+
/^# ?((?:end)?region) ([\w*-]+)$/
|
|
1983
|
+
// C#, PHP, Powershell, Python, perl & misc
|
|
1984
|
+
];
|
|
1985
|
+
let regexp = null;
|
|
1986
|
+
let start = -1;
|
|
1987
|
+
for (const [lineId, line] of lines.entries()) {
|
|
1988
|
+
if (regexp === null) {
|
|
1989
|
+
for (const reg of regionRegexps) {
|
|
1990
|
+
if (testLine(line, reg, regionName)) {
|
|
1991
|
+
start = lineId + 1;
|
|
1992
|
+
regexp = reg;
|
|
1993
|
+
break;
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
} else if (testLine(line, regexp, regionName, true)) {
|
|
1997
|
+
return { start, end: lineId, regexp };
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
return null;
|
|
2001
|
+
}
|
|
2002
|
+
function transformSnippet({ s, slide, options }) {
|
|
2003
|
+
const watchFiles = options.data.watchFiles;
|
|
2004
|
+
const dir = path2.dirname(slide.source?.filepath ?? options.entry ?? options.userRoot);
|
|
2005
|
+
s.replace(
|
|
2006
|
+
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
2007
|
+
/^<<<\s*(\S.*?)(#[\w-]+)?\s*(?:\s(\S+?))?\s*(\{.*)?$/gm,
|
|
2008
|
+
(full, filepath = "", regionName = "", lang = "", meta = "") => {
|
|
2009
|
+
const src = slash2(
|
|
2010
|
+
/^@\//.test(filepath) ? path2.resolve(options.userRoot, filepath.slice(2)) : path2.resolve(dir, filepath)
|
|
2011
|
+
);
|
|
2012
|
+
watchFiles[src] ??= /* @__PURE__ */ new Set();
|
|
2013
|
+
watchFiles[src].add(slide.index);
|
|
2014
|
+
const isAFile = fs5.statSync(src).isFile();
|
|
2015
|
+
if (!fs5.existsSync(src) || !isAFile) {
|
|
2016
|
+
throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
|
|
2017
|
+
}
|
|
2018
|
+
let content = fs5.readFileSync(src, "utf8");
|
|
2019
|
+
if (regionName) {
|
|
2020
|
+
const lines = content.split(/\r?\n/);
|
|
2021
|
+
const region = findRegion(lines, regionName.slice(1));
|
|
2022
|
+
if (region) {
|
|
2023
|
+
content = dedent(
|
|
2024
|
+
lines.slice(region.start, region.end).filter((line) => !region.regexp.test(line.trim())).join("\n")
|
|
2025
|
+
);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
meta = meta.trim();
|
|
2029
|
+
lang = lang.trim();
|
|
2030
|
+
lang = lang || path2.extname(filepath).slice(1);
|
|
2031
|
+
if (meta.match(/^\{monaco-write\}/)) {
|
|
2032
|
+
monacoWriterWhitelist.add(filepath);
|
|
2033
|
+
lang = lang.trim();
|
|
2034
|
+
meta = meta.replace(/^\{monaco-write\}/, "").trim() || "{}";
|
|
2035
|
+
const encoded = lz4.compressToBase64(content);
|
|
2036
|
+
return `<Monaco writable=${JSON.stringify(filepath)} code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />`;
|
|
2037
|
+
}
|
|
2038
|
+
return `\`\`\`${lang} ${meta}
|
|
2039
|
+
${content}
|
|
2040
|
+
\`\`\``;
|
|
2041
|
+
}
|
|
2042
|
+
);
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
// node/syntax/transform/index.ts
|
|
2046
|
+
async function getMarkdownTransformers(options) {
|
|
2047
|
+
const extras = await setupTransformers(options.roots);
|
|
2048
|
+
return [
|
|
2049
|
+
...extras.pre,
|
|
2050
|
+
transformSnippet,
|
|
2051
|
+
options.data.config.highlighter === "shiki" && transformMagicMove,
|
|
2052
|
+
...extras.preCodeblock,
|
|
2053
|
+
transformMermaid,
|
|
2054
|
+
transformPlantUml,
|
|
2055
|
+
options.data.features.monaco && transformMonaco,
|
|
2056
|
+
...extras.postCodeblock,
|
|
2057
|
+
transformCodeWrapper,
|
|
2058
|
+
options.data.features.katex && transformKaTexWrapper,
|
|
2059
|
+
transformPageCSS,
|
|
2060
|
+
transformSlotSugar,
|
|
2061
|
+
...extras.post
|
|
2062
|
+
];
|
|
2214
2063
|
}
|
|
2215
2064
|
|
|
2216
2065
|
// node/vite/markdown.ts
|
|
@@ -2265,10 +2114,10 @@ async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
|
2265
2114
|
}
|
|
2266
2115
|
|
|
2267
2116
|
// node/vite/monacoTypes.ts
|
|
2268
|
-
import
|
|
2117
|
+
import fs6 from "node:fs/promises";
|
|
2269
2118
|
import { dirname, resolve as resolve5 } from "node:path";
|
|
2270
|
-
import { slash as
|
|
2271
|
-
import
|
|
2119
|
+
import { slash as slash3 } from "@antfu/utils";
|
|
2120
|
+
import fg2 from "fast-glob";
|
|
2272
2121
|
import { findDepPkgJsonPath } from "vitefu";
|
|
2273
2122
|
function createMonacoTypesLoader({ userRoot, utils }) {
|
|
2274
2123
|
return {
|
|
@@ -2289,8 +2138,8 @@ function createMonacoTypesLoader({ userRoot, utils }) {
|
|
|
2289
2138
|
const pkgJsonPath = await findDepPkgJsonPath(pkg, importer);
|
|
2290
2139
|
if (!pkgJsonPath)
|
|
2291
2140
|
throw new Error(`Package "${pkg}" not found in "${importer}"`);
|
|
2292
|
-
const root =
|
|
2293
|
-
const pkgJson = JSON.parse(await
|
|
2141
|
+
const root = slash3(dirname(pkgJsonPath));
|
|
2142
|
+
const pkgJson = JSON.parse(await fs6.readFile(pkgJsonPath, "utf-8"));
|
|
2294
2143
|
let deps = Object.keys(pkgJson.dependencies ?? {});
|
|
2295
2144
|
deps = deps.filter((pkg2) => !utils.isMonacoTypesIgnored(pkg2));
|
|
2296
2145
|
return [
|
|
@@ -2302,7 +2151,7 @@ function createMonacoTypesLoader({ userRoot, utils }) {
|
|
|
2302
2151
|
const query = new URLSearchParams(url.search);
|
|
2303
2152
|
const root = query.get("root");
|
|
2304
2153
|
const name = query.get("name");
|
|
2305
|
-
const files = await
|
|
2154
|
+
const files = await fg2(
|
|
2306
2155
|
[
|
|
2307
2156
|
"**/*.ts",
|
|
2308
2157
|
"**/*.mts",
|
|
@@ -2350,9 +2199,9 @@ async function createRemoteAssetsPlugin({ data: { config }, mode }, pluginOption
|
|
|
2350
2199
|
import ServerRef from "vite-plugin-vue-server-ref";
|
|
2351
2200
|
|
|
2352
2201
|
// node/integrations/drawings.ts
|
|
2353
|
-
import { basename, dirname as dirname2, join as
|
|
2354
|
-
import
|
|
2355
|
-
import
|
|
2202
|
+
import { basename, dirname as dirname2, join as join9, resolve as resolve6 } from "node:path";
|
|
2203
|
+
import fg3 from "fast-glob";
|
|
2204
|
+
import fs7 from "fs-extra";
|
|
2356
2205
|
function resolveDrawingsDir(options) {
|
|
2357
2206
|
return options.data.config.drawings.persist ? resolve6(
|
|
2358
2207
|
dirname2(options.entry),
|
|
@@ -2361,9 +2210,9 @@ function resolveDrawingsDir(options) {
|
|
|
2361
2210
|
}
|
|
2362
2211
|
async function loadDrawings(options) {
|
|
2363
2212
|
const dir = resolveDrawingsDir(options);
|
|
2364
|
-
if (!dir || !
|
|
2213
|
+
if (!dir || !fs7.existsSync(dir))
|
|
2365
2214
|
return {};
|
|
2366
|
-
const files = await
|
|
2215
|
+
const files = await fg3("*.svg", {
|
|
2367
2216
|
onlyFiles: true,
|
|
2368
2217
|
cwd: dir,
|
|
2369
2218
|
absolute: true,
|
|
@@ -2374,7 +2223,7 @@ async function loadDrawings(options) {
|
|
|
2374
2223
|
const num = +basename(path4, ".svg");
|
|
2375
2224
|
if (Number.isNaN(num))
|
|
2376
2225
|
return;
|
|
2377
|
-
const content = await
|
|
2226
|
+
const content = await fs7.readFile(path4, "utf8");
|
|
2378
2227
|
const lines = content.split(/\n/g);
|
|
2379
2228
|
obj[num.toString()] = lines.slice(1, -1).join("\n");
|
|
2380
2229
|
}));
|
|
@@ -2387,7 +2236,7 @@ async function writeDrawings(options, drawing) {
|
|
|
2387
2236
|
const width = options.data.config.canvasWidth;
|
|
2388
2237
|
const height = Math.round(width / options.data.config.aspectRatio);
|
|
2389
2238
|
const SVG_HEAD = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">`;
|
|
2390
|
-
await
|
|
2239
|
+
await fs7.ensureDir(dir);
|
|
2391
2240
|
return Promise.all(
|
|
2392
2241
|
Object.entries(drawing).map(async ([key, value]) => {
|
|
2393
2242
|
if (!value)
|
|
@@ -2395,14 +2244,34 @@ async function writeDrawings(options, drawing) {
|
|
|
2395
2244
|
const svg = `${SVG_HEAD}
|
|
2396
2245
|
${value}
|
|
2397
2246
|
</svg>`;
|
|
2398
|
-
await
|
|
2247
|
+
await fs7.writeFile(join9(dir, `${key}.svg`), svg, "utf-8");
|
|
2399
2248
|
})
|
|
2400
2249
|
);
|
|
2401
2250
|
}
|
|
2402
2251
|
|
|
2252
|
+
// node/integrations/snapshots.ts
|
|
2253
|
+
import { dirname as dirname3, join as join10, resolve as resolve7 } from "node:path";
|
|
2254
|
+
import fs8 from "fs-extra";
|
|
2255
|
+
function resolveSnapshotsDir(options) {
|
|
2256
|
+
return resolve7(dirname3(options.entry), ".slidev/snapshots");
|
|
2257
|
+
}
|
|
2258
|
+
async function loadSnapshots(options) {
|
|
2259
|
+
const dir = resolveSnapshotsDir(options);
|
|
2260
|
+
const file = join10(dir, "snapshots.json");
|
|
2261
|
+
if (!dir || !fs8.existsSync(file))
|
|
2262
|
+
return {};
|
|
2263
|
+
return JSON.parse(await fs8.readFile(file, "utf8"));
|
|
2264
|
+
}
|
|
2265
|
+
async function writeSnapshots(options, data) {
|
|
2266
|
+
const dir = resolveSnapshotsDir(options);
|
|
2267
|
+
if (!dir)
|
|
2268
|
+
return;
|
|
2269
|
+
await fs8.ensureDir(dir);
|
|
2270
|
+
await fs8.writeFile(join10(dir, "snapshots.json"), JSON.stringify(data, null, 2), "utf-8");
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2403
2273
|
// node/vite/serverRef.ts
|
|
2404
2274
|
async function createServerRefPlugin(options, pluginOptions) {
|
|
2405
|
-
const drawingData = await loadDrawings(options);
|
|
2406
2275
|
return ServerRef({
|
|
2407
2276
|
debug: false,
|
|
2408
2277
|
// process.env.NODE_ENV === 'development',
|
|
@@ -2412,37 +2281,56 @@ async function createServerRefPlugin(options, pluginOptions) {
|
|
|
2412
2281
|
page: 0,
|
|
2413
2282
|
clicks: 0
|
|
2414
2283
|
},
|
|
2415
|
-
drawings:
|
|
2284
|
+
drawings: await loadDrawings(options),
|
|
2285
|
+
snapshots: await loadSnapshots(options),
|
|
2416
2286
|
...pluginOptions.serverRef?.state
|
|
2417
2287
|
},
|
|
2418
2288
|
onChanged(key, data, patch, timestamp) {
|
|
2419
2289
|
pluginOptions.serverRef?.onChanged?.(key, data, patch, timestamp);
|
|
2420
|
-
if (
|
|
2421
|
-
return;
|
|
2422
|
-
if (key === "drawings")
|
|
2290
|
+
if (options.data.config.drawings.persist && key === "drawings")
|
|
2423
2291
|
writeDrawings(options, patch ?? data);
|
|
2292
|
+
if (key === "snapshots")
|
|
2293
|
+
writeSnapshots(options, data);
|
|
2424
2294
|
}
|
|
2425
2295
|
});
|
|
2426
2296
|
}
|
|
2427
2297
|
|
|
2298
|
+
// node/vite/staticCopy.ts
|
|
2299
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
2300
|
+
import { join as join11 } from "node:path";
|
|
2301
|
+
async function createStaticCopyPlugin({ themeRoots, addonRoots }, pluginOptions) {
|
|
2302
|
+
const publicDirs = [...themeRoots, ...addonRoots].map((i) => join11(i, "public")).filter(existsSync5);
|
|
2303
|
+
if (!publicDirs.length)
|
|
2304
|
+
return;
|
|
2305
|
+
const { viteStaticCopy } = await import("vite-plugin-static-copy");
|
|
2306
|
+
return viteStaticCopy({
|
|
2307
|
+
silent: true,
|
|
2308
|
+
targets: publicDirs.map((dir) => ({
|
|
2309
|
+
src: `${dir}/*`,
|
|
2310
|
+
dest: "theme"
|
|
2311
|
+
})),
|
|
2312
|
+
...pluginOptions.staticCopy
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2428
2316
|
// node/vite/unocss.ts
|
|
2429
2317
|
import UnoCSS from "unocss/vite";
|
|
2430
2318
|
|
|
2431
2319
|
// node/setups/unocss.ts
|
|
2432
|
-
import {
|
|
2433
|
-
import {
|
|
2320
|
+
import { existsSync as existsSync6, readFileSync } from "node:fs";
|
|
2321
|
+
import { resolve as resolve8 } from "node:path";
|
|
2434
2322
|
import { mergeConfigs, presetIcons } from "unocss";
|
|
2435
2323
|
async function setupUnocss({ clientRoot, roots, data, utils }) {
|
|
2436
|
-
function loadFileConfigs(root) {
|
|
2437
|
-
return [
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
].map((i) => {
|
|
2324
|
+
async function loadFileConfigs(root) {
|
|
2325
|
+
return (await Promise.all([
|
|
2326
|
+
resolve8(root, "uno.config.ts"),
|
|
2327
|
+
resolve8(root, "unocss.config.ts")
|
|
2328
|
+
].map(async (i) => {
|
|
2441
2329
|
if (!existsSync6(i))
|
|
2442
2330
|
return void 0;
|
|
2443
|
-
const loaded = loadModule(i);
|
|
2331
|
+
const loaded = await loadModule(i);
|
|
2444
2332
|
return "default" in loaded ? loaded.default : loaded;
|
|
2445
|
-
});
|
|
2333
|
+
}))).filter((x) => !!x);
|
|
2446
2334
|
}
|
|
2447
2335
|
const configs = [
|
|
2448
2336
|
{
|
|
@@ -2451,13 +2339,13 @@ async function setupUnocss({ clientRoot, roots, data, utils }) {
|
|
|
2451
2339
|
collectionsNodeResolvePath: utils.iconsResolvePath,
|
|
2452
2340
|
collections: {
|
|
2453
2341
|
slidev: {
|
|
2454
|
-
logo: () =>
|
|
2342
|
+
logo: () => readFileSync(resolve8(clientRoot, "assets/logo.svg"), "utf-8")
|
|
2455
2343
|
}
|
|
2456
2344
|
}
|
|
2457
2345
|
})
|
|
2458
2346
|
]
|
|
2459
2347
|
},
|
|
2460
|
-
...loadFileConfigs(clientRoot),
|
|
2348
|
+
...await loadFileConfigs(clientRoot),
|
|
2461
2349
|
...await loadSetups(roots, "unocss.ts", [], loadFileConfigs)
|
|
2462
2350
|
].filter(Boolean);
|
|
2463
2351
|
const config = mergeConfigs(configs);
|
|
@@ -2536,24 +2424,6 @@ async function createVuePlugin(_options, pluginOptions) {
|
|
|
2536
2424
|
];
|
|
2537
2425
|
}
|
|
2538
2426
|
|
|
2539
|
-
// node/vite/staticCopy.ts
|
|
2540
|
-
import { existsSync as existsSync7 } from "node:fs";
|
|
2541
|
-
import { join as join11 } from "node:path";
|
|
2542
|
-
async function createStaticCopyPlugin({ themeRoots, addonRoots }, pluginOptions) {
|
|
2543
|
-
const publicDirs = [...themeRoots, ...addonRoots].map((i) => join11(i, "public")).filter(existsSync7);
|
|
2544
|
-
if (!publicDirs.length)
|
|
2545
|
-
return;
|
|
2546
|
-
const { viteStaticCopy } = await import("vite-plugin-static-copy");
|
|
2547
|
-
return viteStaticCopy({
|
|
2548
|
-
silent: true,
|
|
2549
|
-
targets: publicDirs.map((dir) => ({
|
|
2550
|
-
src: `${dir}/*`,
|
|
2551
|
-
dest: "theme"
|
|
2552
|
-
})),
|
|
2553
|
-
...pluginOptions.staticCopy
|
|
2554
|
-
});
|
|
2555
|
-
}
|
|
2556
|
-
|
|
2557
2427
|
// node/vite/index.ts
|
|
2558
2428
|
async function ViteSlidevPlugin(options, pluginOptions = {}, serverOptions = {}) {
|
|
2559
2429
|
return Promise.all([
|
|
@@ -2593,7 +2463,7 @@ async function resolveViteConfigs(options, baseConfig, overrideConfigs, command,
|
|
|
2593
2463
|
};
|
|
2594
2464
|
const files = options.roots.map((i) => join12(i, "vite.config.ts"));
|
|
2595
2465
|
for (const file of files) {
|
|
2596
|
-
if (!
|
|
2466
|
+
if (!existsSync7(file))
|
|
2597
2467
|
continue;
|
|
2598
2468
|
const viteConfig = await loadConfigFromFile(configEnv, file);
|
|
2599
2469
|
if (!viteConfig?.config)
|
|
@@ -2613,15 +2483,184 @@ async function resolveViteConfigs(options, baseConfig, overrideConfigs, command,
|
|
|
2613
2483
|
return baseConfig;
|
|
2614
2484
|
}
|
|
2615
2485
|
|
|
2486
|
+
// node/setups/indexHtml.ts
|
|
2487
|
+
function toAttrValue(unsafe) {
|
|
2488
|
+
return JSON.stringify(escapeHtml(String(unsafe)));
|
|
2489
|
+
}
|
|
2490
|
+
function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data }) {
|
|
2491
|
+
let main = readFileSync2(join13(clientRoot, "index.html"), "utf-8");
|
|
2492
|
+
let head = "";
|
|
2493
|
+
let body = "";
|
|
2494
|
+
const { info, author, keywords } = data.headmatter;
|
|
2495
|
+
head += [
|
|
2496
|
+
`<meta name="slidev:version" content="${version}">`,
|
|
2497
|
+
mode === "dev" && `<meta charset="slidev:entry" content="${slash4(entry)}">`,
|
|
2498
|
+
`<link rel="icon" href="${data.config.favicon}">`,
|
|
2499
|
+
`<title>${getSlideTitle(data)}</title>`,
|
|
2500
|
+
info && `<meta name="description" content=${toAttrValue(info)}>`,
|
|
2501
|
+
author && `<meta name="author" content=${toAttrValue(author)}>`,
|
|
2502
|
+
keywords && `<meta name="keywords" content=${toAttrValue(Array.isArray(keywords) ? keywords.join(", ") : keywords)}>`
|
|
2503
|
+
].filter(Boolean).join("\n");
|
|
2504
|
+
for (const root of roots) {
|
|
2505
|
+
const path4 = join13(root, "index.html");
|
|
2506
|
+
if (!existsSync8(path4))
|
|
2507
|
+
continue;
|
|
2508
|
+
const index = readFileSync2(path4, "utf-8");
|
|
2509
|
+
if (root === userRoot && index.includes("<!DOCTYPE")) {
|
|
2510
|
+
console.error(yellow2(`[Slidev] Ignored provided index.html with doctype declaration. (${white(path4)})`));
|
|
2511
|
+
console.error(yellow2("This file may be generated by Slidev, please remove it from your project."));
|
|
2512
|
+
continue;
|
|
2513
|
+
}
|
|
2514
|
+
head += `
|
|
2515
|
+
${(index.match(/<head>([\s\S]*?)<\/head>/i)?.[1] || "").trim()}`;
|
|
2516
|
+
body += `
|
|
2517
|
+
${(index.match(/<body>([\s\S]*?)<\/body>/i)?.[1] || "").trim()}`;
|
|
2518
|
+
}
|
|
2519
|
+
if (data.features.tweet)
|
|
2520
|
+
body += '\n<script async src="https://platform.twitter.com/widgets.js"></script>';
|
|
2521
|
+
if (data.config.fonts.webfonts.length && data.config.fonts.provider !== "none")
|
|
2522
|
+
head += `
|
|
2523
|
+
<link rel="stylesheet" href="${generateGoogleFontsUrl(data.config.fonts)}" type="text/css">`;
|
|
2524
|
+
main = main.replace("__ENTRY__", toAtFS(join13(clientRoot, "main.ts"))).replace("<!-- head -->", head).replace("<!-- body -->", body);
|
|
2525
|
+
return main;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
// node/setups/shiki.ts
|
|
2529
|
+
import fs9 from "node:fs/promises";
|
|
2530
|
+
import { bundledLanguages, createHighlighter } from "shiki";
|
|
2531
|
+
var cachedRoots;
|
|
2532
|
+
var cachedShiki;
|
|
2533
|
+
async function setupShiki(roots) {
|
|
2534
|
+
if (cachedRoots === roots)
|
|
2535
|
+
return cachedShiki;
|
|
2536
|
+
cachedShiki?.shiki.dispose();
|
|
2537
|
+
const options = await loadSetups(
|
|
2538
|
+
roots,
|
|
2539
|
+
"shiki.ts",
|
|
2540
|
+
[{
|
|
2541
|
+
/** @deprecated */
|
|
2542
|
+
async loadTheme(path4) {
|
|
2543
|
+
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.");
|
|
2544
|
+
return JSON.parse(await fs9.readFile(path4, "utf-8"));
|
|
2545
|
+
}
|
|
2546
|
+
}]
|
|
2547
|
+
);
|
|
2548
|
+
const mergedOptions = Object.assign({}, ...options);
|
|
2549
|
+
if ("theme" in mergedOptions && "themes" in mergedOptions)
|
|
2550
|
+
delete mergedOptions.theme;
|
|
2551
|
+
if (mergedOptions.theme && typeof mergedOptions.theme !== "string" && !mergedOptions.theme.name && !mergedOptions.theme.tokenColors) {
|
|
2552
|
+
mergedOptions.themes = mergedOptions.theme;
|
|
2553
|
+
delete mergedOptions.theme;
|
|
2554
|
+
}
|
|
2555
|
+
if (!mergedOptions.theme && !mergedOptions.themes) {
|
|
2556
|
+
mergedOptions.themes = {
|
|
2557
|
+
dark: "vitesse-dark",
|
|
2558
|
+
light: "vitesse-light"
|
|
2559
|
+
};
|
|
2560
|
+
}
|
|
2561
|
+
if (mergedOptions.themes)
|
|
2562
|
+
mergedOptions.defaultColor = false;
|
|
2563
|
+
const shiki = await createHighlighter({
|
|
2564
|
+
...mergedOptions,
|
|
2565
|
+
langs: mergedOptions.langs ?? Object.keys(bundledLanguages),
|
|
2566
|
+
themes: "themes" in mergedOptions ? Object.values(mergedOptions.themes) : [mergedOptions.theme]
|
|
2567
|
+
});
|
|
2568
|
+
cachedRoots = roots;
|
|
2569
|
+
return cachedShiki = {
|
|
2570
|
+
shiki,
|
|
2571
|
+
shikiOptions: mergedOptions
|
|
2572
|
+
};
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
// node/options.ts
|
|
2576
|
+
var debug = Debug("slidev:options");
|
|
2577
|
+
async function resolveOptions(entryOptions, mode) {
|
|
2578
|
+
const entry = await resolveEntry(entryOptions.entry);
|
|
2579
|
+
const rootsInfo = await getRoots(entry);
|
|
2580
|
+
const loaded = await parser.load(rootsInfo.userRoot, entry, void 0, mode);
|
|
2581
|
+
let themeRaw = entryOptions.theme || loaded.headmatter.theme;
|
|
2582
|
+
themeRaw = themeRaw === null ? "none" : themeRaw || "default";
|
|
2583
|
+
const [theme, themeRoot] = await resolveTheme(themeRaw, entry);
|
|
2584
|
+
const themeRoots = themeRoot ? [themeRoot] : [];
|
|
2585
|
+
const themeMeta = themeRoot ? await getThemeMeta(theme, themeRoot) : void 0;
|
|
2586
|
+
const config = parser.resolveConfig(loaded.headmatter, themeMeta, entryOptions.entry);
|
|
2587
|
+
const addonRoots = await resolveAddons(config.addons);
|
|
2588
|
+
const roots = uniq5([...themeRoots, ...addonRoots, rootsInfo.userRoot]);
|
|
2589
|
+
debug({
|
|
2590
|
+
...rootsInfo,
|
|
2591
|
+
...entryOptions,
|
|
2592
|
+
config,
|
|
2593
|
+
mode,
|
|
2594
|
+
entry,
|
|
2595
|
+
themeRaw,
|
|
2596
|
+
theme,
|
|
2597
|
+
themeRoots,
|
|
2598
|
+
addonRoots,
|
|
2599
|
+
roots
|
|
2600
|
+
});
|
|
2601
|
+
const data = {
|
|
2602
|
+
...loaded,
|
|
2603
|
+
config,
|
|
2604
|
+
themeMeta
|
|
2605
|
+
};
|
|
2606
|
+
const resolved = {
|
|
2607
|
+
...rootsInfo,
|
|
2608
|
+
...entryOptions,
|
|
2609
|
+
data,
|
|
2610
|
+
mode,
|
|
2611
|
+
entry,
|
|
2612
|
+
themeRaw,
|
|
2613
|
+
theme,
|
|
2614
|
+
themeRoots,
|
|
2615
|
+
addonRoots,
|
|
2616
|
+
roots
|
|
2617
|
+
};
|
|
2618
|
+
return {
|
|
2619
|
+
...resolved,
|
|
2620
|
+
utils: await createDataUtils(resolved)
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2623
|
+
async function createDataUtils(resolved) {
|
|
2624
|
+
const monacoTypesIgnorePackagesMatches = (resolved.data.config.monacoTypesIgnorePackages || []).map((i) => mm.matcher(i));
|
|
2625
|
+
let _layouts_cache_time = 0;
|
|
2626
|
+
let _layouts_cache = {};
|
|
2627
|
+
return {
|
|
2628
|
+
...await setupShiki(resolved.roots),
|
|
2629
|
+
indexHtml: setupIndexHtml(resolved),
|
|
2630
|
+
iconsResolvePath: [resolved.clientRoot, ...resolved.roots].reverse(),
|
|
2631
|
+
isMonacoTypesIgnored: (pkg) => monacoTypesIgnorePackagesMatches.some((i) => i(pkg)),
|
|
2632
|
+
getLayouts: () => {
|
|
2633
|
+
const now = Date.now();
|
|
2634
|
+
if (now - _layouts_cache_time < 2e3)
|
|
2635
|
+
return _layouts_cache;
|
|
2636
|
+
const layouts = {};
|
|
2637
|
+
for (const root of [resolved.clientRoot, ...resolved.roots]) {
|
|
2638
|
+
const layoutPaths = fg4.sync("layouts/**/*.{vue,ts}", {
|
|
2639
|
+
cwd: root,
|
|
2640
|
+
absolute: true,
|
|
2641
|
+
suppressErrors: true
|
|
2642
|
+
});
|
|
2643
|
+
for (const layoutPath of layoutPaths) {
|
|
2644
|
+
const layoutName = path3.basename(layoutPath).replace(/\.\w+$/, "");
|
|
2645
|
+
layouts[layoutName] = layoutPath;
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
_layouts_cache_time = now;
|
|
2649
|
+
_layouts_cache = layouts;
|
|
2650
|
+
return layouts;
|
|
2651
|
+
}
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
|
|
2616
2655
|
export {
|
|
2617
|
-
resolveViteConfigs,
|
|
2618
|
-
parser,
|
|
2619
2656
|
version,
|
|
2657
|
+
resolveAddons,
|
|
2620
2658
|
resolveTheme,
|
|
2621
2659
|
getThemeMeta,
|
|
2622
|
-
|
|
2660
|
+
parser,
|
|
2623
2661
|
loadSetups,
|
|
2624
2662
|
resolveOptions,
|
|
2625
2663
|
createDataUtils,
|
|
2626
|
-
ViteSlidevPlugin
|
|
2664
|
+
ViteSlidevPlugin,
|
|
2665
|
+
resolveViteConfigs
|
|
2627
2666
|
};
|