@slidev/cli 51.6.0 → 51.6.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-oRYT3yXD.js +62 -0
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +518 -594
- package/dist/export-D1Zqc-n1.js +433 -0
- package/dist/index.d.ts +12 -7
- package/dist/index.js +5 -17
- package/dist/resolver-BShaA6qw.js +155 -0
- package/dist/serve-D6FyjIir.js +14 -0
- package/dist/shared-D3tuRsUE.js +2475 -0
- package/package.json +23 -23
- package/dist/build-Z7GTSSXD.js +0 -77
- package/dist/chunk-BCA62OS7.js +0 -29
- package/dist/chunk-TJFRPB4N.js +0 -190
- package/dist/chunk-Y2DHOFI5.js +0 -2761
- package/dist/export-5TR5BGLG.js +0 -520
package/dist/chunk-Y2DHOFI5.js
DELETED
|
@@ -1,2761 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createResolver,
|
|
3
|
-
getRoots,
|
|
4
|
-
isInstalledGlobally,
|
|
5
|
-
resolveEntry,
|
|
6
|
-
resolveImportPath,
|
|
7
|
-
resolveImportUrl,
|
|
8
|
-
toAtFS
|
|
9
|
-
} from "./chunk-TJFRPB4N.js";
|
|
10
|
-
|
|
11
|
-
// package.json
|
|
12
|
-
var version = "51.6.0";
|
|
13
|
-
|
|
14
|
-
// node/utils.ts
|
|
15
|
-
import { fileURLToPath } from "node:url";
|
|
16
|
-
import { createJiti } from "jiti";
|
|
17
|
-
import YAML from "yaml";
|
|
18
|
-
var jiti;
|
|
19
|
-
function loadModule(absolutePath) {
|
|
20
|
-
jiti ??= createJiti(fileURLToPath(import.meta.url), {
|
|
21
|
-
// Allows changes to take effect
|
|
22
|
-
moduleCache: false
|
|
23
|
-
});
|
|
24
|
-
return jiti.import(absolutePath);
|
|
25
|
-
}
|
|
26
|
-
function stringifyMarkdownTokens(tokens) {
|
|
27
|
-
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(" ");
|
|
28
|
-
}
|
|
29
|
-
function generateFontParams(options) {
|
|
30
|
-
const weights = options.weights.flatMap((i) => options.italic ? [`0,${i}`, `1,${i}`] : [`${i}`]).sort().join(";");
|
|
31
|
-
const fontParams = options.webfonts.map((i) => `family=${i.replace(/^(['"])(.*)\1$/, "$1").replace(/\s+/g, "+")}:${options.italic ? "ital," : ""}wght@${weights}`).join("&");
|
|
32
|
-
return fontParams;
|
|
33
|
-
}
|
|
34
|
-
function generateGoogleFontsUrl(options) {
|
|
35
|
-
return `https://fonts.googleapis.com/css2?${generateFontParams(options)}&display=swap`;
|
|
36
|
-
}
|
|
37
|
-
function generateCoollabsFontsUrl(options) {
|
|
38
|
-
return `https://api.fonts.coollabs.io/fonts?${generateFontParams(options)}&display=swap`;
|
|
39
|
-
}
|
|
40
|
-
function updateFrontmatterPatch(source, frontmatter) {
|
|
41
|
-
let doc = source.frontmatterDoc;
|
|
42
|
-
if (!doc) {
|
|
43
|
-
source.frontmatterStyle = "frontmatter";
|
|
44
|
-
source.frontmatterDoc = doc = new YAML.Document({});
|
|
45
|
-
}
|
|
46
|
-
for (const [key, value] of Object.entries(frontmatter)) {
|
|
47
|
-
source.frontmatter[key] = value;
|
|
48
|
-
if (value == null) {
|
|
49
|
-
doc.delete(key);
|
|
50
|
-
} else {
|
|
51
|
-
const valueNode = doc.createNode(value);
|
|
52
|
-
let found = false;
|
|
53
|
-
YAML.visit(doc.contents, {
|
|
54
|
-
Pair(_key, node, path5) {
|
|
55
|
-
if (path5.length === 1 && YAML.isScalar(node.key) && node.key.value === key) {
|
|
56
|
-
node.value = valueNode;
|
|
57
|
-
found = true;
|
|
58
|
-
return YAML.visit.BREAK;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
if (!found) {
|
|
63
|
-
if (!YAML.isMap(doc.contents))
|
|
64
|
-
doc.contents = doc.createNode({});
|
|
65
|
-
doc.contents.add(
|
|
66
|
-
doc.createPair(key, valueNode)
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function getBodyJson(req) {
|
|
73
|
-
return new Promise((resolve9, reject) => {
|
|
74
|
-
let body = "";
|
|
75
|
-
req.on("data", (chunk) => body += chunk);
|
|
76
|
-
req.on("error", reject);
|
|
77
|
-
req.on("end", () => {
|
|
78
|
-
try {
|
|
79
|
-
resolve9(JSON.parse(body) || {});
|
|
80
|
-
} catch (e) {
|
|
81
|
-
reject(e);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// node/integrations/themes.ts
|
|
88
|
-
import { existsSync } from "node:fs";
|
|
89
|
-
import fs from "node:fs/promises";
|
|
90
|
-
import { join } from "node:path";
|
|
91
|
-
import { satisfies } from "semver";
|
|
92
|
-
var officialThemes = {
|
|
93
|
-
"none": "",
|
|
94
|
-
"default": "@slidev/theme-default",
|
|
95
|
-
"seriph": "@slidev/theme-seriph",
|
|
96
|
-
"apple-basic": "@slidev/theme-apple-basic",
|
|
97
|
-
"shibainu": "@slidev/theme-shibainu",
|
|
98
|
-
"bricks": "@slidev/theme-bricks"
|
|
99
|
-
};
|
|
100
|
-
var resolveTheme = createResolver("theme", officialThemes);
|
|
101
|
-
async function getThemeMeta(name, root) {
|
|
102
|
-
const path5 = join(root, "package.json");
|
|
103
|
-
if (!existsSync(path5))
|
|
104
|
-
return {};
|
|
105
|
-
const { slidev = {}, engines = {} } = JSON.parse(await fs.readFile(path5, "utf-8"));
|
|
106
|
-
if (engines.slidev && !satisfies(version, engines.slidev, { includePrerelease: true }))
|
|
107
|
-
throw new Error(`[slidev] theme "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
|
|
108
|
-
return slidev;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// node/parser.ts
|
|
112
|
-
import * as parser from "@slidev/parser/fs";
|
|
113
|
-
|
|
114
|
-
// node/options.ts
|
|
115
|
-
import path4 from "node:path";
|
|
116
|
-
import { objectMap as objectMap2, uniq as uniq5 } from "@antfu/utils";
|
|
117
|
-
import Debug from "debug";
|
|
118
|
-
import fg4 from "fast-glob";
|
|
119
|
-
import pm from "picomatch";
|
|
120
|
-
|
|
121
|
-
// node/integrations/addons.ts
|
|
122
|
-
import fs2 from "node:fs/promises";
|
|
123
|
-
import { resolve } from "node:path";
|
|
124
|
-
import { satisfies as satisfies2 } from "semver";
|
|
125
|
-
async function resolveAddons(addonsInConfig) {
|
|
126
|
-
const { userRoot, userPkgJson } = await getRoots();
|
|
127
|
-
const resolved = [];
|
|
128
|
-
const resolveAddonNameAndRoot = createResolver("addon", {});
|
|
129
|
-
async function resolveAddon(name, parent) {
|
|
130
|
-
const [, pkgRoot] = await resolveAddonNameAndRoot(name, parent);
|
|
131
|
-
if (!pkgRoot)
|
|
132
|
-
return;
|
|
133
|
-
resolved.push(pkgRoot);
|
|
134
|
-
const { slidev = {}, engines = {} } = JSON.parse(await fs2.readFile(resolve(pkgRoot, "package.json"), "utf-8"));
|
|
135
|
-
if (engines.slidev && !satisfies2(version, engines.slidev, { includePrerelease: true }))
|
|
136
|
-
throw new Error(`[slidev] addon "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
|
|
137
|
-
if (Array.isArray(slidev.addons))
|
|
138
|
-
await Promise.all(slidev.addons.map((addon) => resolveAddon(addon, pkgRoot)));
|
|
139
|
-
}
|
|
140
|
-
if (Array.isArray(addonsInConfig))
|
|
141
|
-
await Promise.all(addonsInConfig.map((addon) => resolveAddon(addon, userRoot)));
|
|
142
|
-
if (Array.isArray(userPkgJson.slidev?.addons))
|
|
143
|
-
await Promise.all(userPkgJson.slidev.addons.map((addon) => resolveAddon(addon, userRoot)));
|
|
144
|
-
return resolved;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// node/setups/indexHtml.ts
|
|
148
|
-
import { existsSync as existsSync13, readFileSync as readFileSync2 } from "node:fs";
|
|
149
|
-
import { join as join13 } from "node:path";
|
|
150
|
-
import { slash as slash4 } from "@antfu/utils";
|
|
151
|
-
import { white, yellow as yellow2 } from "ansis";
|
|
152
|
-
import { escapeHtml } from "markdown-it/lib/common/utils.mjs";
|
|
153
|
-
import { createHead, extractUnheadInputFromHtml, transformHtmlTemplate } from "unhead/server";
|
|
154
|
-
|
|
155
|
-
// node/commands/shared.ts
|
|
156
|
-
import { existsSync as existsSync12 } from "node:fs";
|
|
157
|
-
import { join as join12 } from "node:path";
|
|
158
|
-
import MarkdownIt2 from "markdown-it";
|
|
159
|
-
import { loadConfigFromFile, mergeConfig as mergeConfig2 } from "vite";
|
|
160
|
-
|
|
161
|
-
// node/syntax/markdown-it/markdown-it-link.ts
|
|
162
|
-
function MarkdownItLink(md) {
|
|
163
|
-
const defaultRender = md.renderer.rules.link_open ?? ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));
|
|
164
|
-
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
|
|
165
|
-
const token = tokens[idx];
|
|
166
|
-
const hrefIndex = token.attrIndex("href");
|
|
167
|
-
const attr = token.attrs?.[hrefIndex];
|
|
168
|
-
const href = attr?.[1] ?? "";
|
|
169
|
-
if ("./#".includes(href[0]) || /^\d+$/.test(href)) {
|
|
170
|
-
token.tag = "Link";
|
|
171
|
-
attr[0] = "to";
|
|
172
|
-
for (let i = idx + 1; i < tokens.length; i++) {
|
|
173
|
-
if (tokens[i].type === "link_close") {
|
|
174
|
-
tokens[i].tag = "Link";
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
} else if (token.attrGet("target") == null) {
|
|
179
|
-
token.attrPush(["target", "_blank"]);
|
|
180
|
-
}
|
|
181
|
-
return defaultRender(tokens, idx, options, env, self);
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// node/vite/compilerFlagsVue.ts
|
|
186
|
-
import { objectEntries } from "@antfu/utils";
|
|
187
|
-
function createVueCompilerFlagsPlugin(options) {
|
|
188
|
-
const define = objectEntries(options.utils.define);
|
|
189
|
-
return {
|
|
190
|
-
name: "slidev:flags",
|
|
191
|
-
enforce: "pre",
|
|
192
|
-
transform(code, id) {
|
|
193
|
-
if (!id.match(/\.vue($|\?)/) && !id.includes("?vue&"))
|
|
194
|
-
return;
|
|
195
|
-
const original = code;
|
|
196
|
-
define.forEach(([from, to]) => {
|
|
197
|
-
code = code.replaceAll(from, to);
|
|
198
|
-
});
|
|
199
|
-
if (original !== code)
|
|
200
|
-
return code;
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// node/vite/components.ts
|
|
206
|
-
import { join as join2 } from "node:path";
|
|
207
|
-
import IconsResolver from "unplugin-icons/resolver";
|
|
208
|
-
import Components from "unplugin-vue-components/vite";
|
|
209
|
-
function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
|
|
210
|
-
return Components({
|
|
211
|
-
extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
|
|
212
|
-
dirs: [
|
|
213
|
-
join2(clientRoot, "builtin"),
|
|
214
|
-
...roots.map((i) => join2(i, "components"))
|
|
215
|
-
],
|
|
216
|
-
globsExclude: [],
|
|
217
|
-
include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
|
|
218
|
-
exclude: [],
|
|
219
|
-
resolvers: [
|
|
220
|
-
IconsResolver({
|
|
221
|
-
prefix: "",
|
|
222
|
-
customCollections: Object.keys(pluginOptions.icons?.customCollections || [])
|
|
223
|
-
})
|
|
224
|
-
],
|
|
225
|
-
dts: false,
|
|
226
|
-
...pluginOptions.components
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// node/vite/common.ts
|
|
231
|
-
var regexSlideReqPath = /^\/__slidev\/slides\/(\d+)\.json$/;
|
|
232
|
-
var regexSlideFacadeId = /^\/@slidev\/slides\/(\d+)\/(md|frontmatter)($|\?)/;
|
|
233
|
-
var regexSlideSourceId = /__slidev_(\d+)\.(md|frontmatter)$/;
|
|
234
|
-
var templateInjectionMarker = "/* @slidev-injection */";
|
|
235
|
-
var templateImportContextUtils = `import { useSlideContext as _useSlideContext, frontmatterToProps as _frontmatterToProps } from "@slidev/client/context.ts"`;
|
|
236
|
-
var templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = _useSlideContext()`;
|
|
237
|
-
|
|
238
|
-
// node/vite/contextInjection.ts
|
|
239
|
-
function createContextInjectionPlugin() {
|
|
240
|
-
return {
|
|
241
|
-
name: "slidev:context-injection",
|
|
242
|
-
async transform(code, id) {
|
|
243
|
-
if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/"))
|
|
244
|
-
return;
|
|
245
|
-
if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
|
|
246
|
-
return code;
|
|
247
|
-
const imports = [
|
|
248
|
-
templateImportContextUtils,
|
|
249
|
-
templateInitContext,
|
|
250
|
-
templateInjectionMarker
|
|
251
|
-
];
|
|
252
|
-
const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
|
|
253
|
-
if (matchScript && matchScript[2]) {
|
|
254
|
-
return code.replace(/(<script.*>)/g, `$1
|
|
255
|
-
${imports.join("\n")}
|
|
256
|
-
`);
|
|
257
|
-
} else if (matchScript && !matchScript[2]) {
|
|
258
|
-
const matchExport = code.match(/export\s+default\s+\{/);
|
|
259
|
-
if (matchExport) {
|
|
260
|
-
const exportIndex = (matchExport.index || 0) + matchExport[0].length;
|
|
261
|
-
let component = code.slice(exportIndex);
|
|
262
|
-
component = component.slice(0, component.indexOf("</script>"));
|
|
263
|
-
const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
|
|
264
|
-
const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
|
|
265
|
-
code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
|
|
266
|
-
let injectIndex = exportIndex + provideImport.length;
|
|
267
|
-
let injectObject = "$slidev: { from: injectionSlidevContext },";
|
|
268
|
-
const matchInject = component.match(/.*inject\s*:\s*([[{])/);
|
|
269
|
-
if (matchInject) {
|
|
270
|
-
injectIndex += (matchInject.index || 0) + matchInject[0].length;
|
|
271
|
-
if (matchInject[1] === "[") {
|
|
272
|
-
let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
|
|
273
|
-
const injectEndIndex = injects.indexOf("]");
|
|
274
|
-
injects = injects.slice(0, injectEndIndex);
|
|
275
|
-
injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
|
|
276
|
-
return `${code.slice(0, injectIndex - 1)}{
|
|
277
|
-
${injectObject}
|
|
278
|
-
}${code.slice(injectIndex + injectEndIndex + 1)}`;
|
|
279
|
-
} else {
|
|
280
|
-
return `${code.slice(0, injectIndex)}
|
|
281
|
-
${injectObject}
|
|
282
|
-
${code.slice(injectIndex)}`;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
return `${code.slice(0, injectIndex)}
|
|
286
|
-
inject: { ${injectObject} },
|
|
287
|
-
${code.slice(injectIndex)}`;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return `<script setup>
|
|
291
|
-
${imports.join("\n")}
|
|
292
|
-
</script>
|
|
293
|
-
${code}`;
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// node/vite/extendConfig.ts
|
|
299
|
-
import { join as join3 } from "node:path";
|
|
300
|
-
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
301
|
-
import { slash, uniq } from "@antfu/utils";
|
|
302
|
-
import { createResolve } from "mlly";
|
|
303
|
-
import { mergeConfig } from "vite";
|
|
304
|
-
var INCLUDE_GLOBAL = [
|
|
305
|
-
"@typescript/ata",
|
|
306
|
-
"file-saver",
|
|
307
|
-
"lz-string",
|
|
308
|
-
"prettier",
|
|
309
|
-
"recordrtc",
|
|
310
|
-
"typescript",
|
|
311
|
-
"yaml"
|
|
312
|
-
];
|
|
313
|
-
var INCLUDE_LOCAL = INCLUDE_GLOBAL.map((i) => `@slidev/cli > @slidev/client > ${i}`);
|
|
314
|
-
var EXCLUDE_GLOBAL = [
|
|
315
|
-
"@antfu/utils",
|
|
316
|
-
"@shikijs/monaco",
|
|
317
|
-
"@shikijs/vitepress-twoslash/client",
|
|
318
|
-
"@slidev/client",
|
|
319
|
-
"@slidev/client/constants",
|
|
320
|
-
"@slidev/client/context",
|
|
321
|
-
"@slidev/client/logic/dark",
|
|
322
|
-
"@slidev/parser",
|
|
323
|
-
"@slidev/parser/core",
|
|
324
|
-
"@slidev/rough-notation",
|
|
325
|
-
"@slidev/types",
|
|
326
|
-
"@unhead/vue",
|
|
327
|
-
"@unocss/reset",
|
|
328
|
-
"@vueuse/core",
|
|
329
|
-
"@vueuse/math",
|
|
330
|
-
"@vueuse/motion",
|
|
331
|
-
"@vueuse/shared",
|
|
332
|
-
"drauu",
|
|
333
|
-
"floating-vue",
|
|
334
|
-
"fuse.js",
|
|
335
|
-
"mermaid",
|
|
336
|
-
"monaco-editor",
|
|
337
|
-
"shiki-magic-move/vue",
|
|
338
|
-
"shiki",
|
|
339
|
-
"shiki/core",
|
|
340
|
-
"vue-demi",
|
|
341
|
-
"vue-router",
|
|
342
|
-
"vue"
|
|
343
|
-
];
|
|
344
|
-
var EXCLUDE_LOCAL = EXCLUDE_GLOBAL;
|
|
345
|
-
var ASYNC_MODULES = [
|
|
346
|
-
"file-saver",
|
|
347
|
-
"vue",
|
|
348
|
-
"@vue"
|
|
349
|
-
];
|
|
350
|
-
function createConfigPlugin(options) {
|
|
351
|
-
const resolveClientDep = createResolve({
|
|
352
|
-
// Same as Vite's default resolve conditions
|
|
353
|
-
conditions: ["import", "module", "browser", "default", options.mode === "build" ? "production" : "development"],
|
|
354
|
-
url: pathToFileURL(options.clientRoot)
|
|
355
|
-
});
|
|
356
|
-
return {
|
|
357
|
-
name: "slidev:config",
|
|
358
|
-
async config(config) {
|
|
359
|
-
const injection = {
|
|
360
|
-
define: options.utils.define,
|
|
361
|
-
resolve: {
|
|
362
|
-
alias: [
|
|
363
|
-
{
|
|
364
|
-
find: /^@slidev\/client$/,
|
|
365
|
-
replacement: `${toAtFS(options.clientRoot)}/index.ts`
|
|
366
|
-
},
|
|
367
|
-
{
|
|
368
|
-
find: /^@slidev\/client\/(.*)/,
|
|
369
|
-
replacement: `${toAtFS(options.clientRoot)}/$1`
|
|
370
|
-
},
|
|
371
|
-
{
|
|
372
|
-
find: /^#slidev\/(.*)/,
|
|
373
|
-
replacement: "/@slidev/$1"
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
find: "vue",
|
|
377
|
-
replacement: await resolveImportPath("vue/dist/vue.esm-bundler.js", true)
|
|
378
|
-
},
|
|
379
|
-
...isInstalledGlobally.value ? await Promise.all(INCLUDE_GLOBAL.map(async (dep) => ({
|
|
380
|
-
find: dep,
|
|
381
|
-
replacement: fileURLToPath2(await resolveClientDep(dep))
|
|
382
|
-
}))) : []
|
|
383
|
-
],
|
|
384
|
-
dedupe: ["vue"]
|
|
385
|
-
},
|
|
386
|
-
optimizeDeps: isInstalledGlobally.value ? {
|
|
387
|
-
exclude: EXCLUDE_GLOBAL,
|
|
388
|
-
include: INCLUDE_GLOBAL
|
|
389
|
-
} : {
|
|
390
|
-
// We need to specify the full deps path for non-hoisted modules
|
|
391
|
-
exclude: EXCLUDE_LOCAL,
|
|
392
|
-
include: INCLUDE_LOCAL
|
|
393
|
-
},
|
|
394
|
-
css: {
|
|
395
|
-
postcss: {
|
|
396
|
-
plugins: [
|
|
397
|
-
await import("postcss-nested").then((r) => (r.default || r)())
|
|
398
|
-
]
|
|
399
|
-
}
|
|
400
|
-
},
|
|
401
|
-
server: {
|
|
402
|
-
fs: {
|
|
403
|
-
strict: true,
|
|
404
|
-
allow: uniq([
|
|
405
|
-
options.userWorkspaceRoot,
|
|
406
|
-
options.clientRoot,
|
|
407
|
-
// Special case for PNPM global installation
|
|
408
|
-
isInstalledGlobally.value ? slash(options.cliRoot).replace(/\/\.pnpm\/.*$/gi, "") : options.cliRoot,
|
|
409
|
-
...options.roots
|
|
410
|
-
])
|
|
411
|
-
}
|
|
412
|
-
},
|
|
413
|
-
publicDir: join3(options.userRoot, "public"),
|
|
414
|
-
build: {
|
|
415
|
-
rollupOptions: {
|
|
416
|
-
output: {
|
|
417
|
-
chunkFileNames(chunkInfo) {
|
|
418
|
-
const DEFAULT = "assets/[name]-[hash].js";
|
|
419
|
-
if (chunkInfo.name.includes("/"))
|
|
420
|
-
return DEFAULT;
|
|
421
|
-
if (chunkInfo.moduleIds.filter((i) => isSlidevClient(i)).length > chunkInfo.moduleIds.length * 0.6)
|
|
422
|
-
return "assets/slidev/[name]-[hash].js";
|
|
423
|
-
if (chunkInfo.moduleIds.filter((i) => i.match(/\/monaco-editor(-core)?\//)).length > chunkInfo.moduleIds.length * 0.6)
|
|
424
|
-
return "assets/monaco/[name]-[hash].js";
|
|
425
|
-
return DEFAULT;
|
|
426
|
-
},
|
|
427
|
-
manualChunks(id) {
|
|
428
|
-
if (id.startsWith("/@slidev-monaco-types/") || id.includes("/@slidev/monaco-types") || id.endsWith("?monaco-types&raw"))
|
|
429
|
-
return "monaco/bundled-types";
|
|
430
|
-
if (id.includes("/shiki/") || id.includes("/@shikijs/"))
|
|
431
|
-
return `modules/shiki`;
|
|
432
|
-
if (id.startsWith("~icons/"))
|
|
433
|
-
return "modules/unplugin-icons";
|
|
434
|
-
const matchedAsyncModule = ASYNC_MODULES.find((i) => id.includes(`/node_modules/${i}`));
|
|
435
|
-
if (matchedAsyncModule)
|
|
436
|
-
return `modules/${matchedAsyncModule.replace("@", "").replace("/", "-")}`;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
},
|
|
441
|
-
cacheDir: isInstalledGlobally.value ? join3(options.cliRoot, "node_modules/.vite") : void 0
|
|
442
|
-
};
|
|
443
|
-
function isSlidevClient(id) {
|
|
444
|
-
return id.includes("/@slidev/") || id.includes("/slidev/packages/client/") || id.includes("/@vueuse/");
|
|
445
|
-
}
|
|
446
|
-
return mergeConfig(injection, config);
|
|
447
|
-
},
|
|
448
|
-
configureServer(server) {
|
|
449
|
-
return () => {
|
|
450
|
-
server.middlewares.use(async (req, res, next) => {
|
|
451
|
-
if (req.url === "/index.html") {
|
|
452
|
-
res.setHeader("Content-Type", "text/html");
|
|
453
|
-
res.statusCode = 200;
|
|
454
|
-
res.end(options.utils.indexHtml);
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
next();
|
|
458
|
-
});
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// node/vite/hmrPatch.ts
|
|
465
|
-
function createHmrPatchPlugin() {
|
|
466
|
-
return {
|
|
467
|
-
name: "slidev:hmr-patch",
|
|
468
|
-
transform(code, id) {
|
|
469
|
-
if (!id.match(regexSlideSourceId))
|
|
470
|
-
return;
|
|
471
|
-
return code.replace("if (_rerender_only)", "if (false)");
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// node/vite/icons.ts
|
|
477
|
-
import Icons from "unplugin-icons/vite";
|
|
478
|
-
function createIconsPlugin(options, pluginOptions) {
|
|
479
|
-
return Icons({
|
|
480
|
-
defaultClass: "slidev-icon",
|
|
481
|
-
collectionsNodeResolvePath: options.utils.iconsResolvePath,
|
|
482
|
-
...pluginOptions.icons
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// node/vite/inspect.ts
|
|
487
|
-
async function createInspectPlugin(options, pluginOptions) {
|
|
488
|
-
if (!options.inspect)
|
|
489
|
-
return;
|
|
490
|
-
const { default: PluginInspect } = await import("vite-plugin-inspect");
|
|
491
|
-
return PluginInspect({
|
|
492
|
-
dev: true,
|
|
493
|
-
build: true,
|
|
494
|
-
...pluginOptions.inspect
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// node/vite/layoutWrapper.ts
|
|
499
|
-
import { bold, gray, red, yellow } from "ansis";
|
|
500
|
-
function createLayoutWrapperPlugin({ data, utils }) {
|
|
501
|
-
return {
|
|
502
|
-
name: "slidev:layout-wrapper",
|
|
503
|
-
async transform(code, id) {
|
|
504
|
-
const match = id.match(regexSlideSourceId);
|
|
505
|
-
if (!match)
|
|
506
|
-
return;
|
|
507
|
-
const [, no, type] = match;
|
|
508
|
-
if (type !== "md")
|
|
509
|
-
return;
|
|
510
|
-
const index = +no - 1;
|
|
511
|
-
const layouts = utils.getLayouts();
|
|
512
|
-
const rawLayoutName = data.slides[index]?.frontmatter?.layout ?? data.slides[0]?.frontmatter?.defaults?.layout;
|
|
513
|
-
let layoutName = rawLayoutName || (index === 0 ? "cover" : "default");
|
|
514
|
-
if (!layouts[layoutName]) {
|
|
515
|
-
console.error(red(`
|
|
516
|
-
Unknown layout "${bold(layoutName)}".${yellow(" Available layouts are:")}`) + Object.keys(layouts).map((i, idx) => (idx % 3 === 0 ? "\n " : "") + gray(i.padEnd(15, " "))).join(" "));
|
|
517
|
-
console.error();
|
|
518
|
-
layoutName = "default";
|
|
519
|
-
}
|
|
520
|
-
const setupTag = code.match(/^<script setup.*>/m);
|
|
521
|
-
if (!setupTag)
|
|
522
|
-
throw new Error(`[Slidev] Internal error: <script setup> block not found in slide ${index + 1}.`);
|
|
523
|
-
const templatePart = code.slice(0, setupTag.index);
|
|
524
|
-
const scriptPart = code.slice(setupTag.index);
|
|
525
|
-
const bodyStart = templatePart.indexOf("<template>") + 10;
|
|
526
|
-
const bodyEnd = templatePart.lastIndexOf("</template>");
|
|
527
|
-
let body = code.slice(bodyStart, bodyEnd).trim();
|
|
528
|
-
if (body.startsWith("<div>") && body.endsWith("</div>"))
|
|
529
|
-
body = body.slice(5, -6);
|
|
530
|
-
return [
|
|
531
|
-
templatePart.slice(0, bodyStart),
|
|
532
|
-
`<InjectedLayout v-bind="_frontmatterToProps($frontmatter,${index})">
|
|
533
|
-
${body}
|
|
534
|
-
</InjectedLayout>`,
|
|
535
|
-
templatePart.slice(bodyEnd),
|
|
536
|
-
scriptPart.slice(0, setupTag[0].length),
|
|
537
|
-
`import InjectedLayout from "${toAtFS(layouts[layoutName])}"`,
|
|
538
|
-
templateImportContextUtils,
|
|
539
|
-
templateInitContext,
|
|
540
|
-
"$clicksContext.setup()",
|
|
541
|
-
templateInjectionMarker,
|
|
542
|
-
scriptPart.slice(setupTag[0].length)
|
|
543
|
-
].join("\n");
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
// node/vite/loaders.ts
|
|
549
|
-
import { notNullish, range } from "@antfu/utils";
|
|
550
|
-
import * as parser2 from "@slidev/parser/fs";
|
|
551
|
-
import equal from "fast-deep-equal";
|
|
552
|
-
import MarkdownIt from "markdown-it";
|
|
553
|
-
import YAML2 from "yaml";
|
|
554
|
-
|
|
555
|
-
// node/syntax/markdown-it/markdown-it-katex.ts
|
|
556
|
-
import katex from "katex";
|
|
557
|
-
function isValidDelim(state, pos) {
|
|
558
|
-
const max = state.posMax;
|
|
559
|
-
let can_open = true;
|
|
560
|
-
let can_close = true;
|
|
561
|
-
const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;
|
|
562
|
-
const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1;
|
|
563
|
-
if (prevChar === 32 || prevChar === 9 || /* \t */
|
|
564
|
-
nextChar >= 48 && nextChar <= 57)
|
|
565
|
-
can_close = false;
|
|
566
|
-
if (nextChar === 32 || nextChar === 9)
|
|
567
|
-
can_open = false;
|
|
568
|
-
return {
|
|
569
|
-
can_open,
|
|
570
|
-
can_close
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
function math_inline(state, silent) {
|
|
574
|
-
let match, token, res, pos;
|
|
575
|
-
if (state.src[state.pos] !== "$")
|
|
576
|
-
return false;
|
|
577
|
-
res = isValidDelim(state, state.pos);
|
|
578
|
-
if (!res.can_open) {
|
|
579
|
-
if (!silent)
|
|
580
|
-
state.pending += "$";
|
|
581
|
-
state.pos += 1;
|
|
582
|
-
return true;
|
|
583
|
-
}
|
|
584
|
-
const start = state.pos + 1;
|
|
585
|
-
match = start;
|
|
586
|
-
while ((match = state.src.indexOf("$", match)) !== -1) {
|
|
587
|
-
pos = match - 1;
|
|
588
|
-
while (state.src[pos] === "\\") pos -= 1;
|
|
589
|
-
if ((match - pos) % 2 === 1)
|
|
590
|
-
break;
|
|
591
|
-
match += 1;
|
|
592
|
-
}
|
|
593
|
-
if (match === -1) {
|
|
594
|
-
if (!silent)
|
|
595
|
-
state.pending += "$";
|
|
596
|
-
state.pos = start;
|
|
597
|
-
return true;
|
|
598
|
-
}
|
|
599
|
-
if (match - start === 0) {
|
|
600
|
-
if (!silent)
|
|
601
|
-
state.pending += "$$";
|
|
602
|
-
state.pos = start + 1;
|
|
603
|
-
return true;
|
|
604
|
-
}
|
|
605
|
-
res = isValidDelim(state, match);
|
|
606
|
-
if (!res.can_close) {
|
|
607
|
-
if (!silent)
|
|
608
|
-
state.pending += "$";
|
|
609
|
-
state.pos = start;
|
|
610
|
-
return true;
|
|
611
|
-
}
|
|
612
|
-
if (!silent) {
|
|
613
|
-
token = state.push("math_inline", "math", 0);
|
|
614
|
-
token.markup = "$";
|
|
615
|
-
token.content = state.src.slice(start, match);
|
|
616
|
-
}
|
|
617
|
-
state.pos = match + 1;
|
|
618
|
-
return true;
|
|
619
|
-
}
|
|
620
|
-
function math_block(state, start, end, silent) {
|
|
621
|
-
let firstLine;
|
|
622
|
-
let lastLine;
|
|
623
|
-
let next;
|
|
624
|
-
let lastPos;
|
|
625
|
-
let found = false;
|
|
626
|
-
let pos = state.bMarks[start] + state.tShift[start];
|
|
627
|
-
let max = state.eMarks[start];
|
|
628
|
-
if (pos + 2 > max)
|
|
629
|
-
return false;
|
|
630
|
-
if (state.src.slice(pos, pos + 2) !== "$$")
|
|
631
|
-
return false;
|
|
632
|
-
pos += 2;
|
|
633
|
-
firstLine = state.src.slice(pos, max);
|
|
634
|
-
if (silent)
|
|
635
|
-
return true;
|
|
636
|
-
if (firstLine.trim().slice(-2) === "$$") {
|
|
637
|
-
firstLine = firstLine.trim().slice(0, -2);
|
|
638
|
-
found = true;
|
|
639
|
-
}
|
|
640
|
-
for (next = start; !found; ) {
|
|
641
|
-
next++;
|
|
642
|
-
if (next >= end)
|
|
643
|
-
break;
|
|
644
|
-
pos = state.bMarks[next] + state.tShift[next];
|
|
645
|
-
max = state.eMarks[next];
|
|
646
|
-
if (pos < max && state.tShift[next] < state.blkIndent) {
|
|
647
|
-
break;
|
|
648
|
-
}
|
|
649
|
-
if (state.src.slice(pos, max).trim().slice(-2) === "$$") {
|
|
650
|
-
lastPos = state.src.slice(0, max).lastIndexOf("$$");
|
|
651
|
-
lastLine = state.src.slice(pos, lastPos);
|
|
652
|
-
found = true;
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
state.line = next + 1;
|
|
656
|
-
const token = state.push("math_block", "math", 0);
|
|
657
|
-
token.block = true;
|
|
658
|
-
token.content = (firstLine && firstLine.trim() ? `${firstLine}
|
|
659
|
-
` : "") + state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : "");
|
|
660
|
-
token.map = [start, state.line];
|
|
661
|
-
token.markup = "$$";
|
|
662
|
-
return true;
|
|
663
|
-
}
|
|
664
|
-
function MarkdownItKatex(md, options) {
|
|
665
|
-
const katexInline = function(latex) {
|
|
666
|
-
options.displayMode = false;
|
|
667
|
-
try {
|
|
668
|
-
return katex.renderToString(latex, options);
|
|
669
|
-
} catch (error) {
|
|
670
|
-
if (options.throwOnError)
|
|
671
|
-
console.warn(error);
|
|
672
|
-
return latex;
|
|
673
|
-
}
|
|
674
|
-
};
|
|
675
|
-
const inlineRenderer = function(tokens, idx) {
|
|
676
|
-
return katexInline(tokens[idx].content);
|
|
677
|
-
};
|
|
678
|
-
const katexBlock = function(latex) {
|
|
679
|
-
options.displayMode = true;
|
|
680
|
-
try {
|
|
681
|
-
return `<p>${katex.renderToString(latex, options)}</p>`;
|
|
682
|
-
} catch (error) {
|
|
683
|
-
if (options.throwOnError)
|
|
684
|
-
console.warn(error);
|
|
685
|
-
return latex;
|
|
686
|
-
}
|
|
687
|
-
};
|
|
688
|
-
const blockRenderer = function(tokens, idx) {
|
|
689
|
-
return `${katexBlock(tokens[idx].content)}
|
|
690
|
-
`;
|
|
691
|
-
};
|
|
692
|
-
md.inline.ruler.after("escape", "math_inline", math_inline);
|
|
693
|
-
md.block.ruler.after("blockquote", "math_block", math_block, {
|
|
694
|
-
alt: ["paragraph", "reference", "blockquote", "list"]
|
|
695
|
-
});
|
|
696
|
-
md.renderer.rules.math_inline = inlineRenderer;
|
|
697
|
-
md.renderer.rules.math_block = blockRenderer;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// node/virtual/configs.ts
|
|
701
|
-
import { isString } from "@antfu/utils";
|
|
702
|
-
var templateConfigs = {
|
|
703
|
-
id: "/@slidev/configs",
|
|
704
|
-
getContent({ data, remote }) {
|
|
705
|
-
const config = {
|
|
706
|
-
...data.config,
|
|
707
|
-
remote,
|
|
708
|
-
slidesTitle: getSlideTitle(data)
|
|
709
|
-
};
|
|
710
|
-
if (isString(config.info))
|
|
711
|
-
config.info = sharedMd.render(config.info);
|
|
712
|
-
return `export default ${JSON.stringify(config)}`;
|
|
713
|
-
}
|
|
714
|
-
};
|
|
715
|
-
|
|
716
|
-
// node/virtual/deprecated.ts
|
|
717
|
-
var templateLegacyRoutes = {
|
|
718
|
-
id: "/@slidev/routes",
|
|
719
|
-
getContent() {
|
|
720
|
-
return [
|
|
721
|
-
`export { slides } from '#slidev/slides'`,
|
|
722
|
-
`console.warn('[slidev] #slidev/routes is deprecated, use #slidev/slides instead')`
|
|
723
|
-
].join("\n");
|
|
724
|
-
}
|
|
725
|
-
};
|
|
726
|
-
var templateLegacyTitles = {
|
|
727
|
-
id: "/@slidev/titles.md",
|
|
728
|
-
getContent() {
|
|
729
|
-
return `
|
|
730
|
-
<script setup lang="ts">
|
|
731
|
-
import TitleRenderer from '#slidev/title-renderer'
|
|
732
|
-
defineProps<{ no: number | string }>()
|
|
733
|
-
console.warn('/@slidev/titles.md is deprecated, import from #slidev/title-renderer instead')
|
|
734
|
-
</script>
|
|
735
|
-
|
|
736
|
-
<TitleRenderer :no="no" />
|
|
737
|
-
`;
|
|
738
|
-
}
|
|
739
|
-
};
|
|
740
|
-
|
|
741
|
-
// node/virtual/global-layers.ts
|
|
742
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
743
|
-
import { join as join4 } from "node:path";
|
|
744
|
-
var templateGlobalLayers = {
|
|
745
|
-
id: `/@slidev/global-layers`,
|
|
746
|
-
getContent({ roots }) {
|
|
747
|
-
const imports = [];
|
|
748
|
-
let n = 0;
|
|
749
|
-
function getComponent(names) {
|
|
750
|
-
const components = roots.flatMap((root) => names.map((name) => join4(root, name))).filter((i) => existsSync2(i));
|
|
751
|
-
imports.push(components.map((path5, i) => `import __n${n}_${i} from '${toAtFS(path5)}'`).join("\n"));
|
|
752
|
-
const render = components.map((_, i) => `h(__n${n}_${i})`).join(",");
|
|
753
|
-
n++;
|
|
754
|
-
return `{ render: () => [${render}] }`;
|
|
755
|
-
}
|
|
756
|
-
const globalTop = getComponent(["global.vue", "global-top.vue", "GlobalTop.vue"]);
|
|
757
|
-
const globalBottom = getComponent(["global-bottom.vue", "GlobalBottom.vue"]);
|
|
758
|
-
const slideTop = getComponent(["slide-top.vue", "SlideTop.vue"]);
|
|
759
|
-
const slideBottom = getComponent(["slide-bottom.vue", "SlideBottom.vue"]);
|
|
760
|
-
return [
|
|
761
|
-
imports.join("\n"),
|
|
762
|
-
`import { h } from 'vue'`,
|
|
763
|
-
`export const GlobalTop = ${globalTop}`,
|
|
764
|
-
`export const GlobalBottom = ${globalBottom}`,
|
|
765
|
-
`export const SlideTop = ${slideTop}`,
|
|
766
|
-
`export const SlideBottom = ${slideBottom}`
|
|
767
|
-
].join("\n");
|
|
768
|
-
}
|
|
769
|
-
};
|
|
770
|
-
|
|
771
|
-
// node/virtual/layouts.ts
|
|
772
|
-
import { objectMap } from "@antfu/utils";
|
|
773
|
-
var templateLayouts = {
|
|
774
|
-
id: "/@slidev/layouts",
|
|
775
|
-
getContent({ utils }) {
|
|
776
|
-
const imports = [];
|
|
777
|
-
const layouts = objectMap(
|
|
778
|
-
utils.getLayouts(),
|
|
779
|
-
(k, v) => {
|
|
780
|
-
imports.push(`import __layout_${k} from "${toAtFS(v)}"`);
|
|
781
|
-
return [k, `__layout_${k}`];
|
|
782
|
-
}
|
|
783
|
-
);
|
|
784
|
-
return [
|
|
785
|
-
imports.join("\n"),
|
|
786
|
-
`export default {
|
|
787
|
-
${Object.entries(layouts).map(([k, v]) => `"${k}": ${v}`).join(",\n")}
|
|
788
|
-
}`
|
|
789
|
-
].join("\n\n");
|
|
790
|
-
}
|
|
791
|
-
};
|
|
792
|
-
|
|
793
|
-
// node/virtual/monaco-deps.ts
|
|
794
|
-
import { resolve as resolve2 } from "node:path";
|
|
795
|
-
import { uniq as uniq2 } from "@antfu/utils";
|
|
796
|
-
var templateMonacoRunDeps = {
|
|
797
|
-
id: "/@slidev/monaco-run-deps",
|
|
798
|
-
async getContent({ userRoot, data }) {
|
|
799
|
-
if (!data.features.monaco)
|
|
800
|
-
return "";
|
|
801
|
-
const deps = uniq2(data.features.monaco.deps.concat(data.config.monacoTypesAdditionalPackages));
|
|
802
|
-
const importerPath = resolve2(userRoot, "./snippets/__importer__.ts");
|
|
803
|
-
let result = "";
|
|
804
|
-
for (let i = 0; i < deps.length; i++) {
|
|
805
|
-
const specifier = deps[i];
|
|
806
|
-
const resolved = await this.resolve(specifier, importerPath);
|
|
807
|
-
if (!resolved)
|
|
808
|
-
continue;
|
|
809
|
-
result += `import * as vendored${i} from ${JSON.stringify(resolved.id)}
|
|
810
|
-
`;
|
|
811
|
-
}
|
|
812
|
-
result += "export default {\n";
|
|
813
|
-
for (let i = 0; i < deps.length; i++)
|
|
814
|
-
result += `${JSON.stringify(deps[i])}: vendored${i},
|
|
815
|
-
`;
|
|
816
|
-
result += "}\n";
|
|
817
|
-
return result;
|
|
818
|
-
}
|
|
819
|
-
};
|
|
820
|
-
|
|
821
|
-
// node/virtual/monaco-types.ts
|
|
822
|
-
import { builtinModules } from "node:module";
|
|
823
|
-
import { join as join5, resolve as resolve3 } from "node:path";
|
|
824
|
-
import { uniq as uniq3 } from "@antfu/utils";
|
|
825
|
-
import fg from "fast-glob";
|
|
826
|
-
var templateMonacoTypes = {
|
|
827
|
-
id: "/@slidev/monaco-types",
|
|
828
|
-
getContent: async ({ userRoot, data, utils }) => {
|
|
829
|
-
if (!data.features.monaco)
|
|
830
|
-
return "";
|
|
831
|
-
const typesRoot = join5(userRoot, "snippets");
|
|
832
|
-
const files = await fg(["**/*.ts", "**/*.mts", "**/*.cts"], { cwd: typesRoot });
|
|
833
|
-
let result = 'import { addFile } from "@slidev/client/setup/monaco.ts"\n';
|
|
834
|
-
for (const file of files) {
|
|
835
|
-
const url = `${toAtFS(resolve3(typesRoot, file))}?monaco-types&raw`;
|
|
836
|
-
result += `addFile(() => import(${JSON.stringify(url)}), ${JSON.stringify(file)})
|
|
837
|
-
`;
|
|
838
|
-
}
|
|
839
|
-
function mapModuleNameToModule(moduleSpecifier) {
|
|
840
|
-
if (moduleSpecifier.startsWith("node:"))
|
|
841
|
-
return "node";
|
|
842
|
-
if (builtinModules.includes(moduleSpecifier))
|
|
843
|
-
return "node";
|
|
844
|
-
const mainPackageName = moduleSpecifier.split("/")[0];
|
|
845
|
-
if (builtinModules.includes(mainPackageName) && !mainPackageName.startsWith("@"))
|
|
846
|
-
return "node";
|
|
847
|
-
const [a = "", b = ""] = moduleSpecifier.split("/");
|
|
848
|
-
const moduleName = a.startsWith("@") ? `${a}/${b}` : a;
|
|
849
|
-
return moduleName;
|
|
850
|
-
}
|
|
851
|
-
let deps = [...data.config.monacoTypesAdditionalPackages];
|
|
852
|
-
if (data.config.monacoTypesSource === "local")
|
|
853
|
-
deps.push(...data.features.monaco.types);
|
|
854
|
-
deps = uniq3(deps.map((specifier) => {
|
|
855
|
-
if (specifier[0] === ".")
|
|
856
|
-
return "";
|
|
857
|
-
return mapModuleNameToModule(specifier);
|
|
858
|
-
}).filter(Boolean));
|
|
859
|
-
deps = deps.filter((pkg) => !utils.isMonacoTypesIgnored(pkg));
|
|
860
|
-
for (const pkg of deps) {
|
|
861
|
-
result += `import(${JSON.stringify(`/@slidev-monaco-types/resolve?${new URLSearchParams({ pkg })}`)})
|
|
862
|
-
`;
|
|
863
|
-
}
|
|
864
|
-
return result;
|
|
865
|
-
}
|
|
866
|
-
};
|
|
867
|
-
|
|
868
|
-
// node/virtual/nav-controls.ts
|
|
869
|
-
import { existsSync as existsSync3 } from "node:fs";
|
|
870
|
-
import { join as join6 } from "node:path";
|
|
871
|
-
var templateNavControls = {
|
|
872
|
-
id: "/@slidev/custom-nav-controls",
|
|
873
|
-
getContent({ roots }) {
|
|
874
|
-
const components = roots.flatMap((root) => {
|
|
875
|
-
return [
|
|
876
|
-
join6(root, "custom-nav-controls.vue"),
|
|
877
|
-
join6(root, "CustomNavControls.vue")
|
|
878
|
-
];
|
|
879
|
-
}).filter((i) => existsSync3(i));
|
|
880
|
-
const imports = components.map((i, idx) => `import __n${idx} from '${toAtFS(i)}'`).join("\n");
|
|
881
|
-
const render = components.map((i, idx) => `h(__n${idx})`).join(",");
|
|
882
|
-
return `${imports}
|
|
883
|
-
import { h } from 'vue'
|
|
884
|
-
export default {
|
|
885
|
-
render: () => [${render}],
|
|
886
|
-
}`;
|
|
887
|
-
}
|
|
888
|
-
};
|
|
889
|
-
|
|
890
|
-
// node/virtual/setups.ts
|
|
891
|
-
import { existsSync as existsSync4 } from "node:fs";
|
|
892
|
-
import { join as join7 } from "node:path";
|
|
893
|
-
function createSetupTemplate(name) {
|
|
894
|
-
return {
|
|
895
|
-
id: `/@slidev/setups/${name}`,
|
|
896
|
-
getContent({ roots }) {
|
|
897
|
-
const setups = roots.flatMap((i) => {
|
|
898
|
-
const path5 = join7(i, "setup", name);
|
|
899
|
-
return [".ts", ".mts", ".js", ".mjs"].map((ext) => path5 + ext);
|
|
900
|
-
}).filter((i) => existsSync4(i));
|
|
901
|
-
const imports = [];
|
|
902
|
-
setups.forEach((path5, idx) => {
|
|
903
|
-
imports.push(`import __n${idx} from '${toAtFS(path5)}'`);
|
|
904
|
-
});
|
|
905
|
-
imports.push(`export default [${setups.map((_, idx) => `__n${idx}`).join(",")}]`);
|
|
906
|
-
return imports.join("\n");
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
var setupModules = ["shiki", "code-runners", "monaco", "mermaid", "main", "root", "routes", "shortcuts", "context-menu"];
|
|
911
|
-
var templateSetups = setupModules.map(createSetupTemplate);
|
|
912
|
-
|
|
913
|
-
// node/virtual/shiki.ts
|
|
914
|
-
import { uniq as uniq4 } from "@antfu/utils";
|
|
915
|
-
var templateShiki = {
|
|
916
|
-
id: "/@slidev/shiki",
|
|
917
|
-
getContent: async ({ utils }) => {
|
|
918
|
-
const options = utils.shikiOptions;
|
|
919
|
-
const langs = await resolveLangs(options.langs || ["markdown", "vue", "javascript", "typescript", "html", "css"]);
|
|
920
|
-
const resolvedThemeOptions = "themes" in options ? {
|
|
921
|
-
themes: Object.fromEntries(await Promise.all(
|
|
922
|
-
Object.entries(options.themes).map(async ([name, value]) => [name, await resolveTheme2(value)])
|
|
923
|
-
))
|
|
924
|
-
} : {
|
|
925
|
-
theme: await resolveTheme2(options.theme || "vitesse-dark")
|
|
926
|
-
};
|
|
927
|
-
const themes = resolvedThemeOptions.themes ? Object.values(resolvedThemeOptions.themes) : [resolvedThemeOptions.theme];
|
|
928
|
-
const themeOptionsNames = resolvedThemeOptions.themes ? { themes: Object.fromEntries(Object.entries(resolvedThemeOptions.themes).map(([name, value]) => [name, typeof value === "string" ? value : value.name])) } : { theme: typeof resolvedThemeOptions.theme === "string" ? resolvedThemeOptions.theme : resolvedThemeOptions.theme.name };
|
|
929
|
-
async function normalizeGetter(p) {
|
|
930
|
-
const r = typeof p === "function" ? p() : p;
|
|
931
|
-
return r.default || r;
|
|
932
|
-
}
|
|
933
|
-
async function resolveLangs(langs2) {
|
|
934
|
-
const awaited = await Promise.all(langs2.map((lang) => normalizeGetter(lang)));
|
|
935
|
-
return uniq4(awaited.flat());
|
|
936
|
-
}
|
|
937
|
-
async function resolveTheme2(theme) {
|
|
938
|
-
return typeof theme === "string" ? theme : await normalizeGetter(theme);
|
|
939
|
-
}
|
|
940
|
-
const langsInit = await Promise.all(
|
|
941
|
-
langs.map(async (lang) => typeof lang === "string" ? `import('${await resolveImportUrl(`shiki/langs/${lang}.mjs`)}')` : JSON.stringify(lang))
|
|
942
|
-
);
|
|
943
|
-
const themesInit = await Promise.all(themes.map(async (theme) => typeof theme === "string" ? `import('${await resolveImportUrl(`shiki/themes/${theme}.mjs`)}')` : JSON.stringify(theme)));
|
|
944
|
-
const langNames = langs.flatMap((lang) => typeof lang === "string" ? lang : lang.name);
|
|
945
|
-
const lines = [];
|
|
946
|
-
lines.push(
|
|
947
|
-
`import { createHighlighterCore } from "${await resolveImportUrl("shiki/core")}"`,
|
|
948
|
-
`import { createJavaScriptRegexEngine } from "${await resolveImportUrl("@shikijs/engine-javascript")}"`,
|
|
949
|
-
`export { shikiToMonaco } from "${await resolveImportUrl("@shikijs/monaco")}"`,
|
|
950
|
-
`export const languages = ${JSON.stringify(langNames)}`,
|
|
951
|
-
`export const themes = ${JSON.stringify(themeOptionsNames.themes || themeOptionsNames.theme)}`,
|
|
952
|
-
"export const shiki = createHighlighterCore({",
|
|
953
|
-
` themes: [${themesInit.join(",")}],`,
|
|
954
|
-
` langs: [${langsInit.join(",")}],`,
|
|
955
|
-
` engine: createJavaScriptRegexEngine(),`,
|
|
956
|
-
"})",
|
|
957
|
-
"let highlight",
|
|
958
|
-
"export async function getHighlighter() {",
|
|
959
|
-
" if (highlight) return highlight",
|
|
960
|
-
" const highlighter = await shiki",
|
|
961
|
-
" highlight = (code, lang, options) => highlighter.codeToHtml(code, {",
|
|
962
|
-
" lang,",
|
|
963
|
-
` theme: ${JSON.stringify(themeOptionsNames.theme)},`,
|
|
964
|
-
` themes: ${JSON.stringify(themeOptionsNames.themes)},`,
|
|
965
|
-
" defaultColor: false,",
|
|
966
|
-
" ...options,",
|
|
967
|
-
" })",
|
|
968
|
-
" return highlight",
|
|
969
|
-
"}"
|
|
970
|
-
);
|
|
971
|
-
return lines.join("\n");
|
|
972
|
-
}
|
|
973
|
-
};
|
|
974
|
-
|
|
975
|
-
// node/virtual/slides.ts
|
|
976
|
-
var VIRTUAL_SLIDE_PREFIX = "/@slidev/slides/";
|
|
977
|
-
var templateSlides = {
|
|
978
|
-
id: "/@slidev/slides",
|
|
979
|
-
getContent({ data, utils }) {
|
|
980
|
-
const layouts = utils.getLayouts();
|
|
981
|
-
const statements = [
|
|
982
|
-
`import { defineAsyncComponent, shallowRef } from 'vue'`,
|
|
983
|
-
`import SlideError from '${layouts.error}'`,
|
|
984
|
-
`import SlideLoading from '@slidev/client/internals/SlideLoading.vue'`,
|
|
985
|
-
`const componentsCache = new Array(${data.slides.length})`,
|
|
986
|
-
`const getAsyncComponent = (idx, loader) => defineAsyncComponent({`,
|
|
987
|
-
` loader,`,
|
|
988
|
-
` delay: 300,`,
|
|
989
|
-
` loadingComponent: SlideLoading,`,
|
|
990
|
-
` errorComponent: SlideError,`,
|
|
991
|
-
` onError: e => console.error('Failed to load slide ' + (idx + 1), e) `,
|
|
992
|
-
`})`
|
|
993
|
-
];
|
|
994
|
-
const slides = data.slides.map((_, idx) => {
|
|
995
|
-
const no = idx + 1;
|
|
996
|
-
statements.push(
|
|
997
|
-
`import { meta as f${no} } from '${VIRTUAL_SLIDE_PREFIX}${no}/frontmatter'`,
|
|
998
|
-
// For some unknown reason, import error won't be caught by the error component. Catch it here.
|
|
999
|
-
`const load${no} = async () => {`,
|
|
1000
|
-
` try { return componentsCache[${idx}] ??= await import('${VIRTUAL_SLIDE_PREFIX}${no}/md') }`,
|
|
1001
|
-
` catch (e) { console.error('slide failed to load', e); return SlideError }`,
|
|
1002
|
-
`}`
|
|
1003
|
-
);
|
|
1004
|
-
return `{ no: ${no}, meta: f${no}, load: load${no}, component: getAsyncComponent(${idx}, load${no}) }`;
|
|
1005
|
-
});
|
|
1006
|
-
return [
|
|
1007
|
-
...statements,
|
|
1008
|
-
`const data = [
|
|
1009
|
-
${slides.join(",\n")}
|
|
1010
|
-
]`,
|
|
1011
|
-
`if (import.meta.hot) {`,
|
|
1012
|
-
` import.meta.hot.data.slides ??= shallowRef()`,
|
|
1013
|
-
` import.meta.hot.data.slides.value = data`,
|
|
1014
|
-
` import.meta.hot.dispose(() => componentsCache.length = 0)`,
|
|
1015
|
-
` import.meta.hot.accept()`,
|
|
1016
|
-
`}`,
|
|
1017
|
-
`export const slides = import.meta.hot ? import.meta.hot.data.slides : shallowRef(data)`
|
|
1018
|
-
].join("\n");
|
|
1019
|
-
}
|
|
1020
|
-
};
|
|
1021
|
-
|
|
1022
|
-
// node/virtual/styles.ts
|
|
1023
|
-
import { existsSync as existsSync5 } from "node:fs";
|
|
1024
|
-
import { join as join8 } from "node:path";
|
|
1025
|
-
var templateStyle = {
|
|
1026
|
-
id: "/@slidev/styles",
|
|
1027
|
-
async getContent({ data, clientRoot, roots }) {
|
|
1028
|
-
function resolveUrlOfClient(name) {
|
|
1029
|
-
return toAtFS(join8(clientRoot, name));
|
|
1030
|
-
}
|
|
1031
|
-
const imports = [
|
|
1032
|
-
`import "${resolveUrlOfClient("styles/vars.css")}"`,
|
|
1033
|
-
`import "${resolveUrlOfClient("styles/index.css")}"`,
|
|
1034
|
-
`import "${resolveUrlOfClient("styles/code.css")}"`,
|
|
1035
|
-
`import "${resolveUrlOfClient("styles/katex.css")}"`,
|
|
1036
|
-
`import "${resolveUrlOfClient("styles/transitions.css")}"`
|
|
1037
|
-
];
|
|
1038
|
-
for (const root of roots) {
|
|
1039
|
-
const styles = [
|
|
1040
|
-
join8(root, "styles", "index.ts"),
|
|
1041
|
-
join8(root, "styles", "index.js"),
|
|
1042
|
-
join8(root, "styles", "index.css"),
|
|
1043
|
-
join8(root, "styles.css"),
|
|
1044
|
-
join8(root, "style.css")
|
|
1045
|
-
];
|
|
1046
|
-
for (const style of styles) {
|
|
1047
|
-
if (existsSync5(style)) {
|
|
1048
|
-
imports.push(`import "${toAtFS(style)}"`);
|
|
1049
|
-
continue;
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
if (data.features.katex)
|
|
1054
|
-
imports.push(`import "${await resolveImportUrl("katex/dist/katex.min.css")}"`);
|
|
1055
|
-
if (data.config.highlighter === "shiki") {
|
|
1056
|
-
imports.push(
|
|
1057
|
-
`import "${await resolveImportUrl("@shikijs/vitepress-twoslash/style.css")}"`,
|
|
1058
|
-
`import "${resolveUrlOfClient("styles/shiki-twoslash.css")}"`,
|
|
1059
|
-
`import "${await resolveImportUrl("shiki-magic-move/style.css")}"`
|
|
1060
|
-
);
|
|
1061
|
-
}
|
|
1062
|
-
imports.unshift(
|
|
1063
|
-
`import "${await resolveImportUrl("@unocss/reset/tailwind.css")}"`,
|
|
1064
|
-
'import "uno:preflights.css"',
|
|
1065
|
-
'import "uno:typography.css"',
|
|
1066
|
-
'import "uno:shortcuts.css"'
|
|
1067
|
-
);
|
|
1068
|
-
imports.push('import "uno.css"');
|
|
1069
|
-
return imports.join("\n");
|
|
1070
|
-
}
|
|
1071
|
-
};
|
|
1072
|
-
|
|
1073
|
-
// node/virtual/titles.ts
|
|
1074
|
-
var templateTitleRendererMd = {
|
|
1075
|
-
id: "/@slidev/title-renderer.md",
|
|
1076
|
-
getContent({ data }) {
|
|
1077
|
-
const lines = data.slides.map(({ title }, i) => `<template ${i === 0 ? "v-if" : "v-else-if"}="no === ${i + 1}">
|
|
1078
|
-
|
|
1079
|
-
${title}
|
|
1080
|
-
|
|
1081
|
-
</template>`);
|
|
1082
|
-
lines.push(
|
|
1083
|
-
`<script setup lang="ts">`,
|
|
1084
|
-
`import { useSlideContext } from '@slidev/client/context.ts'`,
|
|
1085
|
-
`import { computed } from 'vue'`,
|
|
1086
|
-
`const props = defineProps<{ no?: number | string }>()`,
|
|
1087
|
-
`const { $page } = useSlideContext()`,
|
|
1088
|
-
`const no = computed(() => +(props.no ?? $page.value))`,
|
|
1089
|
-
`</script>`
|
|
1090
|
-
);
|
|
1091
|
-
return lines.join("\n");
|
|
1092
|
-
}
|
|
1093
|
-
};
|
|
1094
|
-
var templateTitleRenderer = {
|
|
1095
|
-
id: "/@slidev/title-renderer",
|
|
1096
|
-
async getContent() {
|
|
1097
|
-
return 'export { default } from "/@slidev/title-renderer.md"';
|
|
1098
|
-
}
|
|
1099
|
-
};
|
|
1100
|
-
|
|
1101
|
-
// node/virtual/index.ts
|
|
1102
|
-
var templates = [
|
|
1103
|
-
templateShiki,
|
|
1104
|
-
templateMonacoTypes,
|
|
1105
|
-
templateMonacoRunDeps,
|
|
1106
|
-
templateConfigs,
|
|
1107
|
-
templateStyle,
|
|
1108
|
-
templateGlobalLayers,
|
|
1109
|
-
templateNavControls,
|
|
1110
|
-
templateSlides,
|
|
1111
|
-
templateLayouts,
|
|
1112
|
-
templateTitleRenderer,
|
|
1113
|
-
templateTitleRendererMd,
|
|
1114
|
-
...templateSetups,
|
|
1115
|
-
// Deprecated
|
|
1116
|
-
templateLegacyRoutes,
|
|
1117
|
-
templateLegacyTitles
|
|
1118
|
-
];
|
|
1119
|
-
|
|
1120
|
-
// node/vite/loaders.ts
|
|
1121
|
-
function createSlidesLoader(options, serverOptions) {
|
|
1122
|
-
const { data, mode, utils } = options;
|
|
1123
|
-
const notesMd = MarkdownIt({ html: true });
|
|
1124
|
-
notesMd.use(MarkdownItLink);
|
|
1125
|
-
if (data.features.katex)
|
|
1126
|
-
notesMd.use(MarkdownItKatex, utils.katexOptions);
|
|
1127
|
-
const hmrSlidesIndexes = /* @__PURE__ */ new Set();
|
|
1128
|
-
let server;
|
|
1129
|
-
let skipHmr = null;
|
|
1130
|
-
let sourceIds = resolveSourceIds(data);
|
|
1131
|
-
function resolveSourceIds(data2) {
|
|
1132
|
-
const ids = {
|
|
1133
|
-
md: [],
|
|
1134
|
-
frontmatter: []
|
|
1135
|
-
};
|
|
1136
|
-
for (const type of ["md", "frontmatter"]) {
|
|
1137
|
-
for (let i = 0; i < data2.slides.length; i++) {
|
|
1138
|
-
ids[type].push(`${data2.slides[i].source.filepath}__slidev_${i + 1}.${type}`);
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
return ids;
|
|
1142
|
-
}
|
|
1143
|
-
function updateServerWatcher() {
|
|
1144
|
-
if (!server)
|
|
1145
|
-
return;
|
|
1146
|
-
server.watcher.add(Object.keys(data.watchFiles));
|
|
1147
|
-
}
|
|
1148
|
-
function getFrontmatter(pageNo) {
|
|
1149
|
-
return {
|
|
1150
|
-
...data.headmatter?.defaults || {},
|
|
1151
|
-
...data.slides[pageNo]?.frontmatter || {}
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
1154
|
-
return {
|
|
1155
|
-
name: "slidev:loader",
|
|
1156
|
-
enforce: "pre",
|
|
1157
|
-
configureServer(_server) {
|
|
1158
|
-
server = _server;
|
|
1159
|
-
updateServerWatcher();
|
|
1160
|
-
server.middlewares.use(async (req, res, next) => {
|
|
1161
|
-
const match = req.url?.match(regexSlideReqPath);
|
|
1162
|
-
if (!match)
|
|
1163
|
-
return next();
|
|
1164
|
-
const [, no] = match;
|
|
1165
|
-
const idx = Number.parseInt(no) - 1;
|
|
1166
|
-
if (req.method === "GET") {
|
|
1167
|
-
res.write(JSON.stringify(withRenderedNote(data.slides[idx])));
|
|
1168
|
-
return res.end();
|
|
1169
|
-
} else if (req.method === "POST") {
|
|
1170
|
-
const body = await getBodyJson(req);
|
|
1171
|
-
const slide = data.slides[idx];
|
|
1172
|
-
if (body.content && body.content !== slide.source.content)
|
|
1173
|
-
hmrSlidesIndexes.add(idx);
|
|
1174
|
-
if (body.content)
|
|
1175
|
-
slide.content = slide.source.content = body.content;
|
|
1176
|
-
if (body.frontmatterRaw != null) {
|
|
1177
|
-
if (body.frontmatterRaw.trim() === "") {
|
|
1178
|
-
slide.source.frontmatterDoc = slide.source.frontmatterStyle = void 0;
|
|
1179
|
-
} else {
|
|
1180
|
-
const parsed = YAML2.parseDocument(body.frontmatterRaw);
|
|
1181
|
-
if (parsed.errors.length)
|
|
1182
|
-
console.error("ERROR when saving frontmatter", parsed.errors);
|
|
1183
|
-
else
|
|
1184
|
-
slide.source.frontmatterDoc = parsed;
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
if (body.note)
|
|
1188
|
-
slide.note = slide.source.note = body.note;
|
|
1189
|
-
if (body.frontmatter) {
|
|
1190
|
-
updateFrontmatterPatch(slide.source, body.frontmatter);
|
|
1191
|
-
Object.assign(slide.frontmatter, body.frontmatter);
|
|
1192
|
-
}
|
|
1193
|
-
parser2.prettifySlide(slide.source);
|
|
1194
|
-
const fileContent = await parser2.save(data.markdownFiles[slide.source.filepath]);
|
|
1195
|
-
if (body.skipHmr) {
|
|
1196
|
-
skipHmr = {
|
|
1197
|
-
filePath: slide.source.filepath,
|
|
1198
|
-
fileContent
|
|
1199
|
-
};
|
|
1200
|
-
server?.moduleGraph.invalidateModule(
|
|
1201
|
-
server.moduleGraph.getModuleById(sourceIds.md[idx])
|
|
1202
|
-
);
|
|
1203
|
-
if (body.frontmatter) {
|
|
1204
|
-
server?.moduleGraph.invalidateModule(
|
|
1205
|
-
server.moduleGraph.getModuleById(sourceIds.frontmatter[idx])
|
|
1206
|
-
);
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
res.statusCode = 200;
|
|
1210
|
-
res.write(JSON.stringify(withRenderedNote(slide)));
|
|
1211
|
-
return res.end();
|
|
1212
|
-
}
|
|
1213
|
-
next();
|
|
1214
|
-
});
|
|
1215
|
-
},
|
|
1216
|
-
async handleHotUpdate(ctx) {
|
|
1217
|
-
const forceChangedSlides = data.watchFiles[ctx.file];
|
|
1218
|
-
if (!forceChangedSlides)
|
|
1219
|
-
return;
|
|
1220
|
-
for (const index of forceChangedSlides) {
|
|
1221
|
-
hmrSlidesIndexes.add(index);
|
|
1222
|
-
}
|
|
1223
|
-
const newData = await serverOptions.loadData?.({
|
|
1224
|
-
[ctx.file]: await ctx.read()
|
|
1225
|
-
});
|
|
1226
|
-
if (!newData)
|
|
1227
|
-
return [];
|
|
1228
|
-
if (skipHmr && newData.markdownFiles[skipHmr.filePath]?.raw === skipHmr.fileContent) {
|
|
1229
|
-
skipHmr = null;
|
|
1230
|
-
return [];
|
|
1231
|
-
}
|
|
1232
|
-
const moduleIds = /* @__PURE__ */ new Set();
|
|
1233
|
-
const newSourceIds = resolveSourceIds(newData);
|
|
1234
|
-
for (const type of ["md", "frontmatter"]) {
|
|
1235
|
-
const old = sourceIds[type];
|
|
1236
|
-
const newIds = newSourceIds[type];
|
|
1237
|
-
for (let i = 0; i < newIds.length; i++) {
|
|
1238
|
-
if (old[i] !== newIds[i]) {
|
|
1239
|
-
moduleIds.add(`${VIRTUAL_SLIDE_PREFIX}${i + 1}/${type}`);
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
sourceIds = newSourceIds;
|
|
1244
|
-
if (data.slides.length !== newData.slides.length) {
|
|
1245
|
-
moduleIds.add(templateSlides.id);
|
|
1246
|
-
}
|
|
1247
|
-
if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
|
|
1248
|
-
moduleIds.add(templateSlides.id);
|
|
1249
|
-
range(data.slides.length).map((i) => hmrSlidesIndexes.add(i));
|
|
1250
|
-
}
|
|
1251
|
-
if (!equal(data.config, newData.config))
|
|
1252
|
-
moduleIds.add(templateConfigs.id);
|
|
1253
|
-
if (!equal(data.features, newData.features)) {
|
|
1254
|
-
setTimeout(() => {
|
|
1255
|
-
ctx.server.hot.send({ type: "full-reload" });
|
|
1256
|
-
}, 1);
|
|
1257
|
-
}
|
|
1258
|
-
const length = Math.min(data.slides.length, newData.slides.length);
|
|
1259
|
-
for (let i = 0; i < length; i++) {
|
|
1260
|
-
const a = data.slides[i];
|
|
1261
|
-
const b = newData.slides[i];
|
|
1262
|
-
if (!hmrSlidesIndexes.has(i) && a.content.trim() === b.content.trim() && a.title?.trim() === b.title?.trim() && equal(a.frontmatter, b.frontmatter)) {
|
|
1263
|
-
if (a.note !== b.note) {
|
|
1264
|
-
ctx.server.hot.send(
|
|
1265
|
-
"slidev:update-note",
|
|
1266
|
-
{
|
|
1267
|
-
no: i + 1,
|
|
1268
|
-
note: b.note || "",
|
|
1269
|
-
noteHTML: renderNote(b.note || "")
|
|
1270
|
-
}
|
|
1271
|
-
);
|
|
1272
|
-
}
|
|
1273
|
-
continue;
|
|
1274
|
-
}
|
|
1275
|
-
ctx.server.hot.send(
|
|
1276
|
-
"slidev:update-slide",
|
|
1277
|
-
{
|
|
1278
|
-
no: i + 1,
|
|
1279
|
-
data: withRenderedNote(newData.slides[i])
|
|
1280
|
-
}
|
|
1281
|
-
);
|
|
1282
|
-
hmrSlidesIndexes.add(i);
|
|
1283
|
-
}
|
|
1284
|
-
Object.assign(data, newData);
|
|
1285
|
-
Object.assign(utils, createDataUtils(options));
|
|
1286
|
-
if (hmrSlidesIndexes.size > 0)
|
|
1287
|
-
moduleIds.add(templateTitleRendererMd.id);
|
|
1288
|
-
const vueModules = Array.from(hmrSlidesIndexes).flatMap((idx) => {
|
|
1289
|
-
const frontmatter = ctx.server.moduleGraph.getModuleById(sourceIds.frontmatter[idx]);
|
|
1290
|
-
const main = ctx.server.moduleGraph.getModuleById(sourceIds.md[idx]);
|
|
1291
|
-
const styles = main ? [...main.clientImportedModules].find((m) => m.id?.includes(`&type=style`)) : void 0;
|
|
1292
|
-
return [
|
|
1293
|
-
frontmatter,
|
|
1294
|
-
main,
|
|
1295
|
-
styles
|
|
1296
|
-
];
|
|
1297
|
-
});
|
|
1298
|
-
hmrSlidesIndexes.clear();
|
|
1299
|
-
const moduleEntries = [
|
|
1300
|
-
...ctx.modules.filter((i) => i.id === templateMonacoRunDeps.id || i.id === templateMonacoTypes.id),
|
|
1301
|
-
...vueModules,
|
|
1302
|
-
...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
|
|
1303
|
-
].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
|
|
1304
|
-
updateServerWatcher();
|
|
1305
|
-
return moduleEntries;
|
|
1306
|
-
},
|
|
1307
|
-
resolveId: {
|
|
1308
|
-
order: "pre",
|
|
1309
|
-
handler(id) {
|
|
1310
|
-
if (id.startsWith("/@slidev/") || id.includes("__slidev_"))
|
|
1311
|
-
return id;
|
|
1312
|
-
return null;
|
|
1313
|
-
}
|
|
1314
|
-
},
|
|
1315
|
-
async load(id) {
|
|
1316
|
-
const template = templates.find((i) => i.id === id);
|
|
1317
|
-
if (template) {
|
|
1318
|
-
return {
|
|
1319
|
-
code: await template.getContent.call(this, options),
|
|
1320
|
-
map: { mappings: "" }
|
|
1321
|
-
};
|
|
1322
|
-
}
|
|
1323
|
-
const matchFacade = id.match(regexSlideFacadeId);
|
|
1324
|
-
if (matchFacade) {
|
|
1325
|
-
const [, no, type] = matchFacade;
|
|
1326
|
-
const idx = +no - 1;
|
|
1327
|
-
const sourceId = JSON.stringify(sourceIds[type][idx]);
|
|
1328
|
-
return [
|
|
1329
|
-
`export * from ${sourceId}`,
|
|
1330
|
-
`export { default } from ${sourceId}`
|
|
1331
|
-
].join("\n");
|
|
1332
|
-
}
|
|
1333
|
-
const matchSource = id.match(regexSlideSourceId);
|
|
1334
|
-
if (matchSource) {
|
|
1335
|
-
const [, no, type] = matchSource;
|
|
1336
|
-
const idx = +no - 1;
|
|
1337
|
-
const slide = data.slides[idx];
|
|
1338
|
-
if (!slide)
|
|
1339
|
-
return;
|
|
1340
|
-
if (type === "md") {
|
|
1341
|
-
return {
|
|
1342
|
-
code: slide.content,
|
|
1343
|
-
map: { mappings: "" }
|
|
1344
|
-
};
|
|
1345
|
-
} else if (type === "frontmatter") {
|
|
1346
|
-
const slideBase = {
|
|
1347
|
-
...withRenderedNote(slide),
|
|
1348
|
-
frontmatter: void 0,
|
|
1349
|
-
source: void 0,
|
|
1350
|
-
importChain: void 0,
|
|
1351
|
-
// remove raw content in build, optimize the bundle size
|
|
1352
|
-
...mode === "build" ? { raw: "", content: "", note: "" } : {}
|
|
1353
|
-
};
|
|
1354
|
-
const fontmatter = getFrontmatter(idx);
|
|
1355
|
-
return {
|
|
1356
|
-
code: [
|
|
1357
|
-
"// @unocss-include",
|
|
1358
|
-
'import { computed, reactive, shallowReactive } from "vue"',
|
|
1359
|
-
`export const frontmatterData = ${JSON.stringify(fontmatter)}`,
|
|
1360
|
-
// handle HMR, update frontmatter with update
|
|
1361
|
-
"if (import.meta.hot) {",
|
|
1362
|
-
" const firstLoad = !import.meta.hot.data.frontmatter",
|
|
1363
|
-
" import.meta.hot.data.frontmatter ??= reactive(frontmatterData)",
|
|
1364
|
-
" import.meta.hot.accept(({ frontmatterData: update }) => {",
|
|
1365
|
-
" if (firstLoad) return",
|
|
1366
|
-
" const frontmatter = import.meta.hot.data.frontmatter",
|
|
1367
|
-
" Object.keys(frontmatter).forEach(key => {",
|
|
1368
|
-
" if (!(key in update)) delete frontmatter[key]",
|
|
1369
|
-
" })",
|
|
1370
|
-
" Object.assign(frontmatter, update)",
|
|
1371
|
-
" })",
|
|
1372
|
-
"}",
|
|
1373
|
-
"export const frontmatter = import.meta.hot ? import.meta.hot.data.frontmatter : reactive(frontmatterData)",
|
|
1374
|
-
"export default frontmatter",
|
|
1375
|
-
"export const meta = shallowReactive({",
|
|
1376
|
-
" get layout(){ return frontmatter.layout },",
|
|
1377
|
-
" get transition(){ return frontmatter.transition },",
|
|
1378
|
-
" get class(){ return frontmatter.class },",
|
|
1379
|
-
" get clicks(){ return frontmatter.clicks },",
|
|
1380
|
-
" get name(){ return frontmatter.name },",
|
|
1381
|
-
" get preload(){ return frontmatter.preload },",
|
|
1382
|
-
// No need to be reactive, as it's only used once after reload
|
|
1383
|
-
" slide: {",
|
|
1384
|
-
` ...(${JSON.stringify(slideBase)}),`,
|
|
1385
|
-
` frontmatter,`,
|
|
1386
|
-
` filepath: ${JSON.stringify(mode === "dev" ? slide.source.filepath : "")},`,
|
|
1387
|
-
` start: ${JSON.stringify(slide.source.start)},`,
|
|
1388
|
-
` id: ${idx},`,
|
|
1389
|
-
` no: ${no},`,
|
|
1390
|
-
" },",
|
|
1391
|
-
" __clicksContext: null,",
|
|
1392
|
-
" __preloaded: false,",
|
|
1393
|
-
"})"
|
|
1394
|
-
].join("\n"),
|
|
1395
|
-
map: { mappings: "" }
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
if (data.markdownFiles[id])
|
|
1400
|
-
return "";
|
|
1401
|
-
}
|
|
1402
|
-
};
|
|
1403
|
-
function renderNote(text = "") {
|
|
1404
|
-
let clickCount = 0;
|
|
1405
|
-
const html = notesMd.render(
|
|
1406
|
-
text.replace(/\[click(?::(\d+))?\]/gi, (_, count = 1) => {
|
|
1407
|
-
clickCount += Number(count);
|
|
1408
|
-
return `<span class="slidev-note-click-mark" data-clicks="${clickCount}"></span>`;
|
|
1409
|
-
})
|
|
1410
|
-
);
|
|
1411
|
-
return html;
|
|
1412
|
-
}
|
|
1413
|
-
function withRenderedNote(data2) {
|
|
1414
|
-
return {
|
|
1415
|
-
...data2,
|
|
1416
|
-
noteHTML: renderNote(data2?.note)
|
|
1417
|
-
};
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
// node/vite/markdown.ts
|
|
1422
|
-
import MagicString from "magic-string-stack";
|
|
1423
|
-
import Markdown from "unplugin-vue-markdown/vite";
|
|
1424
|
-
|
|
1425
|
-
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=49e14003b6caa0b7d164cbe71da573809d375bab_d6f3113a192503d8f8553bee4b7feffb/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
|
|
1426
|
-
var SpecialCharacters;
|
|
1427
|
-
(function(SpecialCharacters2) {
|
|
1428
|
-
SpecialCharacters2[SpecialCharacters2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
|
|
1429
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
|
|
1430
|
-
SpecialCharacters2[SpecialCharacters2["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
|
|
1431
|
-
SpecialCharacters2[SpecialCharacters2["WHITESPACE"] = 32] = "WHITESPACE";
|
|
1432
|
-
SpecialCharacters2[SpecialCharacters2["NEW_LINE"] = 10] = "NEW_LINE";
|
|
1433
|
-
SpecialCharacters2[SpecialCharacters2["EQUALS"] = 61] = "EQUALS";
|
|
1434
|
-
SpecialCharacters2[SpecialCharacters2["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
|
|
1435
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
|
|
1436
|
-
SpecialCharacters2[SpecialCharacters2["NUMBER_NINE"] = 57] = "NUMBER_NINE";
|
|
1437
|
-
SpecialCharacters2[SpecialCharacters2["PERCENTAGE"] = 37] = "PERCENTAGE";
|
|
1438
|
-
SpecialCharacters2[SpecialCharacters2["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
|
|
1439
|
-
})(SpecialCharacters || (SpecialCharacters = {}));
|
|
1440
|
-
|
|
1441
|
-
// ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=49e14003b6caa0b7d164cbe71da573809d375bab_d6f3113a192503d8f8553bee4b7feffb/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
|
|
1442
|
-
import Token from "markdown-it/lib/token.mjs";
|
|
1443
|
-
var checkboxRegex = /^ *\[([\sx])] /i;
|
|
1444
|
-
function taskLists(md, options = { enabled: false, label: false, lineNumber: false }) {
|
|
1445
|
-
md.core.ruler.after("inline", "task-lists", (state) => processToken(state, options));
|
|
1446
|
-
md.renderer.rules.taskListItemCheckbox = (tokens) => {
|
|
1447
|
-
const token = tokens[0];
|
|
1448
|
-
const checkedAttribute = token.attrGet("checked") ? 'checked="" ' : "";
|
|
1449
|
-
const disabledAttribute = token.attrGet("disabled") ? 'disabled="" ' : "";
|
|
1450
|
-
const line = token.attrGet("line");
|
|
1451
|
-
const idAttribute = `id="${token.attrGet("id")}" `;
|
|
1452
|
-
const dataLineAttribute = line && options.lineNumber ? `data-line="${line}" ` : "";
|
|
1453
|
-
return `<input class="task-list-item-checkbox" type="checkbox" ${checkedAttribute}${disabledAttribute}${dataLineAttribute}${idAttribute}/>`;
|
|
1454
|
-
};
|
|
1455
|
-
md.renderer.rules.taskListItemLabel_close = () => {
|
|
1456
|
-
return "</label>";
|
|
1457
|
-
};
|
|
1458
|
-
md.renderer.rules.taskListItemLabel_open = (tokens) => {
|
|
1459
|
-
const token = tokens[0];
|
|
1460
|
-
const id = token.attrGet("id");
|
|
1461
|
-
return `<label for="${id}">`;
|
|
1462
|
-
};
|
|
1463
|
-
}
|
|
1464
|
-
function processToken(state, options) {
|
|
1465
|
-
const allTokens = state.tokens;
|
|
1466
|
-
for (let i = 2; i < allTokens.length; i++) {
|
|
1467
|
-
if (!isTodoItem(allTokens, i)) {
|
|
1468
|
-
continue;
|
|
1469
|
-
}
|
|
1470
|
-
todoify(allTokens[i], options);
|
|
1471
|
-
allTokens[i - 2].attrJoin("class", `task-list-item ${options.enabled ? " enabled" : ""}`);
|
|
1472
|
-
const parentToken = findParentToken(allTokens, i - 2);
|
|
1473
|
-
if (parentToken) {
|
|
1474
|
-
const classes = parentToken.attrGet("class") ?? "";
|
|
1475
|
-
if (!classes.match(/(^| )contains-task-list/)) {
|
|
1476
|
-
parentToken.attrJoin("class", "contains-task-list");
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1480
|
-
return false;
|
|
1481
|
-
}
|
|
1482
|
-
function findParentToken(tokens, index) {
|
|
1483
|
-
const targetLevel = tokens[index].level - 1;
|
|
1484
|
-
for (let currentTokenIndex = index - 1; currentTokenIndex >= 0; currentTokenIndex--) {
|
|
1485
|
-
if (tokens[currentTokenIndex].level === targetLevel) {
|
|
1486
|
-
return tokens[currentTokenIndex];
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
return void 0;
|
|
1490
|
-
}
|
|
1491
|
-
function isTodoItem(tokens, index) {
|
|
1492
|
-
return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);
|
|
1493
|
-
}
|
|
1494
|
-
function todoify(token, options) {
|
|
1495
|
-
if (token.children == null) {
|
|
1496
|
-
return;
|
|
1497
|
-
}
|
|
1498
|
-
const id = generateIdForToken(token);
|
|
1499
|
-
token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
|
|
1500
|
-
token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
|
|
1501
|
-
if (options.label) {
|
|
1502
|
-
token.children.splice(1, 0, createLabelBeginToken(id));
|
|
1503
|
-
token.children.push(createLabelEndToken());
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
function generateIdForToken(token) {
|
|
1507
|
-
if (token.map) {
|
|
1508
|
-
return `task-item-${token.map[0]}`;
|
|
1509
|
-
} else {
|
|
1510
|
-
return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
|
|
1511
|
-
}
|
|
1512
|
-
}
|
|
1513
|
-
function createCheckboxToken(token, enabled, id) {
|
|
1514
|
-
const checkbox = new Token("taskListItemCheckbox", "", 0);
|
|
1515
|
-
if (!enabled) {
|
|
1516
|
-
checkbox.attrSet("disabled", "true");
|
|
1517
|
-
}
|
|
1518
|
-
if (token.map) {
|
|
1519
|
-
checkbox.attrSet("line", token.map[0].toString());
|
|
1520
|
-
}
|
|
1521
|
-
checkbox.attrSet("id", id);
|
|
1522
|
-
const checkboxRegexResult = checkboxRegex.exec(token.content);
|
|
1523
|
-
const isChecked = checkboxRegexResult?.[1].toLowerCase() === "x";
|
|
1524
|
-
if (isChecked) {
|
|
1525
|
-
checkbox.attrSet("checked", "true");
|
|
1526
|
-
}
|
|
1527
|
-
return checkbox;
|
|
1528
|
-
}
|
|
1529
|
-
function createLabelBeginToken(id) {
|
|
1530
|
-
const labelBeginToken = new Token("taskListItemLabel_open", "", 1);
|
|
1531
|
-
labelBeginToken.attrSet("id", id);
|
|
1532
|
-
return labelBeginToken;
|
|
1533
|
-
}
|
|
1534
|
-
function createLabelEndToken() {
|
|
1535
|
-
return new Token("taskListItemLabel_close", "", -1);
|
|
1536
|
-
}
|
|
1537
|
-
function isInline(token) {
|
|
1538
|
-
return token.type === "inline";
|
|
1539
|
-
}
|
|
1540
|
-
function isParagraph(token) {
|
|
1541
|
-
return token.type === "paragraph_open";
|
|
1542
|
-
}
|
|
1543
|
-
function isListItem(token) {
|
|
1544
|
-
return token.type === "list_item_open";
|
|
1545
|
-
}
|
|
1546
|
-
function startsWithTodoMarkdown(token) {
|
|
1547
|
-
return checkboxRegex.test(token.content);
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
// node/syntax/markdown-it/index.ts
|
|
1551
|
-
import MarkdownItFootnote from "markdown-it-footnote";
|
|
1552
|
-
import MarkdownItMdc from "markdown-it-mdc";
|
|
1553
|
-
|
|
1554
|
-
// node/syntax/markdown-it/markdown-it-escape-code.ts
|
|
1555
|
-
function MarkdownItEscapeInlineCode(md) {
|
|
1556
|
-
const codeInline = md.renderer.rules.code_inline;
|
|
1557
|
-
md.renderer.rules.code_inline = (tokens, idx, options, env, self) => {
|
|
1558
|
-
const result = codeInline(tokens, idx, options, env, self);
|
|
1559
|
-
return result.replace(/^<code/, "<code v-pre");
|
|
1560
|
-
};
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
// node/syntax/markdown-it/markdown-it-shiki.ts
|
|
1564
|
-
import { isTruthy } from "@antfu/utils";
|
|
1565
|
-
import { fromHighlighter } from "@shikijs/markdown-it/core";
|
|
1566
|
-
|
|
1567
|
-
// node/syntax/transform/utils.ts
|
|
1568
|
-
function normalizeRangeStr(rangeStr = "") {
|
|
1569
|
-
return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1570
|
-
}
|
|
1571
|
-
function getCodeBlocks(md) {
|
|
1572
|
-
const codeblocks = Array.from(md.matchAll(/^```[\s\S]*?^```/gm)).map((m) => {
|
|
1573
|
-
const start = m.index;
|
|
1574
|
-
const end = m.index + m[0].length;
|
|
1575
|
-
const startLine = md.slice(0, start).match(/\n/g)?.length || 0;
|
|
1576
|
-
const endLine = md.slice(0, end).match(/\n/g)?.length || 0;
|
|
1577
|
-
return [start, end, startLine, endLine];
|
|
1578
|
-
});
|
|
1579
|
-
return {
|
|
1580
|
-
codeblocks,
|
|
1581
|
-
isInsideCodeblocks(idx) {
|
|
1582
|
-
return codeblocks.some(([s, e]) => s <= idx && idx <= e);
|
|
1583
|
-
},
|
|
1584
|
-
isLineInsideCodeblocks(line) {
|
|
1585
|
-
return codeblocks.some(([, , s, e]) => s <= line && line <= e);
|
|
1586
|
-
}
|
|
1587
|
-
};
|
|
1588
|
-
}
|
|
1589
|
-
function escapeVueInCode(md) {
|
|
1590
|
-
return md.replace(/\{\{/g, "{{");
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
// node/syntax/markdown-it/markdown-it-shiki.ts
|
|
1594
|
-
async function MarkdownItShiki({ data: { config }, mode, utils }) {
|
|
1595
|
-
const transformers = [
|
|
1596
|
-
...utils.shikiOptions.transformers || [],
|
|
1597
|
-
(config.twoslash === true || config.twoslash === mode) && (await import("@shikijs/vitepress-twoslash")).transformerTwoslash({
|
|
1598
|
-
explicitTrigger: true,
|
|
1599
|
-
twoslashOptions: {
|
|
1600
|
-
handbookOptions: {
|
|
1601
|
-
noErrorValidation: true
|
|
1602
|
-
}
|
|
1603
|
-
}
|
|
1604
|
-
}),
|
|
1605
|
-
{
|
|
1606
|
-
pre(pre) {
|
|
1607
|
-
this.addClassToHast(pre, "slidev-code");
|
|
1608
|
-
delete pre.properties.tabindex;
|
|
1609
|
-
},
|
|
1610
|
-
postprocess(code) {
|
|
1611
|
-
return escapeVueInCode(code);
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
].filter(isTruthy);
|
|
1615
|
-
return fromHighlighter(utils.shiki, {
|
|
1616
|
-
...utils.shikiOptions,
|
|
1617
|
-
transformers
|
|
1618
|
-
});
|
|
1619
|
-
}
|
|
1620
|
-
|
|
1621
|
-
// node/syntax/markdown-it/markdown-it-v-drag.ts
|
|
1622
|
-
import { SourceMapConsumer } from "source-map-js";
|
|
1623
|
-
var dragComponentRegex = /<(v-?drag-?\w*)([\s>])/i;
|
|
1624
|
-
var dragDirectiveRegex = /(?<![</\w])v-drag(=".*?")?/i;
|
|
1625
|
-
function MarkdownItVDrag(md, markdownTransformMap) {
|
|
1626
|
-
const visited = /* @__PURE__ */ new WeakSet();
|
|
1627
|
-
const sourceMapConsumers = /* @__PURE__ */ new WeakMap();
|
|
1628
|
-
function getSourceMapConsumer(id) {
|
|
1629
|
-
const s = markdownTransformMap.get(id);
|
|
1630
|
-
if (!s)
|
|
1631
|
-
return void 0;
|
|
1632
|
-
let smc = sourceMapConsumers.get(s);
|
|
1633
|
-
if (smc)
|
|
1634
|
-
return smc;
|
|
1635
|
-
const sourceMap = s.generateMap();
|
|
1636
|
-
smc = new SourceMapConsumer({
|
|
1637
|
-
...sourceMap,
|
|
1638
|
-
version: sourceMap.version.toString()
|
|
1639
|
-
});
|
|
1640
|
-
sourceMapConsumers.set(s, smc);
|
|
1641
|
-
return smc;
|
|
1642
|
-
}
|
|
1643
|
-
const _parse = md.parse;
|
|
1644
|
-
md.parse = function(src, env) {
|
|
1645
|
-
const smc = getSourceMapConsumer(env.id);
|
|
1646
|
-
const toOriginalPos = smc ? (line) => smc.originalPositionFor({ line: line + 1, column: 0 }).line - 1 : (line) => line;
|
|
1647
|
-
function toMarkdownSource(map, idx) {
|
|
1648
|
-
const start = toOriginalPos(map[0]);
|
|
1649
|
-
const end = toOriginalPos(map[1]);
|
|
1650
|
-
return `[${start},${Math.max(start + 1, end)},${idx}]`;
|
|
1651
|
-
}
|
|
1652
|
-
function replaceChildren(token, regex, replacement) {
|
|
1653
|
-
for (const child of token.children ?? []) {
|
|
1654
|
-
if (child.type === "html_block" || child.type === "html_inline") {
|
|
1655
|
-
child.content = child.content.replace(regex, replacement);
|
|
1656
|
-
}
|
|
1657
|
-
replaceChildren(child, regex, replacement);
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
return _parse.call(this, src, env).map((token) => {
|
|
1661
|
-
if (!["html_block", "html_inline", "inline"].includes(token.type) || !token.content.includes("drag") || visited.has(token))
|
|
1662
|
-
return token;
|
|
1663
|
-
token.content = token.content.replace(dragComponentRegex, (_, tag, space, idx) => {
|
|
1664
|
-
const replacement = `<${tag} :markdownSource="${toMarkdownSource(token.map, idx)}"${space}`;
|
|
1665
|
-
replaceChildren(token, dragComponentRegex, replacement);
|
|
1666
|
-
return replacement;
|
|
1667
|
-
}).replace(dragDirectiveRegex, (_, value, idx) => {
|
|
1668
|
-
const replacement = `v-drag${value ?? ""} :markdownSource="${toMarkdownSource(token.map, idx)}"`;
|
|
1669
|
-
replaceChildren(token, dragDirectiveRegex, replacement);
|
|
1670
|
-
return replacement;
|
|
1671
|
-
});
|
|
1672
|
-
visited.add(token);
|
|
1673
|
-
return token;
|
|
1674
|
-
});
|
|
1675
|
-
};
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
// node/syntax/markdown-it/index.ts
|
|
1679
|
-
async function useMarkdownItPlugins(md, options, markdownTransformMap) {
|
|
1680
|
-
const { data: { features, config }, utils: { katexOptions } } = options;
|
|
1681
|
-
if (config.highlighter === "shiki") {
|
|
1682
|
-
md.use(await MarkdownItShiki(options));
|
|
1683
|
-
}
|
|
1684
|
-
md.use(MarkdownItLink);
|
|
1685
|
-
md.use(MarkdownItEscapeInlineCode);
|
|
1686
|
-
md.use(MarkdownItFootnote);
|
|
1687
|
-
md.use(taskLists, { enabled: true, lineNumber: true, label: true });
|
|
1688
|
-
if (features.katex)
|
|
1689
|
-
md.use(MarkdownItKatex, katexOptions);
|
|
1690
|
-
md.use(MarkdownItVDrag, markdownTransformMap);
|
|
1691
|
-
if (config.mdc)
|
|
1692
|
-
md.use(MarkdownItMdc);
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1695
|
-
// node/setups/load.ts
|
|
1696
|
-
import { existsSync as existsSync6 } from "node:fs";
|
|
1697
|
-
import { resolve as resolve4 } from "node:path";
|
|
1698
|
-
import { deepMergeWithArray } from "@antfu/utils";
|
|
1699
|
-
async function loadSetups(roots, filename, args, extraLoader) {
|
|
1700
|
-
const returns = [];
|
|
1701
|
-
for (const root of roots) {
|
|
1702
|
-
const path5 = resolve4(root, "setup", filename);
|
|
1703
|
-
if (existsSync6(path5)) {
|
|
1704
|
-
const { default: setup } = await loadModule(path5);
|
|
1705
|
-
const ret = await setup(...args);
|
|
1706
|
-
if (ret)
|
|
1707
|
-
returns.push(ret);
|
|
1708
|
-
}
|
|
1709
|
-
if (extraLoader)
|
|
1710
|
-
returns.push(...await extraLoader(root));
|
|
1711
|
-
}
|
|
1712
|
-
return returns;
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
// node/setups/transformers.ts
|
|
1716
|
-
async function setupTransformers(roots) {
|
|
1717
|
-
const returns = await loadSetups(roots, "transformers.ts", []);
|
|
1718
|
-
const result = {
|
|
1719
|
-
pre: [],
|
|
1720
|
-
preCodeblock: [],
|
|
1721
|
-
postCodeblock: [],
|
|
1722
|
-
post: []
|
|
1723
|
-
};
|
|
1724
|
-
for (const r of [...returns].reverse()) {
|
|
1725
|
-
if (r.pre)
|
|
1726
|
-
result.pre.push(...r.pre);
|
|
1727
|
-
if (r.preCodeblock)
|
|
1728
|
-
result.preCodeblock.push(...r.preCodeblock);
|
|
1729
|
-
}
|
|
1730
|
-
for (const r of returns) {
|
|
1731
|
-
if (r.postCodeblock)
|
|
1732
|
-
result.postCodeblock.push(...r.postCodeblock);
|
|
1733
|
-
if (r.post)
|
|
1734
|
-
result.post.push(...r.post);
|
|
1735
|
-
}
|
|
1736
|
-
return result;
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
// node/syntax/transform/code-wrapper.ts
|
|
1740
|
-
var reCodeBlock = /^```([\w'-]+)?\s*(?:\{([\w*,|-]+)\}\s*?(\{[^}]*\})?([^\r\n]*))?\r?\n([ \t]*\S[\s\S]*?)^```$/gm;
|
|
1741
|
-
function transformCodeWrapper(ctx) {
|
|
1742
|
-
ctx.s.replace(
|
|
1743
|
-
reCodeBlock,
|
|
1744
|
-
(full, lang = "", rangeStr = "", options = "", attrs = "", code) => {
|
|
1745
|
-
const ranges = normalizeRangeStr(rangeStr);
|
|
1746
|
-
code = code.trimEnd();
|
|
1747
|
-
options = options.trim() || "{}";
|
|
1748
|
-
return `
|
|
1749
|
-
<CodeBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1750
|
-
|
|
1751
|
-
\`\`\`${lang}${attrs}
|
|
1752
|
-
${code}
|
|
1753
|
-
\`\`\`
|
|
1754
|
-
|
|
1755
|
-
</CodeBlockWrapper>`;
|
|
1756
|
-
}
|
|
1757
|
-
);
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
// node/syntax/transform/in-page-css.ts
|
|
1761
|
-
function transformPageCSS(ctx) {
|
|
1762
|
-
const codeBlocks = getCodeBlocks(ctx.s.original);
|
|
1763
|
-
ctx.s.replace(
|
|
1764
|
-
/(\n<style[^>]*>)([\s\S]+?)(<\/style>)/g,
|
|
1765
|
-
(full, start, css, end, index) => {
|
|
1766
|
-
if (codeBlocks.isInsideCodeblocks(index))
|
|
1767
|
-
return full;
|
|
1768
|
-
if (!start.includes("scoped"))
|
|
1769
|
-
start = start.replace("<style", "<style scoped");
|
|
1770
|
-
return `${start}
|
|
1771
|
-
${css}${end}`;
|
|
1772
|
-
}
|
|
1773
|
-
);
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
// node/syntax/transform/katex-wrapper.ts
|
|
1777
|
-
function transformKaTexWrapper(ctx) {
|
|
1778
|
-
ctx.s.replace(
|
|
1779
|
-
/^\$\$(?:\s*\{([\w*,|-]+)\}\s*?(?:(\{[^}]*\})\s*?)?)?\n(\S[\s\S]*?)^\$\$/gm,
|
|
1780
|
-
(full, rangeStr = "", options = "", code) => {
|
|
1781
|
-
const ranges = !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
|
|
1782
|
-
code = code.trimEnd();
|
|
1783
|
-
options = options.trim() || "{}";
|
|
1784
|
-
return `<KaTexBlockWrapper v-bind="${options}" :ranges='${JSON.stringify(ranges)}'>
|
|
1785
|
-
|
|
1786
|
-
$$
|
|
1787
|
-
${code}
|
|
1788
|
-
$$
|
|
1789
|
-
</KaTexBlockWrapper>
|
|
1790
|
-
`;
|
|
1791
|
-
}
|
|
1792
|
-
);
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1795
|
-
// node/syntax/transform/magic-move.ts
|
|
1796
|
-
import lz from "lz-string";
|
|
1797
|
-
import { codeToKeyedTokens } from "shiki-magic-move/core";
|
|
1798
|
-
var reMagicMoveBlock = /^````(?:md|markdown) magic-move *(\{[^}]*\})?([^ \n]*)\n([\s\S]+?)^````$/gm;
|
|
1799
|
-
function parseLineNumbersOption(options) {
|
|
1800
|
-
return /lines: *true/.test(options) ? true : /lines: *false/.test(options) ? false : void 0;
|
|
1801
|
-
}
|
|
1802
|
-
function transformMagicMove(ctx) {
|
|
1803
|
-
ctx.s.replace(
|
|
1804
|
-
reMagicMoveBlock,
|
|
1805
|
-
(full, options = "{}", _attrs = "", body) => {
|
|
1806
|
-
const matches = Array.from(body.matchAll(reCodeBlock));
|
|
1807
|
-
if (!matches.length)
|
|
1808
|
-
throw new Error("Magic Move block must contain at least one code block");
|
|
1809
|
-
const defaultLineNumbers = parseLineNumbersOption(options) ?? ctx.options.data.config.lineNumbers;
|
|
1810
|
-
const ranges = matches.map((i) => normalizeRangeStr(i[2]));
|
|
1811
|
-
const steps = matches.map((i) => {
|
|
1812
|
-
const lineNumbers = parseLineNumbersOption(i[3]) ?? defaultLineNumbers;
|
|
1813
|
-
return codeToKeyedTokens(ctx.options.utils.shiki, i[5].trimEnd(), {
|
|
1814
|
-
...ctx.options.utils.shikiOptions,
|
|
1815
|
-
lang: i[1]
|
|
1816
|
-
}, lineNumbers);
|
|
1817
|
-
});
|
|
1818
|
-
const compressed = lz.compressToBase64(JSON.stringify(steps));
|
|
1819
|
-
return `<ShikiMagicMove v-bind="${options}" steps-lz="${compressed}" :step-ranges='${JSON.stringify(ranges)}' />`;
|
|
1820
|
-
}
|
|
1821
|
-
);
|
|
1822
|
-
}
|
|
1823
|
-
|
|
1824
|
-
// node/syntax/transform/mermaid.ts
|
|
1825
|
-
import lz2 from "lz-string";
|
|
1826
|
-
function transformMermaid(ctx) {
|
|
1827
|
-
ctx.s.replace(
|
|
1828
|
-
/^```mermaid *(\{[^\n]*\})?\n([\s\S]+?)\n```/gm,
|
|
1829
|
-
(full, options = "", code = "") => {
|
|
1830
|
-
code = code.trim();
|
|
1831
|
-
options = options.trim() || "{}";
|
|
1832
|
-
const encoded = lz2.compressToBase64(code);
|
|
1833
|
-
return `<Mermaid code-lz="${encoded}" v-bind="${options}" />`;
|
|
1834
|
-
}
|
|
1835
|
-
);
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
// node/syntax/transform/monaco.ts
|
|
1839
|
-
import lz3 from "lz-string";
|
|
1840
|
-
function transformMonaco(ctx) {
|
|
1841
|
-
const enabled = ctx.options.data.config.monaco === true || ctx.options.data.config.monaco === ctx.options.mode;
|
|
1842
|
-
if (!enabled) {
|
|
1843
|
-
ctx.s.replace(/\{monaco([\w:,-]*)\}/g, "");
|
|
1844
|
-
return;
|
|
1845
|
-
}
|
|
1846
|
-
ctx.s.replace(
|
|
1847
|
-
/^```(\w+) *\{monaco-diff\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^~~~ *\n([\s\S]+?)^```/gm,
|
|
1848
|
-
(full, lang = "ts", options = "{}", code, diff) => {
|
|
1849
|
-
lang = lang.trim();
|
|
1850
|
-
options = options.trim() || "{}";
|
|
1851
|
-
const encoded = lz3.compressToBase64(code);
|
|
1852
|
-
const encodedDiff = lz3.compressToBase64(diff);
|
|
1853
|
-
return `<Monaco code-lz="${encoded}" diff-lz="${encodedDiff}" lang="${lang}" v-bind="${options}" />`;
|
|
1854
|
-
}
|
|
1855
|
-
);
|
|
1856
|
-
ctx.s.replace(
|
|
1857
|
-
/^```(\w+) *\{monaco\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^```/gm,
|
|
1858
|
-
(full, lang = "ts", options = "{}", code) => {
|
|
1859
|
-
lang = lang.trim();
|
|
1860
|
-
options = options.trim() || "{}";
|
|
1861
|
-
const encoded = lz3.compressToBase64(code);
|
|
1862
|
-
return `<Monaco code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
1863
|
-
}
|
|
1864
|
-
);
|
|
1865
|
-
ctx.s.replace(
|
|
1866
|
-
/^```(\w+) *\{monaco-run\} *(?:(\{[^\n]*\}) *)?\n([\s\S]+?)^```/gm,
|
|
1867
|
-
(full, lang = "ts", options = "{}", code) => {
|
|
1868
|
-
lang = lang.trim();
|
|
1869
|
-
options = options.trim() || "{}";
|
|
1870
|
-
const encoded = lz3.compressToBase64(code);
|
|
1871
|
-
return `<Monaco runnable code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
|
|
1872
|
-
}
|
|
1873
|
-
);
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
// node/syntax/transform/plant-uml.ts
|
|
1877
|
-
import { encode as encodePlantUml } from "plantuml-encoder";
|
|
1878
|
-
function transformPlantUml(ctx) {
|
|
1879
|
-
const server = ctx.options.data.config.plantUmlServer;
|
|
1880
|
-
ctx.s.replace(
|
|
1881
|
-
/^```plantuml[^\n{}]*(\{[^}\n]*\})?\n([\s\S]+?)\n```/gm,
|
|
1882
|
-
(full, options = "", content = "") => {
|
|
1883
|
-
const code = encodePlantUml(content.trim());
|
|
1884
|
-
options = options.trim() || "{}";
|
|
1885
|
-
return `<PlantUml :code="'${code}'" :server="'${server}'" v-bind="${options}" />`;
|
|
1886
|
-
}
|
|
1887
|
-
);
|
|
1888
|
-
}
|
|
1889
|
-
|
|
1890
|
-
// node/syntax/transform/slot-sugar.ts
|
|
1891
|
-
function transformSlotSugar(ctx) {
|
|
1892
|
-
const linesWithNewline = ctx.s.original.split(/(\r?\n)/g);
|
|
1893
|
-
const codeBlocks = getCodeBlocks(ctx.s.original);
|
|
1894
|
-
const lines = [];
|
|
1895
|
-
for (let i = 0; i < linesWithNewline.length; i += 2) {
|
|
1896
|
-
const line = linesWithNewline[i];
|
|
1897
|
-
const newline = linesWithNewline[i + 1] || "";
|
|
1898
|
-
lines.push(line + newline);
|
|
1899
|
-
}
|
|
1900
|
-
let prevSlot = false;
|
|
1901
|
-
let offset = 0;
|
|
1902
|
-
lines.forEach((line) => {
|
|
1903
|
-
const start = offset;
|
|
1904
|
-
offset += line.length;
|
|
1905
|
-
if (codeBlocks.isInsideCodeblocks(offset))
|
|
1906
|
-
return;
|
|
1907
|
-
const match = line.match(/^::\s*([\w.\-:]+)\s*::(\s*)$/);
|
|
1908
|
-
if (match) {
|
|
1909
|
-
ctx.s.overwrite(start, offset - match[2].length, `${prevSlot ? "\n\n</template>\n" : "\n"}<template v-slot:${match[1]}="slotProps">
|
|
1910
|
-
`);
|
|
1911
|
-
prevSlot = true;
|
|
1912
|
-
}
|
|
1913
|
-
});
|
|
1914
|
-
if (prevSlot)
|
|
1915
|
-
ctx.s.append("\n\n</template>");
|
|
1916
|
-
}
|
|
1917
|
-
|
|
1918
|
-
// node/syntax/transform/snippet.ts
|
|
1919
|
-
import fs4 from "node:fs";
|
|
1920
|
-
import path2 from "node:path";
|
|
1921
|
-
import { slash as slash2 } from "@antfu/utils";
|
|
1922
|
-
import lz4 from "lz-string";
|
|
1923
|
-
|
|
1924
|
-
// node/vite/monacoWrite.ts
|
|
1925
|
-
import fs3 from "node:fs/promises";
|
|
1926
|
-
import path from "node:path";
|
|
1927
|
-
var monacoWriterWhitelist = /* @__PURE__ */ new Set();
|
|
1928
|
-
function createMonacoWriterPlugin({ userRoot }) {
|
|
1929
|
-
return {
|
|
1930
|
-
name: "slidev:monaco-write",
|
|
1931
|
-
apply: "serve",
|
|
1932
|
-
configureServer(server) {
|
|
1933
|
-
server.ws.on("connection", (socket) => {
|
|
1934
|
-
socket.on("message", async (data) => {
|
|
1935
|
-
let json;
|
|
1936
|
-
try {
|
|
1937
|
-
json = JSON.parse(data.toString());
|
|
1938
|
-
} catch {
|
|
1939
|
-
return;
|
|
1940
|
-
}
|
|
1941
|
-
if (json.type === "custom" && json.event === "slidev:monaco-write") {
|
|
1942
|
-
const { file, content } = json.data;
|
|
1943
|
-
if (!monacoWriterWhitelist.has(file)) {
|
|
1944
|
-
console.error(`[Slidev] Unauthorized file write: ${file}`);
|
|
1945
|
-
return;
|
|
1946
|
-
}
|
|
1947
|
-
const filepath = path.join(userRoot, file);
|
|
1948
|
-
console.log("[Slidev] Writing file:", filepath);
|
|
1949
|
-
await fs3.writeFile(filepath, content, "utf-8");
|
|
1950
|
-
}
|
|
1951
|
-
});
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
};
|
|
1955
|
-
}
|
|
1956
|
-
|
|
1957
|
-
// node/syntax/transform/snippet.ts
|
|
1958
|
-
function dedent(text) {
|
|
1959
|
-
const lines = text.split("\n");
|
|
1960
|
-
const minIndentLength = lines.reduce((acc, line) => {
|
|
1961
|
-
for (let i = 0; i < line.length; i++) {
|
|
1962
|
-
if (line[i] !== " " && line[i] !== " ")
|
|
1963
|
-
return Math.min(i, acc);
|
|
1964
|
-
}
|
|
1965
|
-
return acc;
|
|
1966
|
-
}, Number.POSITIVE_INFINITY);
|
|
1967
|
-
if (minIndentLength < Number.POSITIVE_INFINITY)
|
|
1968
|
-
return lines.map((x) => x.slice(minIndentLength)).join("\n");
|
|
1969
|
-
return text;
|
|
1970
|
-
}
|
|
1971
|
-
function findRegion(lines, regionName) {
|
|
1972
|
-
const regionRegexps = [
|
|
1973
|
-
// javascript, typescript, java
|
|
1974
|
-
[/^\/\/ ?#?region ([\w*-]+)$/, /^\/\/ ?#?endregion/],
|
|
1975
|
-
// css, less, scss
|
|
1976
|
-
[/^\/\* ?#region ([\w*-]+) ?\*\/$/, /^\/\* ?#endregion[\s\w*-]*\*\/$/],
|
|
1977
|
-
// C, C++
|
|
1978
|
-
[/^#pragma region ([\w*-]+)$/, /^#pragma endregion/],
|
|
1979
|
-
// HTML, markdown
|
|
1980
|
-
[/^<!-- #?region ([\w*-]+) -->$/, /^<!-- #?region[\s\w*-]*-->$/],
|
|
1981
|
-
// Visual Basic
|
|
1982
|
-
[/^#Region ([\w*-]+)$/, /^#End Region/],
|
|
1983
|
-
// Bat
|
|
1984
|
-
[/^::#region ([\w*-]+)$/, /^::#endregion/],
|
|
1985
|
-
// C#, PHP, Powershell, Python, perl & misc
|
|
1986
|
-
[/^# ?region ([\w*-]+)$/, /^# ?endregion/]
|
|
1987
|
-
];
|
|
1988
|
-
let endReg = null;
|
|
1989
|
-
let start = -1;
|
|
1990
|
-
for (const [lineId, line] of lines.entries()) {
|
|
1991
|
-
if (endReg === null) {
|
|
1992
|
-
for (const [startReg, end] of regionRegexps) {
|
|
1993
|
-
const match = line.trim().match(startReg);
|
|
1994
|
-
if (match && match[1] === regionName) {
|
|
1995
|
-
start = lineId + 1;
|
|
1996
|
-
endReg = end;
|
|
1997
|
-
break;
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
|
-
} else if (endReg.test(line.trim())) {
|
|
2001
|
-
return {
|
|
2002
|
-
start,
|
|
2003
|
-
end: lineId,
|
|
2004
|
-
regexp: endReg
|
|
2005
|
-
};
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
return null;
|
|
2009
|
-
}
|
|
2010
|
-
var reMonacoWrite = /^\{monaco-write\}/;
|
|
2011
|
-
function transformSnippet({ s, slide, options }) {
|
|
2012
|
-
const watchFiles = options.data.watchFiles;
|
|
2013
|
-
const dir = path2.dirname(slide.source?.filepath ?? options.entry ?? options.userRoot);
|
|
2014
|
-
s.replace(
|
|
2015
|
-
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
2016
|
-
/^<<<\s*(\S.*?)(#[\w-]+)?\s*(?:\s(\S+?))?\s*(\{.*)?$/gm,
|
|
2017
|
-
(full, filepath = "", regionName = "", lang = "", meta = "") => {
|
|
2018
|
-
const src = slash2(
|
|
2019
|
-
/^@\//.test(filepath) ? path2.resolve(options.userRoot, filepath.slice(2)) : path2.resolve(dir, filepath)
|
|
2020
|
-
);
|
|
2021
|
-
meta = meta.trim();
|
|
2022
|
-
lang = lang.trim();
|
|
2023
|
-
lang = lang || path2.extname(filepath).slice(1);
|
|
2024
|
-
const isAFile = fs4.statSync(src).isFile();
|
|
2025
|
-
if (!fs4.existsSync(src) || !isAFile) {
|
|
2026
|
-
throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
|
|
2027
|
-
}
|
|
2028
|
-
let content = fs4.readFileSync(src, "utf8");
|
|
2029
|
-
if (regionName) {
|
|
2030
|
-
const lines = content.split(/\r?\n/);
|
|
2031
|
-
const region = findRegion(lines, regionName.slice(1));
|
|
2032
|
-
if (region) {
|
|
2033
|
-
content = dedent(
|
|
2034
|
-
lines.slice(region.start, region.end).filter((line) => !region.regexp.test(line.trim())).join("\n")
|
|
2035
|
-
);
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
if (meta.match(reMonacoWrite)) {
|
|
2039
|
-
monacoWriterWhitelist.add(filepath);
|
|
2040
|
-
lang = lang.trim();
|
|
2041
|
-
meta = meta.replace(reMonacoWrite, "").trim() || "{}";
|
|
2042
|
-
const encoded = lz4.compressToBase64(content);
|
|
2043
|
-
return `<Monaco writable=${JSON.stringify(filepath)} code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />`;
|
|
2044
|
-
} else {
|
|
2045
|
-
watchFiles[src] ??= /* @__PURE__ */ new Set();
|
|
2046
|
-
watchFiles[src].add(slide.index);
|
|
2047
|
-
}
|
|
2048
|
-
return `\`\`\`${lang} ${meta}
|
|
2049
|
-
${content}
|
|
2050
|
-
\`\`\``;
|
|
2051
|
-
}
|
|
2052
|
-
);
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
|
-
// node/syntax/transform/index.ts
|
|
2056
|
-
async function getMarkdownTransformers(options) {
|
|
2057
|
-
const extras = await setupTransformers(options.roots);
|
|
2058
|
-
return [
|
|
2059
|
-
...extras.pre,
|
|
2060
|
-
transformSnippet,
|
|
2061
|
-
options.data.config.highlighter === "shiki" && transformMagicMove,
|
|
2062
|
-
...extras.preCodeblock,
|
|
2063
|
-
transformMermaid,
|
|
2064
|
-
transformPlantUml,
|
|
2065
|
-
options.data.features.monaco && transformMonaco,
|
|
2066
|
-
...extras.postCodeblock,
|
|
2067
|
-
transformCodeWrapper,
|
|
2068
|
-
options.data.features.katex && transformKaTexWrapper,
|
|
2069
|
-
transformPageCSS,
|
|
2070
|
-
transformSlotSugar,
|
|
2071
|
-
...extras.post
|
|
2072
|
-
];
|
|
2073
|
-
}
|
|
2074
|
-
|
|
2075
|
-
// node/vite/markdown.ts
|
|
2076
|
-
async function createMarkdownPlugin(options, { markdown: mdOptions }) {
|
|
2077
|
-
const markdownTransformMap = /* @__PURE__ */ new Map();
|
|
2078
|
-
const transformers = await getMarkdownTransformers(options);
|
|
2079
|
-
return Markdown({
|
|
2080
|
-
include: [/\.md$/],
|
|
2081
|
-
wrapperClasses: "",
|
|
2082
|
-
headEnabled: false,
|
|
2083
|
-
frontmatter: false,
|
|
2084
|
-
escapeCodeTagInterpolation: false,
|
|
2085
|
-
markdownItOptions: {
|
|
2086
|
-
quotes: `""''`,
|
|
2087
|
-
html: true,
|
|
2088
|
-
xhtmlOut: true,
|
|
2089
|
-
linkify: true,
|
|
2090
|
-
...mdOptions?.markdownItOptions
|
|
2091
|
-
},
|
|
2092
|
-
...mdOptions,
|
|
2093
|
-
async markdownItSetup(md) {
|
|
2094
|
-
await useMarkdownItPlugins(md, options, markdownTransformMap);
|
|
2095
|
-
await mdOptions?.markdownItSetup?.(md);
|
|
2096
|
-
},
|
|
2097
|
-
transforms: {
|
|
2098
|
-
...mdOptions?.transforms,
|
|
2099
|
-
async before(code, id) {
|
|
2100
|
-
if (options.data.markdownFiles[id])
|
|
2101
|
-
return "";
|
|
2102
|
-
code = await mdOptions?.transforms?.before?.(code, id) ?? code;
|
|
2103
|
-
const match = id.match(regexSlideSourceId);
|
|
2104
|
-
if (!match)
|
|
2105
|
-
return code;
|
|
2106
|
-
const s = new MagicString(code);
|
|
2107
|
-
markdownTransformMap.set(id, s);
|
|
2108
|
-
const ctx = {
|
|
2109
|
-
s,
|
|
2110
|
-
slide: options.data.slides[+match[1] - 1],
|
|
2111
|
-
options
|
|
2112
|
-
};
|
|
2113
|
-
for (const transformer of transformers) {
|
|
2114
|
-
if (!transformer)
|
|
2115
|
-
continue;
|
|
2116
|
-
await transformer(ctx);
|
|
2117
|
-
if (!ctx.s.isEmpty())
|
|
2118
|
-
ctx.s.commit();
|
|
2119
|
-
}
|
|
2120
|
-
return s.toString();
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
});
|
|
2124
|
-
}
|
|
2125
|
-
|
|
2126
|
-
// node/vite/monacoTypes.ts
|
|
2127
|
-
import fs5 from "node:fs/promises";
|
|
2128
|
-
import { dirname, resolve as resolve5 } from "node:path";
|
|
2129
|
-
import { slash as slash3 } from "@antfu/utils";
|
|
2130
|
-
import fg2 from "fast-glob";
|
|
2131
|
-
import { findDepPkgJsonPath } from "vitefu";
|
|
2132
|
-
function createMonacoTypesLoader({ userRoot, utils }) {
|
|
2133
|
-
return {
|
|
2134
|
-
name: "slidev:monaco-types-loader",
|
|
2135
|
-
resolveId(id) {
|
|
2136
|
-
if (id.startsWith("/@slidev-monaco-types/"))
|
|
2137
|
-
return id;
|
|
2138
|
-
return null;
|
|
2139
|
-
},
|
|
2140
|
-
async load(id) {
|
|
2141
|
-
if (!id.startsWith("/@slidev-monaco-types/"))
|
|
2142
|
-
return null;
|
|
2143
|
-
const url = new URL(id, "http://localhost");
|
|
2144
|
-
if (url.pathname === "/@slidev-monaco-types/resolve") {
|
|
2145
|
-
const query = new URLSearchParams(url.search);
|
|
2146
|
-
const pkg = query.get("pkg");
|
|
2147
|
-
const importer = query.get("importer") ?? userRoot;
|
|
2148
|
-
const pkgJsonPath = await findDepPkgJsonPath(pkg, importer);
|
|
2149
|
-
if (!pkgJsonPath)
|
|
2150
|
-
throw new Error(`Package "${pkg}" not found in "${importer}"`);
|
|
2151
|
-
const root = slash3(dirname(pkgJsonPath));
|
|
2152
|
-
const pkgJson = JSON.parse(await fs5.readFile(pkgJsonPath, "utf-8"));
|
|
2153
|
-
let deps = Object.keys(pkgJson.dependencies ?? {});
|
|
2154
|
-
deps = deps.filter((pkg2) => !utils.isMonacoTypesIgnored(pkg2));
|
|
2155
|
-
return [
|
|
2156
|
-
`import "/@slidev-monaco-types/load?${new URLSearchParams({ root, name: pkgJson.name })}"`,
|
|
2157
|
-
...deps.map((dep) => `import "/@slidev-monaco-types/resolve?${new URLSearchParams({ pkg: dep, importer: root })}"`)
|
|
2158
|
-
].join("\n");
|
|
2159
|
-
}
|
|
2160
|
-
if (url.pathname === "/@slidev-monaco-types/load") {
|
|
2161
|
-
const query = new URLSearchParams(url.search);
|
|
2162
|
-
const root = query.get("root");
|
|
2163
|
-
const name = query.get("name");
|
|
2164
|
-
const files = await fg2(
|
|
2165
|
-
[
|
|
2166
|
-
"**/*.ts",
|
|
2167
|
-
"**/*.mts",
|
|
2168
|
-
"**/*.cts",
|
|
2169
|
-
"package.json"
|
|
2170
|
-
],
|
|
2171
|
-
{
|
|
2172
|
-
cwd: root,
|
|
2173
|
-
followSymbolicLinks: true,
|
|
2174
|
-
ignore: ["**/node_modules/**"]
|
|
2175
|
-
}
|
|
2176
|
-
);
|
|
2177
|
-
if (!files.length)
|
|
2178
|
-
return "/** No files found **/";
|
|
2179
|
-
return [
|
|
2180
|
-
'import { addFile } from "@slidev/client/setup/monaco.ts"',
|
|
2181
|
-
...files.map((file) => `addFile(() => import(${JSON.stringify(`${toAtFS(resolve5(root, file))}?monaco-types&raw`)}), ${JSON.stringify(`node_modules/${name}/${file}`)})`)
|
|
2182
|
-
].join("\n");
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
};
|
|
2186
|
-
}
|
|
2187
|
-
|
|
2188
|
-
// node/vite/remoteAssets.ts
|
|
2189
|
-
async function createRemoteAssetsPlugin({ data: { config }, mode }, pluginOptions) {
|
|
2190
|
-
if (!(config.remoteAssets === true || config.remoteAssets === mode))
|
|
2191
|
-
return;
|
|
2192
|
-
const { VitePluginRemoteAssets, DefaultRules } = await import("vite-plugin-remote-assets");
|
|
2193
|
-
return VitePluginRemoteAssets({
|
|
2194
|
-
resolveMode: (id) => id.endsWith("index.html") ? "relative" : "@fs",
|
|
2195
|
-
awaitDownload: mode === "build",
|
|
2196
|
-
...pluginOptions.remoteAssets,
|
|
2197
|
-
rules: [
|
|
2198
|
-
...DefaultRules,
|
|
2199
|
-
{
|
|
2200
|
-
match: /\b(https?:\/\/image.unsplash\.com.*?)(?=[`'")\]])/gi,
|
|
2201
|
-
ext: ".png"
|
|
2202
|
-
},
|
|
2203
|
-
...pluginOptions.remoteAssets?.rules ?? []
|
|
2204
|
-
]
|
|
2205
|
-
});
|
|
2206
|
-
}
|
|
2207
|
-
|
|
2208
|
-
// node/vite/serverRef.ts
|
|
2209
|
-
import ServerRef from "vite-plugin-vue-server-ref";
|
|
2210
|
-
|
|
2211
|
-
// node/integrations/drawings.ts
|
|
2212
|
-
import { existsSync as existsSync7 } from "node:fs";
|
|
2213
|
-
import fs6 from "node:fs/promises";
|
|
2214
|
-
import { basename, dirname as dirname2, join as join9, resolve as resolve6 } from "node:path";
|
|
2215
|
-
import fg3 from "fast-glob";
|
|
2216
|
-
function resolveDrawingsDir(options) {
|
|
2217
|
-
return options.data.config.drawings.persist ? resolve6(
|
|
2218
|
-
dirname2(options.entry),
|
|
2219
|
-
options.data.config.drawings.persist
|
|
2220
|
-
) : void 0;
|
|
2221
|
-
}
|
|
2222
|
-
async function loadDrawings(options) {
|
|
2223
|
-
const dir = resolveDrawingsDir(options);
|
|
2224
|
-
if (!dir || !existsSync7(dir))
|
|
2225
|
-
return {};
|
|
2226
|
-
const files = await fg3("*.svg", {
|
|
2227
|
-
onlyFiles: true,
|
|
2228
|
-
cwd: dir,
|
|
2229
|
-
absolute: true,
|
|
2230
|
-
suppressErrors: true
|
|
2231
|
-
});
|
|
2232
|
-
const obj = {};
|
|
2233
|
-
await Promise.all(files.map(async (path5) => {
|
|
2234
|
-
const num = +basename(path5, ".svg");
|
|
2235
|
-
if (Number.isNaN(num))
|
|
2236
|
-
return;
|
|
2237
|
-
const content = await fs6.readFile(path5, "utf8");
|
|
2238
|
-
const lines = content.split(/\n/g);
|
|
2239
|
-
obj[num.toString()] = lines.slice(1, -1).join("\n");
|
|
2240
|
-
}));
|
|
2241
|
-
return obj;
|
|
2242
|
-
}
|
|
2243
|
-
async function writeDrawings(options, drawing) {
|
|
2244
|
-
const dir = resolveDrawingsDir(options);
|
|
2245
|
-
if (!dir)
|
|
2246
|
-
return;
|
|
2247
|
-
const width = options.data.config.canvasWidth;
|
|
2248
|
-
const height = Math.round(width / options.data.config.aspectRatio);
|
|
2249
|
-
const SVG_HEAD = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">`;
|
|
2250
|
-
await fs6.mkdir(dir, { recursive: true });
|
|
2251
|
-
return Promise.all(
|
|
2252
|
-
Object.entries(drawing).map(async ([key, value]) => {
|
|
2253
|
-
if (!value)
|
|
2254
|
-
return;
|
|
2255
|
-
const svg = `${SVG_HEAD}
|
|
2256
|
-
${value}
|
|
2257
|
-
</svg>`;
|
|
2258
|
-
await fs6.writeFile(join9(dir, `${key}.svg`), svg, "utf-8");
|
|
2259
|
-
})
|
|
2260
|
-
);
|
|
2261
|
-
}
|
|
2262
|
-
|
|
2263
|
-
// node/integrations/snapshots.ts
|
|
2264
|
-
import { existsSync as existsSync8 } from "node:fs";
|
|
2265
|
-
import fs7 from "node:fs/promises";
|
|
2266
|
-
import { dirname as dirname3, join as join10, resolve as resolve7 } from "node:path";
|
|
2267
|
-
function resolveSnapshotsDir(options) {
|
|
2268
|
-
return resolve7(dirname3(options.entry), ".slidev/snapshots");
|
|
2269
|
-
}
|
|
2270
|
-
async function loadSnapshots(options) {
|
|
2271
|
-
const dir = resolveSnapshotsDir(options);
|
|
2272
|
-
const file = join10(dir, "snapshots.json");
|
|
2273
|
-
if (!dir || !existsSync8(file))
|
|
2274
|
-
return {};
|
|
2275
|
-
return JSON.parse(await fs7.readFile(file, "utf8"));
|
|
2276
|
-
}
|
|
2277
|
-
async function writeSnapshots(options, data) {
|
|
2278
|
-
const dir = resolveSnapshotsDir(options);
|
|
2279
|
-
if (!dir)
|
|
2280
|
-
return;
|
|
2281
|
-
await fs7.mkdir(dir, { recursive: true });
|
|
2282
|
-
await fs7.writeFile(join10(dir, "snapshots.json"), JSON.stringify(data, null, 2), "utf-8");
|
|
2283
|
-
}
|
|
2284
|
-
|
|
2285
|
-
// node/vite/serverRef.ts
|
|
2286
|
-
async function createServerRefPlugin(options, pluginOptions) {
|
|
2287
|
-
return ServerRef({
|
|
2288
|
-
debug: false,
|
|
2289
|
-
// process.env.NODE_ENV === 'development',
|
|
2290
|
-
state: {
|
|
2291
|
-
sync: false,
|
|
2292
|
-
nav: {
|
|
2293
|
-
page: 0,
|
|
2294
|
-
clicks: 0
|
|
2295
|
-
},
|
|
2296
|
-
drawings: await loadDrawings(options),
|
|
2297
|
-
snapshots: await loadSnapshots(options),
|
|
2298
|
-
...pluginOptions.serverRef?.state
|
|
2299
|
-
},
|
|
2300
|
-
onChanged(key, data, patch, timestamp) {
|
|
2301
|
-
pluginOptions.serverRef?.onChanged?.(key, data, patch, timestamp);
|
|
2302
|
-
if (options.data.config.drawings.persist && key === "drawings")
|
|
2303
|
-
writeDrawings(options, patch ?? data);
|
|
2304
|
-
if (key === "snapshots")
|
|
2305
|
-
writeSnapshots(options, data);
|
|
2306
|
-
}
|
|
2307
|
-
});
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
// node/vite/staticCopy.ts
|
|
2311
|
-
import { existsSync as existsSync9 } from "node:fs";
|
|
2312
|
-
import { join as join11 } from "node:path";
|
|
2313
|
-
async function createStaticCopyPlugin({ themeRoots, addonRoots }, pluginOptions) {
|
|
2314
|
-
const publicDirs = [...themeRoots, ...addonRoots].map((i) => join11(i, "public")).filter(existsSync9);
|
|
2315
|
-
if (!publicDirs.length)
|
|
2316
|
-
return;
|
|
2317
|
-
const { viteStaticCopy } = await import("vite-plugin-static-copy");
|
|
2318
|
-
return viteStaticCopy({
|
|
2319
|
-
silent: true,
|
|
2320
|
-
targets: publicDirs.map((dir) => ({
|
|
2321
|
-
src: `${dir}/*`,
|
|
2322
|
-
dest: "theme"
|
|
2323
|
-
})),
|
|
2324
|
-
...pluginOptions.staticCopy
|
|
2325
|
-
});
|
|
2326
|
-
}
|
|
2327
|
-
|
|
2328
|
-
// node/vite/unocss.ts
|
|
2329
|
-
import UnoCSS from "unocss/vite";
|
|
2330
|
-
|
|
2331
|
-
// node/setups/unocss.ts
|
|
2332
|
-
import { existsSync as existsSync10, readFileSync } from "node:fs";
|
|
2333
|
-
import { resolve as resolve8 } from "node:path";
|
|
2334
|
-
import { mergeConfigs, presetIcons } from "unocss";
|
|
2335
|
-
async function setupUnocss({ clientRoot, roots, data, utils }) {
|
|
2336
|
-
async function loadFileConfigs(root) {
|
|
2337
|
-
return (await Promise.all([
|
|
2338
|
-
resolve8(root, "uno.config.ts"),
|
|
2339
|
-
resolve8(root, "unocss.config.ts")
|
|
2340
|
-
].map(async (i) => {
|
|
2341
|
-
if (!existsSync10(i))
|
|
2342
|
-
return void 0;
|
|
2343
|
-
const loaded = await loadModule(i);
|
|
2344
|
-
return "default" in loaded ? loaded.default : loaded;
|
|
2345
|
-
}))).filter((x) => !!x);
|
|
2346
|
-
}
|
|
2347
|
-
const configs = [
|
|
2348
|
-
{
|
|
2349
|
-
presets: [
|
|
2350
|
-
presetIcons({
|
|
2351
|
-
collectionsNodeResolvePath: utils.iconsResolvePath,
|
|
2352
|
-
collections: {
|
|
2353
|
-
slidev: {
|
|
2354
|
-
logo: () => readFileSync(resolve8(clientRoot, "assets/logo.svg"), "utf-8")
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
})
|
|
2358
|
-
]
|
|
2359
|
-
},
|
|
2360
|
-
...await loadFileConfigs(clientRoot),
|
|
2361
|
-
...await loadSetups(roots, "unocss.ts", [], loadFileConfigs)
|
|
2362
|
-
].filter(Boolean);
|
|
2363
|
-
const config = mergeConfigs(configs);
|
|
2364
|
-
config.theme ||= {};
|
|
2365
|
-
config.theme.fontFamily ||= {};
|
|
2366
|
-
config.theme.fontFamily.sans ||= data.config.fonts.sans.join(",");
|
|
2367
|
-
config.theme.fontFamily.mono ||= data.config.fonts.mono.join(",");
|
|
2368
|
-
config.theme.fontFamily.serif ||= data.config.fonts.serif.join(",");
|
|
2369
|
-
return config;
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
// node/vite/unocss.ts
|
|
2373
|
-
async function createUnocssPlugin(options, pluginOptions) {
|
|
2374
|
-
return UnoCSS({
|
|
2375
|
-
configFile: false,
|
|
2376
|
-
...await setupUnocss(options),
|
|
2377
|
-
...pluginOptions.unocss
|
|
2378
|
-
});
|
|
2379
|
-
}
|
|
2380
|
-
|
|
2381
|
-
// node/vite/userPlugins.ts
|
|
2382
|
-
import { existsSync as existsSync11 } from "node:fs";
|
|
2383
|
-
import path3 from "node:path";
|
|
2384
|
-
async function createUserVitePlugins(options) {
|
|
2385
|
-
const createPluginTasks = options.roots.map(async (root) => {
|
|
2386
|
-
const modulePath = path3.join(root, "setup", "vite-plugins.ts");
|
|
2387
|
-
if (existsSync11(modulePath)) {
|
|
2388
|
-
const module = await loadModule(modulePath);
|
|
2389
|
-
return module.default(options);
|
|
2390
|
-
}
|
|
2391
|
-
return [];
|
|
2392
|
-
});
|
|
2393
|
-
return (await Promise.all(createPluginTasks)).flatMap((p) => p);
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2396
|
-
// node/vite/vue.ts
|
|
2397
|
-
import Vue from "@vitejs/plugin-vue";
|
|
2398
|
-
import VueJsx from "@vitejs/plugin-vue-jsx";
|
|
2399
|
-
var customElements = /* @__PURE__ */ new Set([
|
|
2400
|
-
// katex
|
|
2401
|
-
"annotation",
|
|
2402
|
-
"math",
|
|
2403
|
-
"menclose",
|
|
2404
|
-
"mfrac",
|
|
2405
|
-
"mglyph",
|
|
2406
|
-
"mi",
|
|
2407
|
-
"mlabeledtr",
|
|
2408
|
-
"mn",
|
|
2409
|
-
"mo",
|
|
2410
|
-
"mover",
|
|
2411
|
-
"mpadded",
|
|
2412
|
-
"mphantom",
|
|
2413
|
-
"mroot",
|
|
2414
|
-
"mrow",
|
|
2415
|
-
"mspace",
|
|
2416
|
-
"msqrt",
|
|
2417
|
-
"mstyle",
|
|
2418
|
-
"msub",
|
|
2419
|
-
"msubsup",
|
|
2420
|
-
"msup",
|
|
2421
|
-
"mtable",
|
|
2422
|
-
"mtd",
|
|
2423
|
-
"mtext",
|
|
2424
|
-
"mtr",
|
|
2425
|
-
"munder",
|
|
2426
|
-
"munderover",
|
|
2427
|
-
"semantics"
|
|
2428
|
-
]);
|
|
2429
|
-
async function createVuePlugin(_options, pluginOptions) {
|
|
2430
|
-
const {
|
|
2431
|
-
vue: vueOptions = {},
|
|
2432
|
-
vuejsx: vuejsxOptions = {}
|
|
2433
|
-
} = pluginOptions;
|
|
2434
|
-
const VuePlugin = Vue({
|
|
2435
|
-
include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
|
|
2436
|
-
exclude: [],
|
|
2437
|
-
...vueOptions,
|
|
2438
|
-
template: {
|
|
2439
|
-
...vueOptions?.template,
|
|
2440
|
-
compilerOptions: {
|
|
2441
|
-
...vueOptions?.template?.compilerOptions,
|
|
2442
|
-
isCustomElement(tag) {
|
|
2443
|
-
return customElements.has(tag) || vueOptions?.template?.compilerOptions?.isCustomElement?.(tag);
|
|
2444
|
-
}
|
|
2445
|
-
}
|
|
2446
|
-
}
|
|
2447
|
-
});
|
|
2448
|
-
const VueJsxPlugin = VueJsx(vuejsxOptions);
|
|
2449
|
-
return [
|
|
2450
|
-
VueJsxPlugin,
|
|
2451
|
-
VuePlugin
|
|
2452
|
-
];
|
|
2453
|
-
}
|
|
2454
|
-
|
|
2455
|
-
// node/vite/index.ts
|
|
2456
|
-
function ViteSlidevPlugin(options, pluginOptions = {}, serverOptions = {}) {
|
|
2457
|
-
return Promise.all([
|
|
2458
|
-
createSlidesLoader(options, serverOptions),
|
|
2459
|
-
createMarkdownPlugin(options, pluginOptions),
|
|
2460
|
-
createLayoutWrapperPlugin(options),
|
|
2461
|
-
createContextInjectionPlugin(),
|
|
2462
|
-
createVuePlugin(options, pluginOptions),
|
|
2463
|
-
createHmrPatchPlugin(),
|
|
2464
|
-
createComponentsPlugin(options, pluginOptions),
|
|
2465
|
-
createIconsPlugin(options, pluginOptions),
|
|
2466
|
-
createRemoteAssetsPlugin(options, pluginOptions),
|
|
2467
|
-
createServerRefPlugin(options, pluginOptions),
|
|
2468
|
-
createConfigPlugin(options),
|
|
2469
|
-
createMonacoTypesLoader(options),
|
|
2470
|
-
createMonacoWriterPlugin(options),
|
|
2471
|
-
createVueCompilerFlagsPlugin(options),
|
|
2472
|
-
createUnocssPlugin(options, pluginOptions),
|
|
2473
|
-
createStaticCopyPlugin(options, pluginOptions),
|
|
2474
|
-
createInspectPlugin(options, pluginOptions),
|
|
2475
|
-
createUserVitePlugins(options)
|
|
2476
|
-
]);
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
// node/commands/shared.ts
|
|
2480
|
-
var sharedMd = MarkdownIt2({ html: true });
|
|
2481
|
-
sharedMd.use(MarkdownItLink);
|
|
2482
|
-
function getSlideTitle(data) {
|
|
2483
|
-
const tokens = sharedMd.parseInline(data.config.title, {});
|
|
2484
|
-
const title = stringifyMarkdownTokens(tokens);
|
|
2485
|
-
const slideTitle = data.config.titleTemplate.replace("%s", title);
|
|
2486
|
-
return slideTitle === "Slidev - Slidev" ? "Slidev" : slideTitle;
|
|
2487
|
-
}
|
|
2488
|
-
async function resolveViteConfigs(options, baseConfig, overrideConfigs, command, serverOptions) {
|
|
2489
|
-
const configEnv = {
|
|
2490
|
-
mode: command === "build" ? "production" : "development",
|
|
2491
|
-
command
|
|
2492
|
-
};
|
|
2493
|
-
const files = options.roots.map((i) => join12(i, "vite.config.ts"));
|
|
2494
|
-
for (const file of files) {
|
|
2495
|
-
if (!existsSync12(file))
|
|
2496
|
-
continue;
|
|
2497
|
-
const viteConfig = await loadConfigFromFile(configEnv, file);
|
|
2498
|
-
if (!viteConfig?.config)
|
|
2499
|
-
continue;
|
|
2500
|
-
baseConfig = mergeConfig2(baseConfig, viteConfig.config);
|
|
2501
|
-
}
|
|
2502
|
-
baseConfig = mergeConfig2(baseConfig, overrideConfigs);
|
|
2503
|
-
baseConfig = mergeConfig2(baseConfig, {
|
|
2504
|
-
configFile: false,
|
|
2505
|
-
root: options.userRoot,
|
|
2506
|
-
plugins: await ViteSlidevPlugin(options, baseConfig.slidev, serverOptions),
|
|
2507
|
-
define: {
|
|
2508
|
-
// Fixes Vue production mode breaking PDF Export #1245
|
|
2509
|
-
__VUE_PROD_DEVTOOLS__: false
|
|
2510
|
-
}
|
|
2511
|
-
});
|
|
2512
|
-
return baseConfig;
|
|
2513
|
-
}
|
|
2514
|
-
|
|
2515
|
-
// node/setups/indexHtml.ts
|
|
2516
|
-
function toAttrValue(unsafe) {
|
|
2517
|
-
return JSON.stringify(escapeHtml(String(unsafe)));
|
|
2518
|
-
}
|
|
2519
|
-
async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data, base }) {
|
|
2520
|
-
let main = readFileSync2(join13(clientRoot, "index.html"), "utf-8");
|
|
2521
|
-
let body = "";
|
|
2522
|
-
const inputs = [];
|
|
2523
|
-
for (const root of roots) {
|
|
2524
|
-
const path5 = join13(root, "index.html");
|
|
2525
|
-
if (!existsSync13(path5))
|
|
2526
|
-
continue;
|
|
2527
|
-
const html2 = readFileSync2(path5, "utf-8");
|
|
2528
|
-
if (root === userRoot && html2.includes("<!DOCTYPE")) {
|
|
2529
|
-
console.error(yellow2(`[Slidev] Ignored provided index.html with doctype declaration. (${white(path5)})`));
|
|
2530
|
-
console.error(yellow2("This file may be generated by Slidev, please remove it from your project."));
|
|
2531
|
-
continue;
|
|
2532
|
-
}
|
|
2533
|
-
inputs.push(extractUnheadInputFromHtml(html2).input);
|
|
2534
|
-
body += `
|
|
2535
|
-
${(html2.match(/<body>([\s\S]*?)<\/body>/i)?.[1] || "").trim()}`;
|
|
2536
|
-
}
|
|
2537
|
-
if (data.features.tweet) {
|
|
2538
|
-
body += '\n<script async src="https://platform.twitter.com/widgets.js"></script>';
|
|
2539
|
-
}
|
|
2540
|
-
const webFontsLink = [];
|
|
2541
|
-
if (data.config.fonts.webfonts.length) {
|
|
2542
|
-
const { provider } = data.config.fonts;
|
|
2543
|
-
if (provider === "google") {
|
|
2544
|
-
webFontsLink.push({ rel: "stylesheet", href: generateGoogleFontsUrl(data.config.fonts), type: "text/css" });
|
|
2545
|
-
} else if (provider === "coollabs") {
|
|
2546
|
-
webFontsLink.push({ rel: "stylesheet", href: generateCoollabsFontsUrl(data.config.fonts), type: "text/css" });
|
|
2547
|
-
}
|
|
2548
|
-
}
|
|
2549
|
-
const { info, author, keywords } = data.headmatter;
|
|
2550
|
-
const seoMeta = data.headmatter.seoMeta ?? {};
|
|
2551
|
-
const title = getSlideTitle(data);
|
|
2552
|
-
const description = info ? toAttrValue(info) : null;
|
|
2553
|
-
const unhead = createHead({
|
|
2554
|
-
init: [
|
|
2555
|
-
{
|
|
2556
|
-
htmlAttrs: data.headmatter.lang ? { lang: data.headmatter.lang } : void 0,
|
|
2557
|
-
title,
|
|
2558
|
-
link: [
|
|
2559
|
-
data.config.favicon ? { rel: "icon", href: data.config.favicon } : null,
|
|
2560
|
-
...webFontsLink
|
|
2561
|
-
].filter((x) => x),
|
|
2562
|
-
meta: [
|
|
2563
|
-
{ property: "slidev:version", content: version },
|
|
2564
|
-
{ charset: "slidev:entry", content: mode === "dev" && slash4(entry) },
|
|
2565
|
-
{ name: "description", content: description },
|
|
2566
|
-
{ name: "author", content: author ? toAttrValue(author) : null },
|
|
2567
|
-
{ name: "keywords", content: keywords ? toAttrValue(Array.isArray(keywords) ? keywords.join(", ") : keywords) : null },
|
|
2568
|
-
{ property: "og:title", content: seoMeta.ogTitle || title },
|
|
2569
|
-
{ property: "og:description", content: seoMeta.ogDescription || description },
|
|
2570
|
-
{ property: "og:image", content: seoMeta.ogImage },
|
|
2571
|
-
{ property: "og:url", content: seoMeta.ogUrl },
|
|
2572
|
-
{ property: "twitter:card", content: seoMeta.twitterCard },
|
|
2573
|
-
{ property: "twitter:site", content: seoMeta.twitterSite },
|
|
2574
|
-
{ property: "twitter:title", content: seoMeta.twitterTitle },
|
|
2575
|
-
{ property: "twitter:description", content: seoMeta.twitterDescription },
|
|
2576
|
-
{ property: "twitter:image", content: seoMeta.twitterImage },
|
|
2577
|
-
{ property: "twitter:url", content: seoMeta.twitterUrl }
|
|
2578
|
-
].filter((x) => x.content)
|
|
2579
|
-
},
|
|
2580
|
-
...inputs
|
|
2581
|
-
]
|
|
2582
|
-
});
|
|
2583
|
-
const baseInDev = mode === "dev" && base ? base.slice(0, -1) : "";
|
|
2584
|
-
main = main.replace("__ENTRY__", baseInDev + toAtFS(join13(clientRoot, "main.ts"))).replace("<!-- body -->", body);
|
|
2585
|
-
const html = await transformHtmlTemplate(unhead, main);
|
|
2586
|
-
return html;
|
|
2587
|
-
}
|
|
2588
|
-
|
|
2589
|
-
// node/setups/katex.ts
|
|
2590
|
-
async function setupKatex(roots) {
|
|
2591
|
-
const options = await loadSetups(roots, "katex.ts", []);
|
|
2592
|
-
return Object.assign(
|
|
2593
|
-
{ strict: false },
|
|
2594
|
-
...options
|
|
2595
|
-
);
|
|
2596
|
-
}
|
|
2597
|
-
|
|
2598
|
-
// node/setups/shiki.ts
|
|
2599
|
-
import fs8 from "node:fs/promises";
|
|
2600
|
-
import { bundledLanguages, createHighlighter } from "shiki";
|
|
2601
|
-
var cachedRoots;
|
|
2602
|
-
var cachedShiki;
|
|
2603
|
-
async function setupShiki(roots) {
|
|
2604
|
-
if (cachedRoots === roots)
|
|
2605
|
-
return cachedShiki;
|
|
2606
|
-
cachedShiki?.shiki.dispose();
|
|
2607
|
-
const options = await loadSetups(
|
|
2608
|
-
roots,
|
|
2609
|
-
"shiki.ts",
|
|
2610
|
-
[{
|
|
2611
|
-
/** @deprecated */
|
|
2612
|
-
async loadTheme(path5) {
|
|
2613
|
-
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.");
|
|
2614
|
-
return JSON.parse(await fs8.readFile(path5, "utf-8"));
|
|
2615
|
-
}
|
|
2616
|
-
}]
|
|
2617
|
-
);
|
|
2618
|
-
const mergedOptions = Object.assign({}, ...options);
|
|
2619
|
-
if ("theme" in mergedOptions && "themes" in mergedOptions)
|
|
2620
|
-
delete mergedOptions.theme;
|
|
2621
|
-
if (mergedOptions.theme && typeof mergedOptions.theme !== "string" && !mergedOptions.theme.name && !mergedOptions.theme.tokenColors) {
|
|
2622
|
-
mergedOptions.themes = mergedOptions.theme;
|
|
2623
|
-
delete mergedOptions.theme;
|
|
2624
|
-
}
|
|
2625
|
-
if (!mergedOptions.theme && !mergedOptions.themes) {
|
|
2626
|
-
mergedOptions.themes = {
|
|
2627
|
-
dark: "vitesse-dark",
|
|
2628
|
-
light: "vitesse-light"
|
|
2629
|
-
};
|
|
2630
|
-
}
|
|
2631
|
-
if (mergedOptions.themes)
|
|
2632
|
-
mergedOptions.defaultColor = false;
|
|
2633
|
-
const shiki = await createHighlighter({
|
|
2634
|
-
...mergedOptions,
|
|
2635
|
-
langs: mergedOptions.langs ?? Object.keys(bundledLanguages),
|
|
2636
|
-
themes: "themes" in mergedOptions ? Object.values(mergedOptions.themes) : [mergedOptions.theme]
|
|
2637
|
-
});
|
|
2638
|
-
cachedRoots = roots;
|
|
2639
|
-
return cachedShiki = {
|
|
2640
|
-
shiki,
|
|
2641
|
-
shikiOptions: mergedOptions
|
|
2642
|
-
};
|
|
2643
|
-
}
|
|
2644
|
-
|
|
2645
|
-
// node/options.ts
|
|
2646
|
-
var debug = Debug("slidev:options");
|
|
2647
|
-
async function resolveOptions(entryOptions, mode) {
|
|
2648
|
-
const entry = await resolveEntry(entryOptions.entry);
|
|
2649
|
-
const rootsInfo = await getRoots(entry);
|
|
2650
|
-
const loaded = await parser.load(rootsInfo.userRoot, entry, void 0, mode);
|
|
2651
|
-
let themeRaw = entryOptions.theme || loaded.headmatter.theme;
|
|
2652
|
-
themeRaw = themeRaw === null ? "none" : themeRaw || "default";
|
|
2653
|
-
const [theme, themeRoot] = await resolveTheme(themeRaw, entry);
|
|
2654
|
-
const themeRoots = themeRoot ? [themeRoot] : [];
|
|
2655
|
-
const themeMeta = themeRoot ? await getThemeMeta(theme, themeRoot) : void 0;
|
|
2656
|
-
const config = parser.resolveConfig(loaded.headmatter, themeMeta, entryOptions.entry);
|
|
2657
|
-
const addonRoots = await resolveAddons(config.addons);
|
|
2658
|
-
const roots = uniq5([...themeRoots, ...addonRoots, rootsInfo.userRoot]);
|
|
2659
|
-
if (entryOptions.download)
|
|
2660
|
-
config.download ||= entryOptions.download;
|
|
2661
|
-
debug({
|
|
2662
|
-
...rootsInfo,
|
|
2663
|
-
...entryOptions,
|
|
2664
|
-
config,
|
|
2665
|
-
mode,
|
|
2666
|
-
entry,
|
|
2667
|
-
themeRaw,
|
|
2668
|
-
theme,
|
|
2669
|
-
themeRoots,
|
|
2670
|
-
addonRoots,
|
|
2671
|
-
roots
|
|
2672
|
-
});
|
|
2673
|
-
const data = {
|
|
2674
|
-
...loaded,
|
|
2675
|
-
config,
|
|
2676
|
-
themeMeta
|
|
2677
|
-
};
|
|
2678
|
-
const resolved = {
|
|
2679
|
-
...rootsInfo,
|
|
2680
|
-
...entryOptions,
|
|
2681
|
-
data,
|
|
2682
|
-
mode,
|
|
2683
|
-
entry,
|
|
2684
|
-
themeRaw,
|
|
2685
|
-
theme,
|
|
2686
|
-
themeRoots,
|
|
2687
|
-
addonRoots,
|
|
2688
|
-
roots
|
|
2689
|
-
};
|
|
2690
|
-
return {
|
|
2691
|
-
...resolved,
|
|
2692
|
-
utils: await createDataUtils(resolved)
|
|
2693
|
-
};
|
|
2694
|
-
}
|
|
2695
|
-
async function createDataUtils(resolved) {
|
|
2696
|
-
const monacoTypesIgnorePackagesMatches = (resolved.data.config.monacoTypesIgnorePackages || []).map((i) => pm.makeRe(i));
|
|
2697
|
-
let _layouts_cache_time = 0;
|
|
2698
|
-
let _layouts_cache = {};
|
|
2699
|
-
return {
|
|
2700
|
-
...await setupShiki(resolved.roots),
|
|
2701
|
-
katexOptions: await setupKatex(resolved.roots),
|
|
2702
|
-
indexHtml: await setupIndexHtml(resolved),
|
|
2703
|
-
define: getDefine(resolved),
|
|
2704
|
-
iconsResolvePath: [resolved.clientRoot, ...resolved.roots].reverse(),
|
|
2705
|
-
isMonacoTypesIgnored: (pkg) => monacoTypesIgnorePackagesMatches.some((i) => i.test(pkg)),
|
|
2706
|
-
getLayouts: () => {
|
|
2707
|
-
const now = Date.now();
|
|
2708
|
-
if (now - _layouts_cache_time < 2e3)
|
|
2709
|
-
return _layouts_cache;
|
|
2710
|
-
const layouts = {};
|
|
2711
|
-
for (const root of [resolved.clientRoot, ...resolved.roots]) {
|
|
2712
|
-
const layoutPaths = fg4.sync("layouts/**/*.{vue,ts}", {
|
|
2713
|
-
cwd: root,
|
|
2714
|
-
absolute: true,
|
|
2715
|
-
suppressErrors: true
|
|
2716
|
-
});
|
|
2717
|
-
for (const layoutPath of layoutPaths) {
|
|
2718
|
-
const layoutName = path4.basename(layoutPath).replace(/\.\w+$/, "");
|
|
2719
|
-
layouts[layoutName] = layoutPath;
|
|
2720
|
-
}
|
|
2721
|
-
}
|
|
2722
|
-
_layouts_cache_time = now;
|
|
2723
|
-
_layouts_cache = layouts;
|
|
2724
|
-
return layouts;
|
|
2725
|
-
}
|
|
2726
|
-
};
|
|
2727
|
-
}
|
|
2728
|
-
function getDefine(options) {
|
|
2729
|
-
const matchMode = (mode) => mode === true || mode === options.mode;
|
|
2730
|
-
return objectMap2(
|
|
2731
|
-
{
|
|
2732
|
-
__DEV__: options.mode === "dev",
|
|
2733
|
-
__SLIDEV_CLIENT_ROOT__: toAtFS(options.clientRoot),
|
|
2734
|
-
__SLIDEV_HASH_ROUTE__: options.data.config.routerMode === "hash",
|
|
2735
|
-
__SLIDEV_FEATURE_DRAWINGS__: matchMode(options.data.config.drawings.enabled),
|
|
2736
|
-
__SLIDEV_FEATURE_EDITOR__: options.mode === "dev" && options.data.config.editor !== false,
|
|
2737
|
-
__SLIDEV_FEATURE_DRAWINGS_PERSIST__: !!options.data.config.drawings.persist,
|
|
2738
|
-
__SLIDEV_FEATURE_RECORD__: matchMode(options.data.config.record),
|
|
2739
|
-
__SLIDEV_FEATURE_PRESENTER__: matchMode(options.data.config.presenter),
|
|
2740
|
-
__SLIDEV_FEATURE_PRINT__: options.mode === "export" || options.mode === "build" && [true, "true", "auto"].includes(options.data.config.download),
|
|
2741
|
-
__SLIDEV_FEATURE_BROWSER_EXPORTER__: matchMode(options.data.config.browserExporter),
|
|
2742
|
-
__SLIDEV_FEATURE_WAKE_LOCK__: matchMode(options.data.config.wakeLock),
|
|
2743
|
-
__SLIDEV_HAS_SERVER__: options.mode !== "build"
|
|
2744
|
-
},
|
|
2745
|
-
(v, k) => [v, JSON.stringify(k)]
|
|
2746
|
-
);
|
|
2747
|
-
}
|
|
2748
|
-
|
|
2749
|
-
export {
|
|
2750
|
-
version,
|
|
2751
|
-
updateFrontmatterPatch,
|
|
2752
|
-
resolveAddons,
|
|
2753
|
-
resolveTheme,
|
|
2754
|
-
getThemeMeta,
|
|
2755
|
-
parser,
|
|
2756
|
-
loadSetups,
|
|
2757
|
-
resolveOptions,
|
|
2758
|
-
createDataUtils,
|
|
2759
|
-
ViteSlidevPlugin,
|
|
2760
|
-
resolveViteConfigs
|
|
2761
|
-
};
|