@slidev/cli 0.50.0-beta.1 → 0.50.0-beta.11

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/README.md CHANGED
@@ -13,7 +13,7 @@ Presentation <b>slide</b>s for <b>dev</b>elopers 🧑‍💻👩‍💻👨‍
13
13
  <a href="https://www.npmjs.com/package/@slidev/cli" target="__blank"><img src="https://img.shields.io/npm/v/@slidev/cli?color=2B90B6&label=" alt="NPM version"></a>
14
14
  <a href="https://www.npmjs.com/package/@slidev/cli" target="__blank"><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/@slidev/cli?color=349dbe&label="></a>
15
15
  <a href="https://sli.dev/" target="__blank"><img src="https://img.shields.io/static/v1?label=&message=docs%20%26%20demos&color=45b8cd" alt="Docs & Demos"></a>
16
- <a href="https://sli.dev/themes/gallery.html" target="__blank"><img src="https://img.shields.io/static/v1?label=&message=themes&color=4ec5d4" alt="Themes"></a>
16
+ <a href="https://sli.dev/resources/theme-gallery" target="__blank"><img src="https://img.shields.io/static/v1?label=&message=themes&color=4ec5d4" alt="Themes"></a>
17
17
  <br>
18
18
  <a href="https://github.com/slidevjs/slidev" target="__blank"><img alt="GitHub stars" src="https://img.shields.io/github/stars/slidevjs/slidev?style=social"></a>
19
19
  </p>
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  resolveViteConfigs
3
- } from "./chunk-6O4GDZ4B.js";
4
- import "./chunk-6DS3IPOB.js";
3
+ } from "./chunk-H4RHMU3C.js";
5
4
  import "./chunk-UNQ5DBLZ.js";
6
5
 
7
6
  // node/commands/build.ts
@@ -51,7 +50,7 @@ async function build(options, viteConfig = {}, args) {
51
50
  await fs.writeFile(redirectsPath, `${config.base}* ${config.base}index.html 200
52
51
  `, "utf-8");
53
52
  if ([true, "true", "auto"].includes(options.data.config.download)) {
54
- const { exportSlides, getExportOptions } = await import("./export-WMRLKOJP.js");
53
+ const { exportSlides, getExportOptions } = await import("./export-I2C456L6.js");
55
54
  const port = 12445;
56
55
  const app = connect();
57
56
  const server = http.createServer(app);
@@ -1,8 +1,3 @@
1
- import {
2
- escapeVueInCode,
3
- getCodeBlocks,
4
- normalizeRangeStr
5
- } from "./chunk-6DS3IPOB.js";
6
1
  import {
7
2
  createResolver,
8
3
  getRoots,
@@ -14,7 +9,7 @@ import {
14
9
  } from "./chunk-UNQ5DBLZ.js";
15
10
 
16
11
  // package.json
17
- var version = "0.50.0-beta.1";
12
+ var version = "0.50.0-beta.11";
18
13
 
19
14
  // node/integrations/themes.ts
20
15
  import { join } from "node:path";
@@ -44,7 +39,7 @@ import * as parser from "@slidev/parser/fs";
44
39
 
45
40
  // node/options.ts
46
41
  import path3 from "node:path";
47
- import { uniq as uniq5 } from "@antfu/utils";
42
+ import { objectMap as objectMap2, uniq as uniq5 } from "@antfu/utils";
48
43
  import Debug from "debug";
49
44
  import fg4 from "fast-glob";
50
45
  import mm from "micromatch";
@@ -179,9 +174,118 @@ function getBodyJson(req) {
179
174
 
180
175
  // node/vite/compilerFlagsVue.ts
181
176
  import { objectEntries } from "@antfu/utils";
177
+ function createVueCompilerFlagsPlugin(options) {
178
+ const define = objectEntries(options.utils.define);
179
+ return {
180
+ name: "slidev:flags",
181
+ enforce: "pre",
182
+ transform(code, id) {
183
+ if (!id.match(/\.vue($|\?)/) && !id.includes("?vue&"))
184
+ return;
185
+ const original = code;
186
+ define.forEach(([from, to]) => {
187
+ code = code.replaceAll(from, to);
188
+ });
189
+ if (original !== code)
190
+ return code;
191
+ }
192
+ };
193
+ }
182
194
 
183
- // node/vite/extendConfig.ts
195
+ // node/vite/components.ts
184
196
  import { join as join2 } from "node:path";
197
+ import IconsResolver from "unplugin-icons/resolver";
198
+ import Components from "unplugin-vue-components/vite";
199
+ function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
200
+ return Components({
201
+ extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
202
+ dirs: [
203
+ join2(clientRoot, "builtin"),
204
+ ...roots.map((i) => join2(i, "components"))
205
+ ],
206
+ include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
207
+ exclude: [],
208
+ resolvers: [
209
+ IconsResolver({
210
+ prefix: "",
211
+ customCollections: Object.keys(pluginOptions.icons?.customCollections || [])
212
+ })
213
+ ],
214
+ dts: false,
215
+ ...pluginOptions.components
216
+ });
217
+ }
218
+
219
+ // node/vite/common.ts
220
+ var regexSlideReqPath = /^\/__slidev\/slides\/(\d+)\.json$/;
221
+ var regexSlideFacadeId = /^\/@slidev\/slides\/(\d+)\/(md|frontmatter)($|\?)/;
222
+ var regexSlideSourceId = /__slidev_(\d+)\.(md|frontmatter)$/;
223
+ var templateInjectionMarker = "/* @slidev-injection */";
224
+ var templateImportContextUtils = `import { useSlideContext as _useSlideContext, frontmatterToProps as _frontmatterToProps } from "@slidev/client/context.ts"`;
225
+ var templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = _useSlideContext()`;
226
+
227
+ // node/vite/contextInjection.ts
228
+ function createContextInjectionPlugin() {
229
+ return {
230
+ name: "slidev:context-injection",
231
+ async transform(code, id) {
232
+ if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/"))
233
+ return;
234
+ if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
235
+ return code;
236
+ const imports = [
237
+ templateImportContextUtils,
238
+ templateInitContext,
239
+ templateInjectionMarker
240
+ ];
241
+ const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
242
+ if (matchScript && matchScript[2]) {
243
+ return code.replace(/(<script.*>)/g, `$1
244
+ ${imports.join("\n")}
245
+ `);
246
+ } else if (matchScript && !matchScript[2]) {
247
+ const matchExport = code.match(/export\s+default\s+\{/);
248
+ if (matchExport) {
249
+ const exportIndex = (matchExport.index || 0) + matchExport[0].length;
250
+ let component = code.slice(exportIndex);
251
+ component = component.slice(0, component.indexOf("</script>"));
252
+ const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
253
+ const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
254
+ code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
255
+ let injectIndex = exportIndex + provideImport.length;
256
+ let injectObject = "$slidev: { from: injectionSlidevContext },";
257
+ const matchInject = component.match(/.*inject\s*:\s*([[{])/);
258
+ if (matchInject) {
259
+ injectIndex += (matchInject.index || 0) + matchInject[0].length;
260
+ if (matchInject[1] === "[") {
261
+ let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
262
+ const injectEndIndex = injects.indexOf("]");
263
+ injects = injects.slice(0, injectEndIndex);
264
+ injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
265
+ return `${code.slice(0, injectIndex - 1)}{
266
+ ${injectObject}
267
+ }${code.slice(injectIndex + injectEndIndex + 1)}`;
268
+ } else {
269
+ return `${code.slice(0, injectIndex)}
270
+ ${injectObject}
271
+ ${code.slice(injectIndex)}`;
272
+ }
273
+ }
274
+ return `${code.slice(0, injectIndex)}
275
+ inject: { ${injectObject} },
276
+ ${code.slice(injectIndex)}`;
277
+ }
278
+ }
279
+ return `<script setup>
280
+ ${imports.join("\n")}
281
+ </script>
282
+ ${code}`;
283
+ }
284
+ };
285
+ }
286
+
287
+ // node/vite/extendConfig.ts
288
+ import { join as join3 } from "node:path";
185
289
  import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
186
290
  import { slash, uniq } from "@antfu/utils";
187
291
  import { createResolve } from "mlly";
@@ -193,7 +297,8 @@ var INCLUDE_GLOBAL = [
193
297
  "prettier",
194
298
  "recordrtc",
195
299
  "typescript",
196
- "yaml"
300
+ "yaml",
301
+ "html-to-image"
197
302
  ];
198
303
  var INCLUDE_LOCAL = INCLUDE_GLOBAL.map((i) => `@slidev/cli > @slidev/client > ${i}`);
199
304
  var EXCLUDE_GLOBAL = [
@@ -242,7 +347,7 @@ function createConfigPlugin(options) {
242
347
  name: "slidev:config",
243
348
  async config(config) {
244
349
  const injection = {
245
- define: getDefine(options),
350
+ define: options.utils.define,
246
351
  resolve: {
247
352
  alias: [
248
353
  {
@@ -295,7 +400,7 @@ function createConfigPlugin(options) {
295
400
  ])
296
401
  }
297
402
  },
298
- publicDir: join2(options.userRoot, "public"),
403
+ publicDir: join3(options.userRoot, "public"),
299
404
  build: {
300
405
  rollupOptions: {
301
406
  output: {
@@ -322,21 +427,18 @@ function createConfigPlugin(options) {
322
427
  }
323
428
  }
324
429
  }
325
- }
430
+ },
431
+ cacheDir: isInstalledGlobally.value ? join3(options.cliRoot, "node_modules/.vite") : void 0
326
432
  };
327
433
  function isSlidevClient(id) {
328
434
  return id.includes("/@slidev/") || id.includes("/slidev/packages/client/") || id.includes("/@vueuse/");
329
435
  }
330
- if (isInstalledGlobally.value) {
331
- injection.cacheDir = join2(options.cliRoot, "node_modules/.vite");
332
- injection.root = options.cliRoot;
333
- }
334
436
  return mergeConfig(injection, config);
335
437
  },
336
438
  configureServer(server) {
337
439
  return () => {
338
440
  server.middlewares.use(async (req, res, next) => {
339
- if (req.url.endsWith(".html")) {
441
+ if (req.url === "/index.html") {
340
442
  res.setHeader("Content-Type", "text/html");
341
443
  res.statusCode = 200;
342
444
  res.end(options.utils.indexHtml);
@@ -348,139 +450,11 @@ function createConfigPlugin(options) {
348
450
  }
349
451
  };
350
452
  }
351
- function getDefine(options) {
352
- return {
353
- __DEV__: options.mode === "dev" ? "true" : "false",
354
- __SLIDEV_CLIENT_ROOT__: JSON.stringify(toAtFS(options.clientRoot)),
355
- __SLIDEV_HASH_ROUTE__: JSON.stringify(options.data.config.routerMode === "hash"),
356
- __SLIDEV_FEATURE_DRAWINGS__: JSON.stringify(options.data.config.drawings.enabled === true || options.data.config.drawings.enabled === options.mode),
357
- __SLIDEV_FEATURE_EDITOR__: JSON.stringify(options.mode === "dev" && options.data.config.editor !== false),
358
- __SLIDEV_FEATURE_DRAWINGS_PERSIST__: JSON.stringify(!!options.data.config.drawings.persist === true),
359
- __SLIDEV_FEATURE_RECORD__: JSON.stringify(options.data.config.record === true || options.data.config.record === options.mode),
360
- __SLIDEV_FEATURE_PRESENTER__: JSON.stringify(options.data.config.presenter === true || options.data.config.presenter === options.mode),
361
- __SLIDEV_FEATURE_PRINT__: JSON.stringify(options.mode === "export" || options.mode === "build" && [true, "true", "auto"].includes(options.data.config.download)),
362
- __SLIDEV_FEATURE_WAKE_LOCK__: JSON.stringify(options.data.config.wakeLock === true || options.data.config.wakeLock === options.mode),
363
- __SLIDEV_HAS_SERVER__: options.mode !== "build" ? "true" : "false"
364
- };
365
- }
366
-
367
- // node/vite/compilerFlagsVue.ts
368
- function createVueCompilerFlagsPlugin(options) {
369
- const define = objectEntries(getDefine(options));
370
- return [
371
- {
372
- name: "slidev:flags",
373
- enforce: "pre",
374
- transform(code, id) {
375
- if (id.match(/\.vue($|\?)/)) {
376
- const original = code;
377
- define.forEach(([from, to]) => {
378
- code = code.replace(new RegExp(from, "g"), to);
379
- });
380
- if (original !== code)
381
- return code;
382
- }
383
- }
384
- }
385
- ];
386
- }
387
-
388
- // node/vite/components.ts
389
- import { join as join3 } from "node:path";
390
- import IconsResolver from "unplugin-icons/resolver";
391
- import Components from "unplugin-vue-components/vite";
392
- function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
393
- return Components({
394
- extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
395
- dirs: [
396
- join3(clientRoot, "builtin"),
397
- ...roots.map((i) => join3(i, "components"))
398
- ],
399
- include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
400
- exclude: [],
401
- resolvers: [
402
- IconsResolver({
403
- prefix: "",
404
- customCollections: Object.keys(pluginOptions.icons?.customCollections || [])
405
- })
406
- ],
407
- dts: false,
408
- ...pluginOptions.components
409
- });
410
- }
411
-
412
- // node/vite/common.ts
413
- var regexSlideReqPath = /^\/__slidev\/slides\/(\d+)\.json$/;
414
- var regexSlideFacadeId = /^\/@slidev\/slides\/(\d+)\/(md|frontmatter)($|\?)/;
415
- var regexSlideSourceId = /__slidev_(\d+)\.(md|frontmatter)$/;
416
- var templateInjectionMarker = "/* @slidev-injection */";
417
- var templateImportContextUtils = `import { useSlideContext as _useSlideContext, frontmatterToProps as _frontmatterToProps } from "@slidev/client/context.ts"`;
418
- var templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = _useSlideContext()`;
419
-
420
- // node/vite/contextInjection.ts
421
- function createContextInjectionPlugin() {
422
- return {
423
- name: "slidev:context-injection",
424
- async transform(code, id) {
425
- if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/"))
426
- return;
427
- if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
428
- return code;
429
- const imports = [
430
- templateImportContextUtils,
431
- templateInitContext,
432
- templateInjectionMarker
433
- ];
434
- const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
435
- if (matchScript && matchScript[2]) {
436
- return code.replace(/(<script.*>)/g, `$1
437
- ${imports.join("\n")}
438
- `);
439
- } else if (matchScript && !matchScript[2]) {
440
- const matchExport = code.match(/export\s+default\s+\{/);
441
- if (matchExport) {
442
- const exportIndex = (matchExport.index || 0) + matchExport[0].length;
443
- let component = code.slice(exportIndex);
444
- component = component.slice(0, component.indexOf("</script>"));
445
- const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
446
- const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
447
- code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
448
- let injectIndex = exportIndex + provideImport.length;
449
- let injectObject = "$slidev: { from: injectionSlidevContext },";
450
- const matchInject = component.match(/.*inject\s*:\s*([[{])/);
451
- if (matchInject) {
452
- injectIndex += (matchInject.index || 0) + matchInject[0].length;
453
- if (matchInject[1] === "[") {
454
- let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
455
- const injectEndIndex = injects.indexOf("]");
456
- injects = injects.slice(0, injectEndIndex);
457
- injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
458
- return `${code.slice(0, injectIndex - 1)}{
459
- ${injectObject}
460
- }${code.slice(injectIndex + injectEndIndex + 1)}`;
461
- } else {
462
- return `${code.slice(0, injectIndex)}
463
- ${injectObject}
464
- ${code.slice(injectIndex)}`;
465
- }
466
- }
467
- return `${code.slice(0, injectIndex)}
468
- inject: { ${injectObject} },
469
- ${code.slice(injectIndex)}`;
470
- }
471
- }
472
- return `<script setup>
473
- ${imports.join("\n")}
474
- </script>
475
- ${code}`;
476
- }
477
- };
478
- }
479
453
 
480
454
  // node/vite/hmrPatch.ts
481
455
  function createHmrPatchPlugin() {
482
456
  return {
483
- name: "slidev:slide-transform:post",
457
+ name: "slidev:hmr-patch",
484
458
  transform(code, id) {
485
459
  if (!id.match(regexSlideSourceId))
486
460
  return;
@@ -524,7 +498,7 @@ function createLayoutWrapperPlugin({ data, utils }) {
524
498
  if (type !== "md")
525
499
  return;
526
500
  const index = +no - 1;
527
- const layouts = await utils.getLayouts();
501
+ const layouts = utils.getLayouts();
528
502
  const rawLayoutName = data.slides[index]?.frontmatter?.layout ?? data.slides[0]?.frontmatter?.defaults?.layout;
529
503
  let layoutName = rawLayoutName || (index === 0 ? "cover" : "default");
530
504
  if (!layouts[layoutName]) {
@@ -1004,12 +978,22 @@ function withRenderedNote(data) {
1004
978
  };
1005
979
  }
1006
980
  function createSlidesLoader(options, serverOptions) {
981
+ const { data, mode, utils } = options;
1007
982
  const hmrSlidesIndexes = /* @__PURE__ */ new Set();
1008
983
  let server;
1009
984
  let skipHmr = null;
1010
- const { data, mode, utils } = options;
1011
- function getSourceId(index, type) {
1012
- return `${data.slides[index].source.filepath}__slidev_${index + 1}.${type}`;
985
+ let sourceIds = resolveSourceIds(data);
986
+ function resolveSourceIds(data2) {
987
+ const ids = {
988
+ md: [],
989
+ frontmatter: []
990
+ };
991
+ for (const type of ["md", "frontmatter"]) {
992
+ for (let i = 0; i < data2.slides.length; i++) {
993
+ ids[type].push(`${data2.slides[i].source.filepath}__slidev_${i + 1}.${type}`);
994
+ }
995
+ }
996
+ return ids;
1013
997
  }
1014
998
  function updateServerWatcher() {
1015
999
  if (!server)
@@ -1067,11 +1051,11 @@ function createSlidesLoader(options, serverOptions) {
1067
1051
  fileContent
1068
1052
  };
1069
1053
  server?.moduleGraph.invalidateModule(
1070
- server.moduleGraph.getModuleById(getSourceId(idx, "md"))
1054
+ server.moduleGraph.getModuleById(sourceIds.md[idx])
1071
1055
  );
1072
1056
  if (body.frontmatter) {
1073
1057
  server?.moduleGraph.invalidateModule(
1074
- server.moduleGraph.getModuleById(getSourceId(idx, "frontmatter"))
1058
+ server.moduleGraph.getModuleById(sourceIds.frontmatter[idx])
1075
1059
  );
1076
1060
  }
1077
1061
  }
@@ -1099,9 +1083,19 @@ function createSlidesLoader(options, serverOptions) {
1099
1083
  return [];
1100
1084
  }
1101
1085
  const moduleIds = /* @__PURE__ */ new Set();
1086
+ const newSourceIds = resolveSourceIds(newData);
1087
+ for (const type of ["md", "frontmatter"]) {
1088
+ const old = sourceIds[type];
1089
+ const newIds = newSourceIds[type];
1090
+ for (let i = 0; i < newIds.length; i++) {
1091
+ if (old[i] !== newIds[i]) {
1092
+ moduleIds.add(`${VIRTUAL_SLIDE_PREFIX}${i + 1}/${type}`);
1093
+ }
1094
+ }
1095
+ }
1096
+ sourceIds = newSourceIds;
1102
1097
  if (data.slides.length !== newData.slides.length) {
1103
1098
  moduleIds.add(templateSlides.id);
1104
- range(newData.slides.length).map((i) => hmrSlidesIndexes.add(i));
1105
1099
  }
1106
1100
  if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
1107
1101
  moduleIds.add(templateSlides.id);
@@ -1145,8 +1139,8 @@ function createSlidesLoader(options, serverOptions) {
1145
1139
  if (hmrSlidesIndexes.size > 0)
1146
1140
  moduleIds.add(templateTitleRendererMd.id);
1147
1141
  const vueModules = Array.from(hmrSlidesIndexes).flatMap((idx) => {
1148
- const frontmatter = ctx.server.moduleGraph.getModuleById(getSourceId(idx, "frontmatter"));
1149
- const main = ctx.server.moduleGraph.getModuleById(getSourceId(idx, "md"));
1142
+ const frontmatter = ctx.server.moduleGraph.getModuleById(sourceIds.frontmatter[idx]);
1143
+ const main = ctx.server.moduleGraph.getModuleById(sourceIds.md[idx]);
1150
1144
  const styles = main ? [...main.clientImportedModules].find((m) => m.id?.includes(`&type=style`)) : void 0;
1151
1145
  return [
1152
1146
  frontmatter,
@@ -1183,7 +1177,7 @@ function createSlidesLoader(options, serverOptions) {
1183
1177
  if (matchFacade) {
1184
1178
  const [, no, type] = matchFacade;
1185
1179
  const idx = +no - 1;
1186
- const sourceId = JSON.stringify(getSourceId(idx, type));
1180
+ const sourceId = JSON.stringify(sourceIds[type][idx]);
1187
1181
  return [
1188
1182
  `export * from ${sourceId}`,
1189
1183
  `export { default } from ${sourceId}`
@@ -1391,8 +1385,8 @@ function startsWithTodoMarkdown(token) {
1391
1385
  }
1392
1386
 
1393
1387
  // node/syntax/markdown-it/index.ts
1394
- import MarkdownItMdc from "markdown-it-mdc";
1395
1388
  import MarkdownItFootnote from "markdown-it-footnote";
1389
+ import MarkdownItMdc from "markdown-it-mdc";
1396
1390
 
1397
1391
  // node/setups/load.ts
1398
1392
  import { resolve as resolve4 } from "node:path";
@@ -1580,6 +1574,34 @@ function MarkdownItKatex(md, options) {
1580
1574
  // node/syntax/markdown-it/markdown-it-shiki.ts
1581
1575
  import { isTruthy } from "@antfu/utils";
1582
1576
  import { fromHighlighter } from "@shikijs/markdown-it/core";
1577
+
1578
+ // node/syntax/transform/utils.ts
1579
+ function normalizeRangeStr(rangeStr = "") {
1580
+ return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
1581
+ }
1582
+ function getCodeBlocks(md) {
1583
+ const codeblocks = Array.from(md.matchAll(/^```[\s\S]*?^```/gm)).map((m) => {
1584
+ const start = m.index;
1585
+ const end = m.index + m[0].length;
1586
+ const startLine = md.slice(0, start).match(/\n/g)?.length || 0;
1587
+ const endLine = md.slice(0, end).match(/\n/g)?.length || 0;
1588
+ return [start, end, startLine, endLine];
1589
+ });
1590
+ return {
1591
+ codeblocks,
1592
+ isInsideCodeblocks(idx) {
1593
+ return codeblocks.some(([s, e]) => s <= idx && idx <= e);
1594
+ },
1595
+ isLineInsideCodeblocks(line) {
1596
+ return codeblocks.some(([, , s, e]) => s <= line && line <= e);
1597
+ }
1598
+ };
1599
+ }
1600
+ function escapeVueInCode(md) {
1601
+ return md.replace(/\{\{/g, "&lbrace;&lbrace;");
1602
+ }
1603
+
1604
+ // node/syntax/markdown-it/markdown-it-shiki.ts
1583
1605
  async function MarkdownItShiki({ data: { config }, mode, utils }) {
1584
1606
  const transformers = [
1585
1607
  ...utils.shikiOptions.transformers || [],
@@ -1669,10 +1691,6 @@ async function useMarkdownItPlugins(md, options, markdownTransformMap) {
1669
1691
  const { roots, data: { features, config } } = options;
1670
1692
  if (config.highlighter === "shiki") {
1671
1693
  md.use(await MarkdownItShiki(options));
1672
- } else {
1673
- console.warn("[Slidev] Highlighter: Prism highlighter is deprecated, and will be removed in v0.50. Refer to https://github.com/slidevjs/slidev/issues/1390");
1674
- const { default: MarkdownItPrism } = await import("./markdown-it-prism-44L27JJK.js");
1675
- md.use(MarkdownItPrism);
1676
1694
  }
1677
1695
  md.use(MarkdownItLink);
1678
1696
  md.use(MarkdownItEscapeInlineCode);
@@ -1710,7 +1728,7 @@ async function setupTransformers(roots) {
1710
1728
  }
1711
1729
 
1712
1730
  // node/syntax/transform/code-wrapper.ts
1713
- var reCodeBlock = /^```([\w'-]+)?\s*(?:\{([\w*,|-]+)\}\s*?(\{[^}]*\})?([^\r\n]*))?\r?\n(\S[\s\S]*?)^```$/gm;
1731
+ var reCodeBlock = /^```([\w'-]+)?\s*(?:\{([\w*,|-]+)\}\s*?(\{[^}]*\})?([^\r\n]*))?\r?\n([ \t]*\S[\s\S]*?)^```$/gm;
1714
1732
  function transformCodeWrapper(ctx) {
1715
1733
  ctx.s.replace(
1716
1734
  reCodeBlock,
@@ -1941,44 +1959,46 @@ function dedent(text) {
1941
1959
  return lines.map((x) => x.slice(minIndentLength)).join("\n");
1942
1960
  return text;
1943
1961
  }
1944
- function testLine(line, regexp, regionName, end = false) {
1945
- const [full, tag, name] = regexp.exec(line.trim()) || [];
1946
- return full && tag && name === regionName && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/);
1947
- }
1948
1962
  function findRegion(lines, regionName) {
1949
1963
  const regionRegexps = [
1950
- /^\/\/ ?#?((?:end)?region) ([\w*-]+)$/,
1951
1964
  // javascript, typescript, java
1952
- /^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/,
1965
+ [/^\/\/ ?#?region ([\w*-]+)$/, /^\/\/ ?#?endregion/],
1953
1966
  // css, less, scss
1954
- /^#pragma ((?:end)?region) ([\w*-]+)$/,
1967
+ [/^\/\* ?#region ([\w*-]+) ?\*\/$/, /^\/\* ?#endregion[\s\w*-]*\*\/$/],
1955
1968
  // C, C++
1956
- /^<!-- #?((?:end)?region) ([\w*-]+) -->$/,
1969
+ [/^#pragma region ([\w*-]+)$/, /^#pragma endregion/],
1957
1970
  // HTML, markdown
1958
- /^#(End Region) ([\w*-]+)$/,
1971
+ [/^<!-- #?region ([\w*-]+) -->$/, /^<!-- #?region[\s\w*-]*-->$/],
1959
1972
  // Visual Basic
1960
- /^::#(endregion) ([\w*-]+)$/,
1973
+ [/^#Region ([\w*-]+)$/, /^#End Region/],
1961
1974
  // Bat
1962
- /^# ?((?:end)?region) ([\w*-]+)$/
1975
+ [/^::#region ([\w*-]+)$/, /^::#endregion/],
1963
1976
  // C#, PHP, Powershell, Python, perl & misc
1977
+ [/^# ?region ([\w*-]+)$/, /^# ?endregion/]
1964
1978
  ];
1965
- let regexp = null;
1979
+ let endReg = null;
1966
1980
  let start = -1;
1967
1981
  for (const [lineId, line] of lines.entries()) {
1968
- if (regexp === null) {
1969
- for (const reg of regionRegexps) {
1970
- if (testLine(line, reg, regionName)) {
1982
+ if (endReg === null) {
1983
+ for (const [startReg, end] of regionRegexps) {
1984
+ const match = line.trim().match(startReg);
1985
+ if (match && match[1] === regionName) {
1971
1986
  start = lineId + 1;
1972
- regexp = reg;
1987
+ endReg = end;
1973
1988
  break;
1974
1989
  }
1975
1990
  }
1976
- } else if (testLine(line, regexp, regionName, true)) {
1977
- return { start, end: lineId, regexp };
1991
+ } else if (endReg.test(line.trim())) {
1992
+ return {
1993
+ start,
1994
+ end: lineId,
1995
+ regexp: endReg
1996
+ };
1978
1997
  }
1979
1998
  }
1980
1999
  return null;
1981
2000
  }
2001
+ var reMonacoWrite = /^\{monaco-write\}/;
1982
2002
  function transformSnippet({ s, slide, options }) {
1983
2003
  const watchFiles = options.data.watchFiles;
1984
2004
  const dir = path2.dirname(slide.source?.filepath ?? options.entry ?? options.userRoot);
@@ -1989,8 +2009,9 @@ function transformSnippet({ s, slide, options }) {
1989
2009
  const src = slash2(
1990
2010
  /^@\//.test(filepath) ? path2.resolve(options.userRoot, filepath.slice(2)) : path2.resolve(dir, filepath)
1991
2011
  );
1992
- watchFiles[src] ??= /* @__PURE__ */ new Set();
1993
- watchFiles[src].add(slide.index);
2012
+ meta = meta.trim();
2013
+ lang = lang.trim();
2014
+ lang = lang || path2.extname(filepath).slice(1);
1994
2015
  const isAFile = fs5.statSync(src).isFile();
1995
2016
  if (!fs5.existsSync(src) || !isAFile) {
1996
2017
  throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
@@ -2005,15 +2026,15 @@ function transformSnippet({ s, slide, options }) {
2005
2026
  );
2006
2027
  }
2007
2028
  }
2008
- meta = meta.trim();
2009
- lang = lang.trim();
2010
- lang = lang || path2.extname(filepath).slice(1);
2011
- if (meta.match(/^\{monaco-write\}/)) {
2029
+ if (meta.match(reMonacoWrite)) {
2012
2030
  monacoWriterWhitelist.add(filepath);
2013
2031
  lang = lang.trim();
2014
- meta = meta.replace(/^\{monaco-write\}/, "").trim() || "{}";
2032
+ meta = meta.replace(reMonacoWrite, "").trim() || "{}";
2015
2033
  const encoded = lz4.compressToBase64(content);
2016
2034
  return `<Monaco writable=${JSON.stringify(filepath)} code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />`;
2035
+ } else {
2036
+ watchFiles[src] ??= /* @__PURE__ */ new Set();
2037
+ watchFiles[src].add(slide.index);
2017
2038
  }
2018
2039
  return `\`\`\`${lang} ${meta}
2019
2040
  ${content}
@@ -2389,12 +2410,13 @@ async function createVuePlugin(_options, pluginOptions) {
2389
2410
  exclude: [],
2390
2411
  ...vueOptions,
2391
2412
  template: {
2413
+ ...vueOptions?.template,
2392
2414
  compilerOptions: {
2415
+ ...vueOptions?.template?.compilerOptions,
2393
2416
  isCustomElement(tag) {
2394
2417
  return customElements.has(tag) || vueOptions?.template?.compilerOptions?.isCustomElement?.(tag);
2395
2418
  }
2396
- },
2397
- ...vueOptions?.template
2419
+ }
2398
2420
  }
2399
2421
  });
2400
2422
  const VueJsxPlugin = VueJsx(vuejsxOptions);
@@ -2405,7 +2427,7 @@ async function createVuePlugin(_options, pluginOptions) {
2405
2427
  }
2406
2428
 
2407
2429
  // node/vite/index.ts
2408
- async function ViteSlidevPlugin(options, pluginOptions = {}, serverOptions = {}) {
2430
+ function ViteSlidevPlugin(options, pluginOptions = {}, serverOptions = {}) {
2409
2431
  return Promise.all([
2410
2432
  createSlidesLoader(options, serverOptions),
2411
2433
  createMarkdownPlugin(options, pluginOptions),
@@ -2501,6 +2523,8 @@ ${(index.match(/<body>([\s\S]*?)<\/body>/i)?.[1] || "").trim()}`;
2501
2523
  if (data.config.fonts.webfonts.length && data.config.fonts.provider !== "none")
2502
2524
  head += `
2503
2525
  <link rel="stylesheet" href="${generateGoogleFontsUrl(data.config.fonts)}" type="text/css">`;
2526
+ if (data.headmatter.lang)
2527
+ main = main.replace('<html lang="en">', `<html lang="${data.headmatter.lang}">`);
2504
2528
  main = main.replace("__ENTRY__", toAtFS(join13(clientRoot, "main.ts"))).replace("<!-- head -->", head).replace("<!-- body -->", body);
2505
2529
  return main;
2506
2530
  }
@@ -2566,6 +2590,8 @@ async function resolveOptions(entryOptions, mode) {
2566
2590
  const config = parser.resolveConfig(loaded.headmatter, themeMeta, entryOptions.entry);
2567
2591
  const addonRoots = await resolveAddons(config.addons);
2568
2592
  const roots = uniq5([...themeRoots, ...addonRoots, rootsInfo.userRoot]);
2593
+ if (entryOptions.download)
2594
+ config.download ||= entryOptions.download;
2569
2595
  debug({
2570
2596
  ...rootsInfo,
2571
2597
  ...entryOptions,
@@ -2607,6 +2633,7 @@ async function createDataUtils(resolved) {
2607
2633
  return {
2608
2634
  ...await setupShiki(resolved.roots),
2609
2635
  indexHtml: setupIndexHtml(resolved),
2636
+ define: getDefine(resolved),
2610
2637
  iconsResolvePath: [resolved.clientRoot, ...resolved.roots].reverse(),
2611
2638
  isMonacoTypesIgnored: (pkg) => monacoTypesIgnorePackagesMatches.some((i) => i(pkg)),
2612
2639
  getLayouts: () => {
@@ -2631,6 +2658,26 @@ async function createDataUtils(resolved) {
2631
2658
  }
2632
2659
  };
2633
2660
  }
2661
+ function getDefine(options) {
2662
+ const matchMode = (mode) => mode === true || mode === options.mode;
2663
+ return objectMap2(
2664
+ {
2665
+ __DEV__: options.mode === "dev",
2666
+ __SLIDEV_CLIENT_ROOT__: toAtFS(options.clientRoot),
2667
+ __SLIDEV_HASH_ROUTE__: options.data.config.routerMode === "hash",
2668
+ __SLIDEV_FEATURE_DRAWINGS__: matchMode(options.data.config.drawings.enabled),
2669
+ __SLIDEV_FEATURE_EDITOR__: options.mode === "dev" && options.data.config.editor !== false,
2670
+ __SLIDEV_FEATURE_DRAWINGS_PERSIST__: !!options.data.config.drawings.persist,
2671
+ __SLIDEV_FEATURE_RECORD__: matchMode(options.data.config.record),
2672
+ __SLIDEV_FEATURE_PRESENTER__: matchMode(options.data.config.presenter),
2673
+ __SLIDEV_FEATURE_PRINT__: options.mode === "export" || options.mode === "build" && [true, "true", "auto"].includes(options.data.config.download),
2674
+ __SLIDEV_FEATURE_BROWSER_EXPORTER__: matchMode(options.data.config.browserExporter),
2675
+ __SLIDEV_FEATURE_WAKE_LOCK__: matchMode(options.data.config.wakeLock),
2676
+ __SLIDEV_HAS_SERVER__: options.mode !== "build"
2677
+ },
2678
+ (v, k) => [v, JSON.stringify(k)]
2679
+ );
2680
+ }
2634
2681
 
2635
2682
  export {
2636
2683
  version,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveViteConfigs
3
- } from "./chunk-6O4GDZ4B.js";
3
+ } from "./chunk-H4RHMU3C.js";
4
4
 
5
5
  // node/commands/serve.ts
6
6
  import { join } from "node:path";
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-6GC5ATZB.js";
3
+ } from "./chunk-SMIAYOAS.js";
4
4
  import {
5
5
  getThemeMeta,
6
6
  loadSetups,
@@ -9,8 +9,7 @@ import {
9
9
  resolveOptions,
10
10
  resolveTheme,
11
11
  version
12
- } from "./chunk-6O4GDZ4B.js";
13
- import "./chunk-6DS3IPOB.js";
12
+ } from "./chunk-H4RHMU3C.js";
14
13
  import {
15
14
  getRoots,
16
15
  isInstalledGlobally,
@@ -27,18 +26,16 @@ import { verifyConfig } from "@slidev/parser";
27
26
  import equal from "fast-deep-equal";
28
27
  import fs from "fs-extra";
29
28
  import { getPort } from "get-port-please";
30
- import { blue, bold, cyan, dim, gray, green, underline, yellow } from "kolorist";
29
+ import { blue, bold, cyan, dim, gray, green, lightCyan, underline, yellow } from "kolorist";
31
30
  import openBrowser from "open";
32
31
  import yargs from "yargs";
33
32
 
34
33
  // node/setups/preparser.ts
35
34
  import { uniq } from "@antfu/utils";
36
35
  import { injectPreparserExtensionLoader } from "@slidev/parser/fs";
37
- async function setupPreparser() {
36
+ function setupPreparser() {
38
37
  injectPreparserExtensionLoader(async (headmatter, filepath, mode) => {
39
- const addons = headmatter?.addons;
40
- if (!addons?.length)
41
- return [];
38
+ const addons = Array.isArray(headmatter?.addons) ? headmatter.addons : [];
42
39
  const { userRoot } = await getRoots();
43
40
  const roots = uniq([
44
41
  ...await resolveAddons(addons),
@@ -51,7 +48,6 @@ async function setupPreparser() {
51
48
 
52
49
  // node/cli.ts
53
50
  var CONFIG_RESTART_FIELDS = [
54
- "highlighter",
55
51
  "monaco",
56
52
  "routerMode",
57
53
  "fonts",
@@ -334,11 +330,9 @@ cli.command(
334
330
  }).strict().help(),
335
331
  async (args) => {
336
332
  const { entry, theme, base, download, out, inspect } = args;
337
- const { build } = await import("./build-FMVKC2PV.js");
333
+ const { build } = await import("./build-GAPXZCUM.js");
338
334
  for (const entryFile of entry) {
339
- const options = await resolveOptions({ entry: entryFile, theme, inspect }, "build");
340
- if (download && !options.data.config.download)
341
- options.data.config.download = download;
335
+ const options = await resolveOptions({ entry: entryFile, theme, inspect, download }, "build");
342
336
  printInfo(options);
343
337
  await build(
344
338
  options,
@@ -414,10 +408,20 @@ cli.command(
414
408
  (args) => exportOptions(commonOptions(args)).strict().help(),
415
409
  async (args) => {
416
410
  const { entry, theme } = args;
417
- const { exportSlides, getExportOptions } = await import("./export-WMRLKOJP.js");
411
+ const { exportSlides, getExportOptions } = await import("./export-I2C456L6.js");
418
412
  const port = await getPort(12445);
413
+ let warned = false;
419
414
  for (const entryFile of entry) {
420
415
  const options = await resolveOptions({ entry: entryFile, theme }, "export");
416
+ if (options.data.config.browserExporter !== false && !warned) {
417
+ warned = true;
418
+ console.log(lightCyan("[Slidev] Try the new browser exporter!"));
419
+ console.log(
420
+ lightCyan("You can use the browser exporter instead by starting the dev server as normal and visit"),
421
+ `${blue("localhost:")}${dim("<port>")}${blue("/export")}
422
+ `
423
+ );
424
+ }
421
425
  const server = await createServer(
422
426
  options,
423
427
  {
@@ -463,7 +467,7 @@ cli.command(
463
467
  timeout,
464
468
  wait
465
469
  }) => {
466
- const { exportNotes } = await import("./export-WMRLKOJP.js");
470
+ const { exportNotes } = await import("./export-I2C456L6.js");
467
471
  const port = await getPort(12445);
468
472
  for (const entryFile of entry) {
469
473
  const options = await resolveOptions({ entry: entryFile }, "export");
@@ -565,8 +569,11 @@ function printInfo(options, port, remote, tunnelUrl, publicIp) {
565
569
  console.log(`${dim(" public slide show ")} > ${cyan(`http://localhost:${bold(port)}/`)}`);
566
570
  if (query)
567
571
  console.log(`${dim(" private slide show ")} > ${cyan(`http://localhost:${bold(port)}/${query}`)}`);
568
- console.log(`${dim(" presenter mode ")} > ${blue(`http://localhost:${bold(port)}${presenterPath}`)}`);
572
+ if (options.utils.define.__SLIDEV_FEATURE_PRESENTER__)
573
+ console.log(`${dim(" presenter mode ")} > ${blue(`http://localhost:${bold(port)}${presenterPath}`)}`);
569
574
  console.log(`${dim(" slides overview ")} > ${blue(`http://localhost:${bold(port)}${overviewPath}`)}`);
575
+ if (options.utils.define.__SLIDEV_FEATURE_BROWSER_EXPORTER__)
576
+ console.log(`${dim(" export slides")} > ${blue(`http://localhost:${bold(port)}/export/`)}`);
570
577
  if (options.inspect)
571
578
  console.log(`${dim(" vite inspector")} > ${yellow(`http://localhost:${bold(port)}/__inspect/`)}`);
572
579
  let lastRemoteUrl = "";
@@ -77,8 +77,7 @@ async function exportNotes({
77
77
  base = "/",
78
78
  output = "notes",
79
79
  timeout = 3e4,
80
- wait = 0,
81
- waitUntil
80
+ wait = 0
82
81
  }) {
83
82
  const { chromium } = await importPlaywright();
84
83
  const browser = await chromium.launch();
@@ -88,9 +87,8 @@ async function exportNotes({
88
87
  progress.start(1);
89
88
  if (!output.endsWith(".pdf"))
90
89
  output = `${output}.pdf`;
91
- await page.goto(`http://localhost:${port}${base}presenter/print`, { waitUntil, timeout });
92
- if (waitUntil)
93
- await page.waitForLoadState(waitUntil);
90
+ await page.goto(`http://localhost:${port}${base}presenter/print`, { waitUntil: "networkidle", timeout });
91
+ await page.waitForLoadState("networkidle");
94
92
  await page.emulateMedia({ media: "screen" });
95
93
  if (wait)
96
94
  await page.waitForTimeout(wait);
package/dist/index.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-6GC5ATZB.js";
3
+ } from "./chunk-SMIAYOAS.js";
4
4
  import {
5
5
  ViteSlidevPlugin,
6
6
  createDataUtils,
7
7
  parser,
8
8
  resolveOptions
9
- } from "./chunk-6O4GDZ4B.js";
10
- import "./chunk-6DS3IPOB.js";
9
+ } from "./chunk-H4RHMU3C.js";
11
10
  import "./chunk-UNQ5DBLZ.js";
12
11
  export {
13
12
  ViteSlidevPlugin,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slidev/cli",
3
3
  "type": "module",
4
- "version": "0.50.0-beta.1",
4
+ "version": "0.50.0-beta.11",
5
5
  "description": "Presentation slides for developers",
6
6
  "author": "antfu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -42,23 +42,23 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "@antfu/ni": "^0.23.0",
45
+ "@antfu/ni": "^0.23.1",
46
46
  "@antfu/utils": "^0.7.10",
47
- "@iconify-json/carbon": "^1.2.1",
48
- "@iconify-json/ph": "^1.2.0",
49
- "@iconify-json/svg-spinners": "^1.2.0",
47
+ "@iconify-json/carbon": "^1.2.4",
48
+ "@iconify-json/ph": "^1.2.1",
49
+ "@iconify-json/svg-spinners": "^1.2.1",
50
50
  "@lillallol/outline-pdf": "^4.0.0",
51
- "@shikijs/markdown-it": "^1.20.0",
52
- "@shikijs/twoslash": "^1.20.0",
53
- "@shikijs/vitepress-twoslash": "^1.20.0",
54
- "@unocss/extractor-mdc": "^0.62.4",
55
- "@unocss/reset": "^0.62.4",
56
- "@vitejs/plugin-vue": "^5.1.4",
57
- "@vitejs/plugin-vue-jsx": "^4.0.1",
51
+ "@shikijs/markdown-it": "^1.24.2",
52
+ "@shikijs/twoslash": "^1.24.2",
53
+ "@shikijs/vitepress-twoslash": "^1.24.2",
54
+ "@unocss/extractor-mdc": "^0.65.1",
55
+ "@unocss/reset": "^0.65.1",
56
+ "@vitejs/plugin-vue": "^5.2.1",
57
+ "@vitejs/plugin-vue-jsx": "^4.1.1",
58
58
  "chokidar": "^4.0.1",
59
59
  "cli-progress": "^3.12.0",
60
60
  "connect": "^3.7.0",
61
- "debug": "^4.3.7",
61
+ "debug": "^4.4.0",
62
62
  "fast-deep-equal": "^3.1.3",
63
63
  "fast-glob": "^3.3.2",
64
64
  "fs-extra": "^11.2.0",
@@ -66,53 +66,52 @@
66
66
  "global-directory": "^4.0.1",
67
67
  "htmlparser2": "^9.1.0",
68
68
  "is-installed-globally": "^1.0.0",
69
- "jiti": "^2.0.0",
70
- "katex": "^0.16.11",
69
+ "jiti": "^2.4.1",
70
+ "katex": "^0.16.15",
71
71
  "kolorist": "^1.8.0",
72
- "local-pkg": "^0.5.0",
72
+ "local-pkg": "^0.5.1",
73
73
  "lz-string": "^1.5.0",
74
- "magic-string": "^0.30.11",
74
+ "magic-string": "^0.30.17",
75
75
  "magic-string-stack": "^0.1.1",
76
76
  "markdown-it": "^14.1.0",
77
77
  "markdown-it-footnote": "^4.0.0",
78
78
  "markdown-it-mdc": "^0.2.5",
79
79
  "micromatch": "^4.0.8",
80
- "mlly": "^1.7.1",
81
- "monaco-editor": "^0.52.0",
80
+ "mlly": "^1.7.3",
81
+ "monaco-editor": "0.51.0",
82
82
  "open": "^10.1.0",
83
83
  "pdf-lib": "^1.17.1",
84
84
  "plantuml-encoder": "^1.4.0",
85
- "postcss-nested": "^6.2.0",
85
+ "postcss-nested": "^7.0.2",
86
86
  "pptxgenjs": "^3.12.0",
87
- "prismjs": "^1.29.0",
88
87
  "prompts": "^2.4.2",
89
88
  "public-ip": "^7.0.1",
90
89
  "resolve-from": "^5.0.0",
91
90
  "resolve-global": "^2.0.0",
92
91
  "semver": "^7.6.3",
93
- "shiki": "^1.20.0",
94
- "shiki-magic-move": "^0.4.4",
95
- "sirv": "^2.0.4",
92
+ "shiki": "^1.24.2",
93
+ "shiki-magic-move": "^0.5.2",
94
+ "sirv": "^3.0.0",
96
95
  "source-map-js": "^1.2.1",
97
- "typescript": "^5.6.2",
98
- "unocss": "^0.62.4",
99
- "unplugin-icons": "^0.19.3",
100
- "unplugin-vue-components": "^0.27.4",
101
- "unplugin-vue-markdown": "^0.26.2",
96
+ "typescript": "5.6.3",
97
+ "unocss": "^0.65.1",
98
+ "unplugin-icons": "^0.22.0",
99
+ "unplugin-vue-components": "^0.28.0",
100
+ "unplugin-vue-markdown": "^0.28.0",
102
101
  "untun": "^0.1.3",
103
102
  "uqr": "^0.1.2",
104
- "vite": "^5.4.8",
105
- "vite-plugin-inspect": "^0.8.7",
106
- "vite-plugin-remote-assets": "^0.5.0",
107
- "vite-plugin-static-copy": "^1.0.6",
103
+ "vite": "^6.0.3",
104
+ "vite-plugin-inspect": "^0.10.3",
105
+ "vite-plugin-remote-assets": "^0.6.0",
106
+ "vite-plugin-static-copy": "^2.2.0",
108
107
  "vite-plugin-vue-server-ref": "^0.4.2",
109
- "vitefu": "^1.0.2",
110
- "vue": "^3.5.9",
111
- "yaml": "^2.5.1",
108
+ "vitefu": "^1.0.4",
109
+ "vue": "^3.5.13",
110
+ "yaml": "^2.6.1",
112
111
  "yargs": "^17.7.2",
113
- "@slidev/client": "0.50.0-beta.1",
114
- "@slidev/parser": "0.50.0-beta.1",
115
- "@slidev/types": "0.50.0-beta.1"
112
+ "@slidev/parser": "0.50.0-beta.11",
113
+ "@slidev/client": "0.50.0-beta.11",
114
+ "@slidev/types": "0.50.0-beta.11"
116
115
  },
117
116
  "devDependencies": {
118
117
  "@hedgedoc/markdown-it-plugins": "^2.1.4",
package/template.md CHANGED
@@ -6,8 +6,6 @@ theme: seriph
6
6
  background: https://cover.sli.dev
7
7
  # apply any unocss classes to the current slide
8
8
  class: 'text-center'
9
- # https://sli.dev/custom/config-highlighter.html
10
- highlighter: shiki
11
9
  # some information about the slides, markdown enabled
12
10
  info: |
13
11
  ## Slidev Starter Template
@@ -24,14 +22,14 @@ mdc: true
24
22
  Presentation slides for developers
25
23
 
26
24
  <div class="pt-12">
27
- <span @click="$slidev.nav.next" class="px-2 py-1 rounded cursor-pointer" hover="bg-white bg-opacity-10">
28
- Press Space for next page <carbon:arrow-right class="inline"/>
25
+ <span @click="$slidev.nav.next" class="px-2 py-1 rounded cursor-pointer" flex="~ justify-center items-center gap-2" hover="bg-white bg-opacity-10">
26
+ Press Space for next page <div class="i-carbon:arrow-right inline-block"/>
29
27
  </span>
30
28
  </div>
31
29
 
32
30
  <div class="abs-br m-6 flex gap-2">
33
31
  <button @click="$slidev.nav.openInEditor()" title="Open in Editor" class="text-xl slidev-icon-btn opacity-50 !border-none !hover:text-white">
34
- <carbon:edit />
32
+ <div class="i-carbon:edit" />
35
33
  </button>
36
34
  <a href="https://github.com/slidevjs/slidev" target="_blank" alt="GitHub" title="Open in GitHub"
37
35
  class="text-xl slidev-icon-btn opacity-50 !border-none !hover:text-white">
@@ -237,8 +235,8 @@ theme: seriph
237
235
 
238
236
  </div>
239
237
 
240
- Read more about [How to use a theme](https://sli.dev/themes/use.html) and
241
- check out the [Awesome Themes Gallery](https://sli.dev/themes/gallery.html).
238
+ Read more about [How to use a theme](https://sli.dev/guide/theme-addon#use-theme) and
239
+ check out the [Awesome Themes Gallery](https://sli.dev/resources/theme-gallery).
242
240
 
243
241
  ---
244
242
  preload: false
@@ -1,31 +0,0 @@
1
- // node/syntax/transform/utils.ts
2
- function normalizeRangeStr(rangeStr = "") {
3
- return !rangeStr.trim() ? [] : rangeStr.trim().split(/\|/g).map((i) => i.trim());
4
- }
5
- function getCodeBlocks(md) {
6
- const codeblocks = Array.from(md.matchAll(/^```[\s\S]*?^```/gm)).map((m) => {
7
- const start = m.index;
8
- const end = m.index + m[0].length;
9
- const startLine = md.slice(0, start).match(/\n/g)?.length || 0;
10
- const endLine = md.slice(0, end).match(/\n/g)?.length || 0;
11
- return [start, end, startLine, endLine];
12
- });
13
- return {
14
- codeblocks,
15
- isInsideCodeblocks(idx) {
16
- return codeblocks.some(([s, e]) => s <= idx && idx <= e);
17
- },
18
- isLineInsideCodeblocks(line) {
19
- return codeblocks.some(([, , s, e]) => s <= line && line <= e);
20
- }
21
- };
22
- }
23
- function escapeVueInCode(md) {
24
- return md.replace(/\{\{/g, "&lbrace;&lbrace;");
25
- }
26
-
27
- export {
28
- normalizeRangeStr,
29
- getCodeBlocks,
30
- escapeVueInCode
31
- };
@@ -1,107 +0,0 @@
1
- import {
2
- escapeVueInCode
3
- } from "./chunk-6DS3IPOB.js";
4
-
5
- // node/syntax/markdown-it/markdown-it-prism.ts
6
- import { createRequire } from "node:module";
7
- import * as htmlparser2 from "htmlparser2";
8
- import Prism from "prismjs";
9
- import loadLanguages from "prismjs/components/index.js";
10
- var require2 = createRequire(import.meta.url);
11
- var Tag = class {
12
- tagname;
13
- attributes;
14
- constructor(tagname, attributes) {
15
- this.tagname = tagname;
16
- this.attributes = attributes;
17
- }
18
- asOpen() {
19
- return `<${this.tagname} ${Object.entries(this.attributes).map(([key, value]) => `${key}="${value}"`).join(" ")}>`;
20
- }
21
- asClosed() {
22
- return `</${this.tagname}>`;
23
- }
24
- };
25
- var DEFAULTS = {
26
- plugins: [],
27
- init: () => {
28
- },
29
- defaultLanguageForUnknown: void 0,
30
- defaultLanguageForUnspecified: void 0,
31
- defaultLanguage: void 0
32
- };
33
- function loadPrismLang(lang) {
34
- if (!lang)
35
- return void 0;
36
- let langObject = Prism.languages[lang];
37
- if (langObject === void 0) {
38
- loadLanguages([lang]);
39
- langObject = Prism.languages[lang];
40
- }
41
- return langObject;
42
- }
43
- function loadPrismPlugin(name) {
44
- try {
45
- require2(`prismjs/plugins/${name}/prism-${name}`);
46
- } catch (e) {
47
- throw new Error(`Cannot load Prism plugin "${name}". Please check the spelling.`, { cause: e });
48
- }
49
- }
50
- function selectLanguage(options, lang) {
51
- let langToUse = lang;
52
- if (langToUse === "" && options.defaultLanguageForUnspecified !== void 0)
53
- langToUse = options.defaultLanguageForUnspecified;
54
- let prismLang = loadPrismLang(langToUse);
55
- if (prismLang === void 0 && options.defaultLanguageForUnknown !== void 0) {
56
- langToUse = options.defaultLanguageForUnknown;
57
- prismLang = loadPrismLang(langToUse);
58
- }
59
- return [langToUse, prismLang];
60
- }
61
- function highlight(markdownit, options, text, lang) {
62
- const [langToUse, prismLang] = selectLanguage(options, lang);
63
- let code = text.trimEnd();
64
- code = prismLang ? highlightPrism(code, prismLang, langToUse) : markdownit.utils.escapeHtml(code);
65
- code = code.split(/\r?\n/g).map((line) => `<span class="line">${line}</span>`).join("\n");
66
- const classAttribute = langToUse ? ` class="slidev-code ${markdownit.options.langPrefix}${markdownit.utils.escapeHtml(langToUse)}"` : "";
67
- return escapeVueInCode(`<pre${classAttribute}><code>${code}</code></pre>`);
68
- }
69
- function highlightPrism(code, prismLang, langToUse) {
70
- const openTags = [];
71
- const parser = new htmlparser2.Parser({
72
- onopentag(tagname, attributes) {
73
- openTags.push(new Tag(tagname, attributes));
74
- },
75
- onclosetag() {
76
- openTags.pop();
77
- }
78
- });
79
- code = Prism.highlight(code, prismLang, langToUse);
80
- code = code.split(/\r?\n/g).map((line) => {
81
- const prefix = openTags.map((tag) => tag.asOpen()).join("");
82
- parser.write(line);
83
- const postfix = openTags.reverse().map((tag) => tag.asClosed()).join("");
84
- return prefix + line + postfix;
85
- }).join("\n");
86
- parser.end();
87
- return code;
88
- }
89
- function checkLanguageOption(options, optionName) {
90
- const language = options[optionName];
91
- if (language !== void 0 && loadPrismLang(language) === void 0)
92
- throw new Error(`Bad option ${optionName}: There is no Prism language '${language}'.`);
93
- }
94
- function MarkdownItPrism(markdownit, useroptions) {
95
- const options = Object.assign({}, DEFAULTS, useroptions);
96
- checkLanguageOption(options, "defaultLanguage");
97
- checkLanguageOption(options, "defaultLanguageForUnknown");
98
- checkLanguageOption(options, "defaultLanguageForUnspecified");
99
- options.defaultLanguageForUnknown = options.defaultLanguageForUnknown || options.defaultLanguage;
100
- options.defaultLanguageForUnspecified = options.defaultLanguageForUnspecified || options.defaultLanguage;
101
- options.plugins.forEach(loadPrismPlugin);
102
- options.init(Prism);
103
- markdownit.options.highlight = (text, lang) => highlight(markdownit, options, text, lang);
104
- }
105
- export {
106
- MarkdownItPrism as default
107
- };