@slidev/cli 0.49.3 → 0.49.5

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.
@@ -2,7 +2,7 @@ import {
2
2
  ViteSlidevPlugin,
3
3
  getIndexHtml,
4
4
  mergeViteConfigs
5
- } from "./chunk-NQBDNZ65.mjs";
5
+ } from "./chunk-TQT222QW.mjs";
6
6
  import "./chunk-LOUKLO2C.mjs";
7
7
  import "./chunk-RG2EEPCO.mjs";
8
8
  import "./chunk-BXO7ZPPU.mjs";
@@ -63,7 +63,7 @@ async function build(options, viteConfig = {}, args) {
63
63
  await fs.writeFile(redirectsPath, `${config.base}* ${config.base}index.html 200
64
64
  `, "utf-8");
65
65
  if ([true, "true", "auto"].includes(options.data.config.download)) {
66
- const { exportSlides, getExportOptions } = await import("./export-WUI5C4U3.mjs");
66
+ const { exportSlides, getExportOptions } = await import("./export-Q4LURPEZ.mjs");
67
67
  const port = 12445;
68
68
  const app = connect();
69
69
  const server = http.createServer(app);
@@ -2,7 +2,7 @@ import {
2
2
  ViteSlidevPlugin,
3
3
  mergeViteConfigs,
4
4
  version
5
- } from "./chunk-NQBDNZ65.mjs";
5
+ } from "./chunk-TQT222QW.mjs";
6
6
  import {
7
7
  createResolver,
8
8
  getRoots,
@@ -89,17 +89,17 @@ var require_visit = __commonJS({
89
89
  visit.BREAK = BREAK;
90
90
  visit.SKIP = SKIP;
91
91
  visit.REMOVE = REMOVE;
92
- function visit_(key, node, visitor, path3) {
93
- const ctrl = callVisitor(key, node, visitor, path3);
92
+ function visit_(key, node, visitor, path4) {
93
+ const ctrl = callVisitor(key, node, visitor, path4);
94
94
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
95
- replaceNode(key, path3, ctrl);
96
- return visit_(key, ctrl, visitor, path3);
95
+ replaceNode(key, path4, ctrl);
96
+ return visit_(key, ctrl, visitor, path4);
97
97
  }
98
98
  if (typeof ctrl !== "symbol") {
99
99
  if (identity.isCollection(node)) {
100
- path3 = Object.freeze(path3.concat(node));
100
+ path4 = Object.freeze(path4.concat(node));
101
101
  for (let i = 0; i < node.items.length; ++i) {
102
- const ci = visit_(i, node.items[i], visitor, path3);
102
+ const ci = visit_(i, node.items[i], visitor, path4);
103
103
  if (typeof ci === "number")
104
104
  i = ci - 1;
105
105
  else if (ci === BREAK)
@@ -110,13 +110,13 @@ var require_visit = __commonJS({
110
110
  }
111
111
  }
112
112
  } else if (identity.isPair(node)) {
113
- path3 = Object.freeze(path3.concat(node));
114
- const ck = visit_("key", node.key, visitor, path3);
113
+ path4 = Object.freeze(path4.concat(node));
114
+ const ck = visit_("key", node.key, visitor, path4);
115
115
  if (ck === BREAK)
116
116
  return BREAK;
117
117
  else if (ck === REMOVE)
118
118
  node.key = null;
119
- const cv = visit_("value", node.value, visitor, path3);
119
+ const cv = visit_("value", node.value, visitor, path4);
120
120
  if (cv === BREAK)
121
121
  return BREAK;
122
122
  else if (cv === REMOVE)
@@ -137,17 +137,17 @@ var require_visit = __commonJS({
137
137
  visitAsync.BREAK = BREAK;
138
138
  visitAsync.SKIP = SKIP;
139
139
  visitAsync.REMOVE = REMOVE;
140
- async function visitAsync_(key, node, visitor, path3) {
141
- const ctrl = await callVisitor(key, node, visitor, path3);
140
+ async function visitAsync_(key, node, visitor, path4) {
141
+ const ctrl = await callVisitor(key, node, visitor, path4);
142
142
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
143
- replaceNode(key, path3, ctrl);
144
- return visitAsync_(key, ctrl, visitor, path3);
143
+ replaceNode(key, path4, ctrl);
144
+ return visitAsync_(key, ctrl, visitor, path4);
145
145
  }
146
146
  if (typeof ctrl !== "symbol") {
147
147
  if (identity.isCollection(node)) {
148
- path3 = Object.freeze(path3.concat(node));
148
+ path4 = Object.freeze(path4.concat(node));
149
149
  for (let i = 0; i < node.items.length; ++i) {
150
- const ci = await visitAsync_(i, node.items[i], visitor, path3);
150
+ const ci = await visitAsync_(i, node.items[i], visitor, path4);
151
151
  if (typeof ci === "number")
152
152
  i = ci - 1;
153
153
  else if (ci === BREAK)
@@ -158,13 +158,13 @@ var require_visit = __commonJS({
158
158
  }
159
159
  }
160
160
  } else if (identity.isPair(node)) {
161
- path3 = Object.freeze(path3.concat(node));
162
- const ck = await visitAsync_("key", node.key, visitor, path3);
161
+ path4 = Object.freeze(path4.concat(node));
162
+ const ck = await visitAsync_("key", node.key, visitor, path4);
163
163
  if (ck === BREAK)
164
164
  return BREAK;
165
165
  else if (ck === REMOVE)
166
166
  node.key = null;
167
- const cv = await visitAsync_("value", node.value, visitor, path3);
167
+ const cv = await visitAsync_("value", node.value, visitor, path4);
168
168
  if (cv === BREAK)
169
169
  return BREAK;
170
170
  else if (cv === REMOVE)
@@ -191,23 +191,23 @@ var require_visit = __commonJS({
191
191
  }
192
192
  return visitor;
193
193
  }
194
- function callVisitor(key, node, visitor, path3) {
194
+ function callVisitor(key, node, visitor, path4) {
195
195
  if (typeof visitor === "function")
196
- return visitor(key, node, path3);
196
+ return visitor(key, node, path4);
197
197
  if (identity.isMap(node))
198
- return visitor.Map?.(key, node, path3);
198
+ return visitor.Map?.(key, node, path4);
199
199
  if (identity.isSeq(node))
200
- return visitor.Seq?.(key, node, path3);
200
+ return visitor.Seq?.(key, node, path4);
201
201
  if (identity.isPair(node))
202
- return visitor.Pair?.(key, node, path3);
202
+ return visitor.Pair?.(key, node, path4);
203
203
  if (identity.isScalar(node))
204
- return visitor.Scalar?.(key, node, path3);
204
+ return visitor.Scalar?.(key, node, path4);
205
205
  if (identity.isAlias(node))
206
- return visitor.Alias?.(key, node, path3);
206
+ return visitor.Alias?.(key, node, path4);
207
207
  return void 0;
208
208
  }
209
- function replaceNode(key, path3, node) {
210
- const parent = path3[path3.length - 1];
209
+ function replaceNode(key, path4, node) {
210
+ const parent = path4[path4.length - 1];
211
211
  if (identity.isCollection(parent)) {
212
212
  parent.items[key] = node;
213
213
  } else if (identity.isPair(parent)) {
@@ -805,10 +805,10 @@ var require_Collection = __commonJS({
805
805
  var createNode = require_createNode();
806
806
  var identity = require_identity();
807
807
  var Node = require_Node();
808
- function collectionFromPath(schema, path3, value) {
808
+ function collectionFromPath(schema, path4, value) {
809
809
  let v = value;
810
- for (let i = path3.length - 1; i >= 0; --i) {
811
- const k = path3[i];
810
+ for (let i = path4.length - 1; i >= 0; --i) {
811
+ const k = path4[i];
812
812
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
813
813
  const a = [];
814
814
  a[k] = v;
@@ -827,7 +827,7 @@ var require_Collection = __commonJS({
827
827
  sourceObjects: /* @__PURE__ */ new Map()
828
828
  });
829
829
  }
830
- var isEmptyPath = (path3) => path3 == null || typeof path3 === "object" && !!path3[Symbol.iterator]().next().done;
830
+ var isEmptyPath = (path4) => path4 == null || typeof path4 === "object" && !!path4[Symbol.iterator]().next().done;
831
831
  var Collection = class extends Node.NodeBase {
832
832
  constructor(type, schema) {
833
833
  super(type);
@@ -857,11 +857,11 @@ var require_Collection = __commonJS({
857
857
  * be a Pair instance or a `{ key, value }` object, which may not have a key
858
858
  * that already exists in the map.
859
859
  */
860
- addIn(path3, value) {
861
- if (isEmptyPath(path3))
860
+ addIn(path4, value) {
861
+ if (isEmptyPath(path4))
862
862
  this.add(value);
863
863
  else {
864
- const [key, ...rest] = path3;
864
+ const [key, ...rest] = path4;
865
865
  const node = this.get(key, true);
866
866
  if (identity.isCollection(node))
867
867
  node.addIn(rest, value);
@@ -875,8 +875,8 @@ var require_Collection = __commonJS({
875
875
  * Removes a value from the collection.
876
876
  * @returns `true` if the item was found and removed.
877
877
  */
878
- deleteIn(path3) {
879
- const [key, ...rest] = path3;
878
+ deleteIn(path4) {
879
+ const [key, ...rest] = path4;
880
880
  if (rest.length === 0)
881
881
  return this.delete(key);
882
882
  const node = this.get(key, true);
@@ -890,8 +890,8 @@ var require_Collection = __commonJS({
890
890
  * scalar values from their surrounding node; to disable set `keepScalar` to
891
891
  * `true` (collections are always returned intact).
892
892
  */
893
- getIn(path3, keepScalar) {
894
- const [key, ...rest] = path3;
893
+ getIn(path4, keepScalar) {
894
+ const [key, ...rest] = path4;
895
895
  const node = this.get(key, true);
896
896
  if (rest.length === 0)
897
897
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -909,8 +909,8 @@ var require_Collection = __commonJS({
909
909
  /**
910
910
  * Checks if the collection includes a value with the key `key`.
911
911
  */
912
- hasIn(path3) {
913
- const [key, ...rest] = path3;
912
+ hasIn(path4) {
913
+ const [key, ...rest] = path4;
914
914
  if (rest.length === 0)
915
915
  return this.has(key);
916
916
  const node = this.get(key, true);
@@ -920,8 +920,8 @@ var require_Collection = __commonJS({
920
920
  * Sets a value in this collection. For `!!set`, `value` needs to be a
921
921
  * boolean to add/remove the item from the set.
922
922
  */
923
- setIn(path3, value) {
924
- const [key, ...rest] = path3;
923
+ setIn(path4, value) {
924
+ const [key, ...rest] = path4;
925
925
  if (rest.length === 0) {
926
926
  this.set(key, value);
927
927
  } else {
@@ -3369,9 +3369,9 @@ var require_Document = __commonJS({
3369
3369
  this.contents.add(value);
3370
3370
  }
3371
3371
  /** Adds a value to the document. */
3372
- addIn(path3, value) {
3372
+ addIn(path4, value) {
3373
3373
  if (assertCollection(this.contents))
3374
- this.contents.addIn(path3, value);
3374
+ this.contents.addIn(path4, value);
3375
3375
  }
3376
3376
  /**
3377
3377
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3446,14 +3446,14 @@ var require_Document = __commonJS({
3446
3446
  * Removes a value from the document.
3447
3447
  * @returns `true` if the item was found and removed.
3448
3448
  */
3449
- deleteIn(path3) {
3450
- if (Collection.isEmptyPath(path3)) {
3449
+ deleteIn(path4) {
3450
+ if (Collection.isEmptyPath(path4)) {
3451
3451
  if (this.contents == null)
3452
3452
  return false;
3453
3453
  this.contents = null;
3454
3454
  return true;
3455
3455
  }
3456
- return assertCollection(this.contents) ? this.contents.deleteIn(path3) : false;
3456
+ return assertCollection(this.contents) ? this.contents.deleteIn(path4) : false;
3457
3457
  }
3458
3458
  /**
3459
3459
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3468,10 +3468,10 @@ var require_Document = __commonJS({
3468
3468
  * scalar values from their surrounding node; to disable set `keepScalar` to
3469
3469
  * `true` (collections are always returned intact).
3470
3470
  */
3471
- getIn(path3, keepScalar) {
3472
- if (Collection.isEmptyPath(path3))
3471
+ getIn(path4, keepScalar) {
3472
+ if (Collection.isEmptyPath(path4))
3473
3473
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3474
- return identity.isCollection(this.contents) ? this.contents.getIn(path3, keepScalar) : void 0;
3474
+ return identity.isCollection(this.contents) ? this.contents.getIn(path4, keepScalar) : void 0;
3475
3475
  }
3476
3476
  /**
3477
3477
  * Checks if the document includes a value with the key `key`.
@@ -3482,10 +3482,10 @@ var require_Document = __commonJS({
3482
3482
  /**
3483
3483
  * Checks if the document includes a value at `path`.
3484
3484
  */
3485
- hasIn(path3) {
3486
- if (Collection.isEmptyPath(path3))
3485
+ hasIn(path4) {
3486
+ if (Collection.isEmptyPath(path4))
3487
3487
  return this.contents !== void 0;
3488
- return identity.isCollection(this.contents) ? this.contents.hasIn(path3) : false;
3488
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path4) : false;
3489
3489
  }
3490
3490
  /**
3491
3491
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3502,13 +3502,13 @@ var require_Document = __commonJS({
3502
3502
  * Sets a value in this document. For `!!set`, `value` needs to be a
3503
3503
  * boolean to add/remove the item from the set.
3504
3504
  */
3505
- setIn(path3, value) {
3506
- if (Collection.isEmptyPath(path3)) {
3505
+ setIn(path4, value) {
3506
+ if (Collection.isEmptyPath(path4)) {
3507
3507
  this.contents = value;
3508
3508
  } else if (this.contents == null) {
3509
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path3), value);
3509
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path4), value);
3510
3510
  } else if (assertCollection(this.contents)) {
3511
- this.contents.setIn(path3, value);
3511
+ this.contents.setIn(path4, value);
3512
3512
  }
3513
3513
  }
3514
3514
  /**
@@ -5403,9 +5403,9 @@ var require_cst_visit = __commonJS({
5403
5403
  visit.BREAK = BREAK;
5404
5404
  visit.SKIP = SKIP;
5405
5405
  visit.REMOVE = REMOVE;
5406
- visit.itemAtPath = (cst, path3) => {
5406
+ visit.itemAtPath = (cst, path4) => {
5407
5407
  let item = cst;
5408
- for (const [field, index] of path3) {
5408
+ for (const [field, index] of path4) {
5409
5409
  const tok = item?.[field];
5410
5410
  if (tok && "items" in tok) {
5411
5411
  item = tok.items[index];
@@ -5414,23 +5414,23 @@ var require_cst_visit = __commonJS({
5414
5414
  }
5415
5415
  return item;
5416
5416
  };
5417
- visit.parentCollection = (cst, path3) => {
5418
- const parent = visit.itemAtPath(cst, path3.slice(0, -1));
5419
- const field = path3[path3.length - 1][0];
5417
+ visit.parentCollection = (cst, path4) => {
5418
+ const parent = visit.itemAtPath(cst, path4.slice(0, -1));
5419
+ const field = path4[path4.length - 1][0];
5420
5420
  const coll = parent?.[field];
5421
5421
  if (coll && "items" in coll)
5422
5422
  return coll;
5423
5423
  throw new Error("Parent collection not found");
5424
5424
  };
5425
- function _visit(path3, item, visitor) {
5426
- let ctrl = visitor(item, path3);
5425
+ function _visit(path4, item, visitor) {
5426
+ let ctrl = visitor(item, path4);
5427
5427
  if (typeof ctrl === "symbol")
5428
5428
  return ctrl;
5429
5429
  for (const field of ["key", "value"]) {
5430
5430
  const token = item[field];
5431
5431
  if (token && "items" in token) {
5432
5432
  for (let i = 0; i < token.items.length; ++i) {
5433
- const ci = _visit(Object.freeze(path3.concat([[field, i]])), token.items[i], visitor);
5433
+ const ci = _visit(Object.freeze(path4.concat([[field, i]])), token.items[i], visitor);
5434
5434
  if (typeof ci === "number")
5435
5435
  i = ci - 1;
5436
5436
  else if (ci === BREAK)
@@ -5441,10 +5441,10 @@ var require_cst_visit = __commonJS({
5441
5441
  }
5442
5442
  }
5443
5443
  if (typeof ctrl === "function" && field === "key")
5444
- ctrl = ctrl(item, path3);
5444
+ ctrl = ctrl(item, path4);
5445
5445
  }
5446
5446
  }
5447
- return typeof ctrl === "function" ? ctrl(item, path3) : ctrl;
5447
+ return typeof ctrl === "function" ? ctrl(item, path4) : ctrl;
5448
5448
  }
5449
5449
  exports.visit = visit;
5450
5450
  }
@@ -6707,14 +6707,14 @@ var require_parser = __commonJS({
6707
6707
  case "scalar":
6708
6708
  case "single-quoted-scalar":
6709
6709
  case "double-quoted-scalar": {
6710
- const fs6 = this.flowScalar(this.type);
6710
+ const fs7 = this.flowScalar(this.type);
6711
6711
  if (atNextItem || it.value) {
6712
- map.items.push({ start, key: fs6, sep: [] });
6712
+ map.items.push({ start, key: fs7, sep: [] });
6713
6713
  this.onKeyLine = true;
6714
6714
  } else if (it.sep) {
6715
- this.stack.push(fs6);
6715
+ this.stack.push(fs7);
6716
6716
  } else {
6717
- Object.assign(it, { key: fs6, sep: [] });
6717
+ Object.assign(it, { key: fs7, sep: [] });
6718
6718
  this.onKeyLine = true;
6719
6719
  }
6720
6720
  return;
@@ -6832,13 +6832,13 @@ var require_parser = __commonJS({
6832
6832
  case "scalar":
6833
6833
  case "single-quoted-scalar":
6834
6834
  case "double-quoted-scalar": {
6835
- const fs6 = this.flowScalar(this.type);
6835
+ const fs7 = this.flowScalar(this.type);
6836
6836
  if (!it || it.value)
6837
- fc.items.push({ start: [], key: fs6, sep: [] });
6837
+ fc.items.push({ start: [], key: fs7, sep: [] });
6838
6838
  else if (it.sep)
6839
- this.stack.push(fs6);
6839
+ this.stack.push(fs7);
6840
6840
  else
6841
- Object.assign(it, { key: fs6, sep: [] });
6841
+ Object.assign(it, { key: fs7, sep: [] });
6842
6842
  return;
6843
6843
  }
6844
6844
  case "flow-map-end":
@@ -7143,13 +7143,12 @@ var require_dist = __commonJS({
7143
7143
  });
7144
7144
 
7145
7145
  // package.json
7146
- var version = "0.49.3";
7146
+ var version = "0.49.5";
7147
7147
 
7148
7148
  // node/commands/shared.ts
7149
7149
  import { existsSync, promises as fs } from "node:fs";
7150
7150
  import { join } from "node:path";
7151
7151
  import { loadConfigFromFile, mergeConfig, resolveConfig } from "vite";
7152
- import { isString } from "unocss";
7153
7152
  import MarkdownIt from "markdown-it";
7154
7153
  import { slash } from "@antfu/utils";
7155
7154
 
@@ -7202,8 +7201,8 @@ function updateFrontmatterPatch(slide, frontmatter) {
7202
7201
  const valueNode = doc.createNode(value);
7203
7202
  let found = false;
7204
7203
  import_yaml.default.visit(doc.contents, {
7205
- Pair(_key, node, path3) {
7206
- if (path3.length === 1 && import_yaml.default.isScalar(node.key) && node.key.value === key) {
7204
+ Pair(_key, node, path4) {
7205
+ if (path4.length === 1 && import_yaml.default.isScalar(node.key) && node.key.value === key) {
7207
7206
  node.value = valueNode;
7208
7207
  found = true;
7209
7208
  return import_yaml.default.visit.BREAK;
@@ -7224,12 +7223,11 @@ function updateFrontmatterPatch(slide, frontmatter) {
7224
7223
  // node/commands/shared.ts
7225
7224
  var sharedMd = MarkdownIt({ html: true });
7226
7225
  sharedMd.use(markdownItLink);
7227
- function getTitle(data) {
7228
- if (isString(data.config.title)) {
7229
- const tokens = sharedMd.parseInline(data.config.title, {});
7230
- return stringifyMarkdownTokens(tokens);
7231
- }
7232
- return data.config.title;
7226
+ function getSlideTitle(data) {
7227
+ const tokens = sharedMd.parseInline(data.config.title, {});
7228
+ const title = stringifyMarkdownTokens(tokens);
7229
+ const slideTitle = data.config.titleTemplate.replace("%s", title);
7230
+ return slideTitle === "Slidev - Slidev" ? "Slidev" : slideTitle;
7233
7231
  }
7234
7232
  function escapeHtml(unsafe) {
7235
7233
  return JSON.stringify(
@@ -7245,16 +7243,16 @@ async function getIndexHtml({ entry, clientRoot, roots, data }) {
7245
7243
  `<meta name="slidev:version" content="${version}">`,
7246
7244
  `<meta charset="slidev:entry" content="${slash(entry)}">`,
7247
7245
  `<link rel="icon" href="${data.config.favicon}">`,
7248
- `<title>${getTitle(data)}</title>`,
7246
+ `<title>${getSlideTitle(data)}</title>`,
7249
7247
  info && `<meta name="description" content=${escapeHtml(info)}>`,
7250
7248
  author && `<meta name="author" content=${escapeHtml(author)}>`,
7251
7249
  keywords && `<meta name="keywords" content=${escapeHtml(Array.isArray(keywords) ? keywords.join(", ") : keywords)}>`
7252
7250
  ].filter(Boolean).join("\n");
7253
7251
  for (const root of roots) {
7254
- const path3 = join(root, "index.html");
7255
- if (!existsSync(path3))
7252
+ const path4 = join(root, "index.html");
7253
+ if (!existsSync(path4))
7256
7254
  continue;
7257
- const index = await fs.readFile(path3, "utf-8");
7255
+ const index = await fs.readFile(path4, "utf-8");
7258
7256
  head += `
7259
7257
  ${(index.match(/<head>([\s\S]*?)<\/head>/i)?.[1] || "").trim()}`;
7260
7258
  body += `
@@ -7320,11 +7318,11 @@ async function loadDrawings(options) {
7320
7318
  suppressErrors: true
7321
7319
  });
7322
7320
  const obj = {};
7323
- await Promise.all(files.map(async (path3) => {
7324
- const num = +basename(path3, ".svg");
7321
+ await Promise.all(files.map(async (path4) => {
7322
+ const num = +basename(path4, ".svg");
7325
7323
  if (Number.isNaN(num))
7326
7324
  return;
7327
- const content = await fs2.readFile(path3, "utf8");
7325
+ const content = await fs2.readFile(path4, "utf8");
7328
7326
  const lines = content.split(/\n/g);
7329
7327
  obj[num.toString()] = lines.slice(1, -1).join("\n");
7330
7328
  }));
@@ -7552,6 +7550,7 @@ function getDefine(options) {
7552
7550
  __SLIDEV_FEATURE_DRAWINGS_PERSIST__: JSON.stringify(!!options.data.config.drawings.persist === true),
7553
7551
  __SLIDEV_FEATURE_RECORD__: JSON.stringify(options.data.config.record === true || options.data.config.record === options.mode),
7554
7552
  __SLIDEV_FEATURE_PRESENTER__: JSON.stringify(options.data.config.presenter === true || options.data.config.presenter === options.mode),
7553
+ __SLIDEV_FEATURE_PRINT__: JSON.stringify(options.mode === "export" || options.mode === "build" && [true, "true", "auto"].includes(options.data.config.download)),
7555
7554
  __SLIDEV_HAS_SERVER__: options.mode !== "build" ? "true" : "false"
7556
7555
  };
7557
7556
  }
@@ -7565,23 +7564,16 @@ import * as parser from "@slidev/parser/fs";
7565
7564
  import equal from "fast-deep-equal";
7566
7565
 
7567
7566
  // node/virtual/configs.ts
7568
- import { isString as isString2 } from "@antfu/utils";
7567
+ import { isString } from "@antfu/utils";
7569
7568
  var templateConfigs = {
7570
7569
  id: "/@slidev/configs",
7571
7570
  getContent: async ({ data, remote }, { md }) => {
7572
- function getTitle2() {
7573
- if (isString2(data.config.title)) {
7574
- const tokens = md.parseInline(data.config.title, {});
7575
- return stringifyMarkdownTokens(tokens);
7576
- }
7577
- return data.config.title;
7578
- }
7579
7571
  const config = {
7580
7572
  ...data.config,
7581
7573
  remote,
7582
- title: getTitle2()
7574
+ slidesTitle: getSlideTitle(data)
7583
7575
  };
7584
- if (isString2(config.info))
7576
+ if (isString(config.info))
7585
7577
  config.info = md.render(config.info);
7586
7578
  return `export default ${JSON.stringify(config)}`;
7587
7579
  }
@@ -7774,12 +7766,12 @@ function createSetupTemplate(name) {
7774
7766
  id: `/@slidev/setups/${name}`,
7775
7767
  getContent({ roots }) {
7776
7768
  const setups = roots.flatMap((i) => {
7777
- const path3 = join6(i, "setup", name);
7778
- return [".ts", ".mts", ".js", ".mjs"].map((ext) => path3 + ext);
7769
+ const path4 = join6(i, "setup", name);
7770
+ return [".ts", ".mts", ".js", ".mjs"].map((ext) => path4 + ext);
7779
7771
  }).filter((i) => existsSync3(i));
7780
7772
  const imports = [];
7781
- setups.forEach((path3, idx) => {
7782
- imports.push(`import __n${idx} from '${toAtFS(path3)}'`);
7773
+ setups.forEach((path4, idx) => {
7774
+ imports.push(`import __n${idx} from '${toAtFS(path4)}'`);
7783
7775
  });
7784
7776
  imports.push(`export default [${setups.map((_, idx) => `__n${idx}`).join(",")}]`);
7785
7777
  return imports.join("\n");
@@ -7798,9 +7790,9 @@ async function loadShikiSetups(clientRoot, roots) {
7798
7790
  "shiki.ts",
7799
7791
  {
7800
7792
  /** @deprecated */
7801
- async loadTheme(path3) {
7793
+ async loadTheme(path4) {
7802
7794
  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.");
7803
- return JSON.parse(await fs3.readFile(path3, "utf-8"));
7795
+ return JSON.parse(await fs3.readFile(path4, "utf-8"));
7804
7796
  }
7805
7797
  },
7806
7798
  {},
@@ -8866,11 +8858,11 @@ function markdownItVDrag(md, markdownTransformMap) {
8866
8858
  return `[${toOriginalPos(start)},${toOriginalPos(end)},${idx}]`;
8867
8859
  }
8868
8860
  return _parse.call(this, src, env).map((token) => {
8869
- if (token.type !== "html_block" || !token.content.includes("v-drag") || visited.has(token))
8861
+ if (!["html_block", "html_inline"].includes(token.type) || !token.content.includes("v-drag") || visited.has(token))
8870
8862
  return token;
8871
8863
  token.content = token.content.replace(
8872
- /<v-drag([\s>])/g,
8873
- (_, space, idx) => `<v-drag :markdownSource="${toMarkdownSource(token.map, idx)}"${space}`
8864
+ /<(v-?drag-?\w*)([\s>])/gi,
8865
+ (_, tag, space, idx) => `<${tag} :markdownSource="${toMarkdownSource(token.map, idx)}"${space}`
8874
8866
  ).replace(
8875
8867
  /(?<![</\w])v-drag(=".*?")?/g,
8876
8868
  (_, value, idx) => `v-drag${value ?? ""} :markdownSource="[${token.map[0]},${token.map[1]},${idx}]"`
@@ -8906,7 +8898,10 @@ ${code}
8906
8898
  import { codeToKeyedTokens } from "shiki-magic-move/core";
8907
8899
  import lz from "lz-string";
8908
8900
  var reMagicMoveBlock = /^````(?:md|markdown) magic-move(?: *(\{[^}]*\})?([^\n]*))?\n([\s\S]+?)^````$/gm;
8909
- function transformMagicMove(shiki, shikiOptions) {
8901
+ function parseLineNumbersOption(options) {
8902
+ return /lines: *true/.test(options) ? true : /lines: *false/.test(options) ? false : void 0;
8903
+ }
8904
+ function transformMagicMove(shiki, shikiOptions, configLineNumbers) {
8910
8905
  return (ctx) => {
8911
8906
  ctx.s.replace(
8912
8907
  reMagicMoveBlock,
@@ -8916,13 +8911,15 @@ function transformMagicMove(shiki, shikiOptions) {
8916
8911
  const matches = Array.from(body.matchAll(reCodeBlock));
8917
8912
  if (!matches.length)
8918
8913
  throw new Error("Magic Move block must contain at least one code block");
8914
+ const defaultLineNumbers = parseLineNumbersOption(options) ?? configLineNumbers;
8919
8915
  const ranges = matches.map((i) => normalizeRangeStr(i[2]));
8920
- const steps = matches.map(
8921
- (i) => codeToKeyedTokens(shiki, i[5].trimEnd(), {
8916
+ const steps = matches.map((i) => {
8917
+ const lineNumbers = parseLineNumbersOption(i[3]) ?? defaultLineNumbers;
8918
+ return codeToKeyedTokens(shiki, i[5].trimEnd(), {
8922
8919
  ...shikiOptions,
8923
8920
  lang: i[1]
8924
- })
8925
- );
8921
+ }, lineNumbers);
8922
+ });
8926
8923
  const compressed = lz.compressToBase64(JSON.stringify(steps));
8927
8924
  return `<ShikiMagicMove v-bind="${options}" steps-lz="${compressed}" :step-ranges='${JSON.stringify(ranges)}' />`;
8928
8925
  }
@@ -8959,9 +8956,45 @@ function transformPlantUml(ctx) {
8959
8956
  }
8960
8957
 
8961
8958
  // node/syntax/transform/snippet.ts
8962
- import path2 from "node:path";
8963
- import fs4 from "fs-extra";
8959
+ import path3 from "node:path";
8960
+ import lz3 from "lz-string";
8961
+ import fs5 from "fs-extra";
8964
8962
  import { slash as slash3 } from "@antfu/utils";
8963
+
8964
+ // node/vite/monacoWrite.ts
8965
+ import fs4 from "node:fs/promises";
8966
+ import path2 from "node:path";
8967
+ var monacoWriterWhitelist = /* @__PURE__ */ new Set();
8968
+ function createMonacoWriter({ userRoot }) {
8969
+ return {
8970
+ name: "slidev:monaco-write",
8971
+ apply: "serve",
8972
+ configureServer(server) {
8973
+ server.ws.on("connection", (socket) => {
8974
+ socket.on("message", async (data) => {
8975
+ let json;
8976
+ try {
8977
+ json = JSON.parse(data.toString());
8978
+ } catch (e) {
8979
+ return;
8980
+ }
8981
+ if (json.type === "custom" && json.event === "slidev:monaco-write") {
8982
+ const { file, content } = json.data;
8983
+ if (!monacoWriterWhitelist.has(file)) {
8984
+ console.error(`[Slidev] Unauthorized file write: ${file}`);
8985
+ return;
8986
+ }
8987
+ const filepath = path2.join(userRoot, file);
8988
+ console.log("[Slidev] Writing file:", filepath);
8989
+ await fs4.writeFile(filepath, content, "utf-8");
8990
+ }
8991
+ });
8992
+ });
8993
+ }
8994
+ };
8995
+ }
8996
+
8997
+ // node/syntax/transform/snippet.ts
8965
8998
  function dedent(text) {
8966
8999
  const lines = text.split("\n");
8967
9000
  const minIndentLength = lines.reduce((acc, line) => {
@@ -9020,21 +9053,20 @@ function transformSnippet(ctx) {
9020
9053
  return;
9021
9054
  const data = options.data;
9022
9055
  const slideInfo = data.slides[+slideId - 1];
9023
- const dir = path2.dirname(slideInfo.source?.filepath ?? options.entry ?? options.userRoot);
9056
+ const dir = path3.dirname(slideInfo.source?.filepath ?? options.entry ?? options.userRoot);
9024
9057
  ctx.s.replace(
9025
9058
  // eslint-disable-next-line regexp/no-super-linear-backtracking
9026
9059
  /^<<<\s*(\S.*?)(#[\w-]+)?\s*(?:\s(\S+?))?\s*(\{.*)?$/gm,
9027
9060
  (full, filepath = "", regionName = "", lang = "", meta = "") => {
9028
- const firstLine = `\`\`\`${lang || path2.extname(filepath).slice(1)} ${meta}`;
9029
9061
  const src = slash3(
9030
- /^@\//.test(filepath) ? path2.resolve(options.userRoot, filepath.slice(2)) : path2.resolve(dir, filepath)
9062
+ /^@\//.test(filepath) ? path3.resolve(options.userRoot, filepath.slice(2)) : path3.resolve(dir, filepath)
9031
9063
  );
9032
9064
  data.watchFiles.push(src);
9033
- const isAFile = fs4.statSync(src).isFile();
9034
- if (!fs4.existsSync(src) || !isAFile) {
9065
+ const isAFile = fs5.statSync(src).isFile();
9066
+ if (!fs5.existsSync(src) || !isAFile) {
9035
9067
  throw new Error(isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`);
9036
9068
  }
9037
- let content = fs4.readFileSync(src, "utf8");
9069
+ let content = fs5.readFileSync(src, "utf8");
9038
9070
  slideInfo.snippetsUsed ??= {};
9039
9071
  slideInfo.snippetsUsed[src] = content;
9040
9072
  if (regionName) {
@@ -9046,7 +9078,17 @@ function transformSnippet(ctx) {
9046
9078
  );
9047
9079
  }
9048
9080
  }
9049
- return `${firstLine}
9081
+ meta = meta.trim();
9082
+ lang = lang.trim();
9083
+ lang = lang || path3.extname(filepath).slice(1);
9084
+ if (meta.match(/^\{monaco-write\}/)) {
9085
+ monacoWriterWhitelist.add(filepath);
9086
+ lang = lang.trim();
9087
+ meta = meta.replace(/^\{monaco-write\}/, "").trim() || "{}";
9088
+ const encoded = lz3.compressToBase64(content);
9089
+ return `<Monaco writable=${JSON.stringify(filepath)} code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />`;
9090
+ }
9091
+ return `\`\`\`${lang} ${meta}
9050
9092
  ${content}
9051
9093
  \`\`\``;
9052
9094
  }
@@ -9101,7 +9143,7 @@ ${css}${end}`;
9101
9143
  }
9102
9144
 
9103
9145
  // node/syntax/transform/monaco.ts
9104
- import lz3 from "lz-string";
9146
+ import lz4 from "lz-string";
9105
9147
  function transformMonaco(ctx) {
9106
9148
  const enabled = ctx.options.data.config.monaco === true || ctx.options.data.config.monaco === ctx.options.mode;
9107
9149
  if (!enabled) {
@@ -9113,8 +9155,8 @@ function transformMonaco(ctx) {
9113
9155
  (full, lang = "ts", options = "{}", code, diff) => {
9114
9156
  lang = lang.trim();
9115
9157
  options = options.trim() || "{}";
9116
- const encoded = lz3.compressToBase64(code);
9117
- const encodedDiff = lz3.compressToBase64(diff);
9158
+ const encoded = lz4.compressToBase64(code);
9159
+ const encodedDiff = lz4.compressToBase64(diff);
9118
9160
  return `<Monaco code-lz="${encoded}" diff-lz="${encodedDiff}" lang="${lang}" v-bind="${options}" />`;
9119
9161
  }
9120
9162
  );
@@ -9123,7 +9165,7 @@ function transformMonaco(ctx) {
9123
9165
  (full, lang = "ts", options = "{}", code) => {
9124
9166
  lang = lang.trim();
9125
9167
  options = options.trim() || "{}";
9126
- const encoded = lz3.compressToBase64(code);
9168
+ const encoded = lz4.compressToBase64(code);
9127
9169
  return `<Monaco code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
9128
9170
  }
9129
9171
  );
@@ -9132,7 +9174,7 @@ function transformMonaco(ctx) {
9132
9174
  (full, lang = "ts", options = "{}", code) => {
9133
9175
  lang = lang.trim();
9134
9176
  options = options.trim() || "{}";
9135
- const encoded = lz3.compressToBase64(code);
9177
+ const encoded = lz4.compressToBase64(code);
9136
9178
  return `<Monaco runnable code-lz="${encoded}" lang="${lang}" v-bind="${options}" />`;
9137
9179
  }
9138
9180
  );
@@ -9275,7 +9317,7 @@ function MarkdownItEscapeInlineCode(md) {
9275
9317
  function applyMarkdownTransform(ctx, shiki, shikiOptions) {
9276
9318
  const transformers = [
9277
9319
  transformSnippet,
9278
- ctx.options.data.config.highlighter ? transformMagicMove(shiki, shikiOptions) : void 0,
9320
+ ctx.options.data.config.highlighter ? transformMagicMove(shiki, shikiOptions, ctx.options.data.config.lineNumbers) : void 0,
9279
9321
  transformMermaid,
9280
9322
  transformPlantUml,
9281
9323
  transformMonaco,
@@ -9317,7 +9359,7 @@ function createVueCompilerFlagsPlugin(options) {
9317
9359
  }
9318
9360
 
9319
9361
  // node/vite/monacoTypes.ts
9320
- import fs5 from "node:fs/promises";
9362
+ import fs6 from "node:fs/promises";
9321
9363
  import { dirname as dirname2, resolve as resolve4 } from "node:path";
9322
9364
  import { slash as slash5 } from "@antfu/utils";
9323
9365
  import fg4 from "fast-glob";
@@ -9343,7 +9385,7 @@ function createMonacoTypesLoader({ userRoot }) {
9343
9385
  if (!pkgJsonPath)
9344
9386
  throw new Error(`Package "${pkg}" not found in "${importer}"`);
9345
9387
  const root = dirname2(pkgJsonPath);
9346
- const pkgJson = JSON.parse(await fs5.readFile(pkgJsonPath, "utf-8"));
9388
+ const pkgJson = JSON.parse(await fs6.readFile(pkgJsonPath, "utf-8"));
9347
9389
  const deps = pkgJson.dependencies ?? {};
9348
9390
  return [
9349
9391
  `import "/@slidev-monaco-types/load?root=${slash5(root)}&name=${pkgJson.name}"`,
@@ -9456,6 +9498,7 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
9456
9498
  createMarkdownPlugin(options, pluginOptions),
9457
9499
  createVuePlugin(options, pluginOptions),
9458
9500
  createSlidesLoader(options, pluginOptions, serverOptions),
9501
+ createMonacoWriter(options),
9459
9502
  Components({
9460
9503
  extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
9461
9504
  dirs: [
package/dist/cli.mjs CHANGED
@@ -5,10 +5,10 @@ import {
5
5
  resolveAddons,
6
6
  resolveOptions,
7
7
  resolveTheme
8
- } from "./chunk-OL3F2SCP.mjs";
8
+ } from "./chunk-5LCF46EH.mjs";
9
9
  import {
10
10
  version
11
- } from "./chunk-NQBDNZ65.mjs";
11
+ } from "./chunk-TQT222QW.mjs";
12
12
  import {
13
13
  loadSetups
14
14
  } from "./chunk-LOUKLO2C.mjs";
@@ -168,6 +168,11 @@ cli.command(
168
168
  restartServer();
169
169
  return false;
170
170
  }
171
+ if (newData.features.katex && !oldData.features.katex || newData.features.monaco && !oldData.features.monaco) {
172
+ console.log(yellow("\n restarting on feature change\n"));
173
+ restartServer();
174
+ return false;
175
+ }
171
176
  return newData;
172
177
  }
173
178
  }
@@ -323,7 +328,7 @@ cli.command(
323
328
  }).strict().help(),
324
329
  async (args) => {
325
330
  const { entry, theme, base, download, out, inspect } = args;
326
- const { build } = await import("./build-B7KZ5KHE.mjs");
331
+ const { build } = await import("./build-KJ6XT4WV.mjs");
327
332
  for (const entryFile of entry) {
328
333
  const options = await resolveOptions({ entry: entryFile, theme, inspect }, "build");
329
334
  if (download && !options.data.config.download)
@@ -403,7 +408,7 @@ cli.command(
403
408
  (args) => exportOptions(commonOptions(args)).strict().help(),
404
409
  async (args) => {
405
410
  const { entry, theme } = args;
406
- const { exportSlides, getExportOptions } = await import("./export-WUI5C4U3.mjs");
411
+ const { exportSlides, getExportOptions } = await import("./export-Q4LURPEZ.mjs");
407
412
  const port = await getPort(12445);
408
413
  for (const entryFile of entry) {
409
414
  const options = await resolveOptions({ entry: entryFile, theme }, "export");
@@ -452,7 +457,7 @@ cli.command(
452
457
  timeout,
453
458
  wait
454
459
  }) => {
455
- const { exportNotes } = await import("./export-WUI5C4U3.mjs");
460
+ const { exportNotes } = await import("./export-Q4LURPEZ.mjs");
456
461
  const port = await getPort(12445);
457
462
  for (const entryFile of entry) {
458
463
  const options = await resolveOptions({ entry: entryFile }, "export");
@@ -496,7 +501,7 @@ function exportOptions(args) {
496
501
  describe: "path to the output"
497
502
  }).option("format", {
498
503
  type: "string",
499
- choices: ["pdf", "png", "md"],
504
+ choices: ["pdf", "png", "pptx", "md"],
500
505
  describe: "output format"
501
506
  }).option("timeout", {
502
507
  type: "number",
@@ -152,8 +152,7 @@ async function exportSlides({
152
152
  query.set("range", range);
153
153
  if (clicks)
154
154
  query.set("clicks", clicks);
155
- const path2 = `${no}?${query.toString()}`;
156
- const url = routerMode === "hash" ? `http://localhost:${port}${base}#${path2}` : `http://localhost:${port}${base}${path2}`;
155
+ const url = routerMode === "hash" ? `http://localhost:${port}${base}?${query}#${no}` : `http://localhost:${port}${base}${no}?${query}`;
157
156
  await page.goto(url, {
158
157
  waitUntil: "networkidle",
159
158
  timeout
@@ -228,13 +227,13 @@ async function exportSlides({
228
227
  function getClicksFromUrl(url) {
229
228
  return url.match(/clicks=([1-9]\d*)/)?.[1];
230
229
  }
231
- async function genPageWithClicks(fn, i, clicks) {
232
- await fn(i, clicks);
230
+ async function genPageWithClicks(fn, no, clicks) {
231
+ await fn(no, clicks);
233
232
  if (withClicks) {
234
233
  await page.keyboard.press("ArrowRight", { delay: 100 });
235
234
  const _clicks = getClicksFromUrl(page.url());
236
235
  if (_clicks && clicks !== _clicks)
237
- await genPageWithClicks(fn, i, _clicks);
236
+ await genPageWithClicks(fn, no, _clicks);
238
237
  }
239
238
  }
240
239
  async function genPagePdfPerSlide() {
@@ -298,50 +297,57 @@ async function exportSlides({
298
297
  pdfData = Buffer.from(await pdf.save());
299
298
  await fs.writeFile(output, pdfData);
300
299
  }
301
- async function genPagePngOnePiece() {
300
+ async function genPagePngOnePiece(writeToDisk) {
301
+ const result = [];
302
302
  await go("print");
303
303
  await fs.emptyDir(output);
304
- const slides2 = await page.locator(".print-slide-container");
305
- const count = await slides2.count();
304
+ const slideContainers = page.locator(".print-slide-container");
305
+ const count = await slideContainers.count();
306
306
  for (let i = 0; i < count; i++) {
307
307
  progress.update(i + 1);
308
- let id = await slides2.nth(i).getAttribute("id") || "";
309
- id = withClicks ? id : id.split("-")[0];
310
- const buffer = await slides2.nth(i).screenshot();
311
- await fs.writeFile(path.join(output, `${id}.png`), buffer);
308
+ const id = await slideContainers.nth(i).getAttribute("id") || "";
309
+ const slideNo = +id.split("-")[0];
310
+ const buffer = await slideContainers.nth(i).screenshot();
311
+ result.push({ slideIndex: slideNo - 1, buffer });
312
+ if (writeToDisk)
313
+ await fs.writeFile(path.join(output, `${withClicks ? id : slideNo}.png`), buffer);
312
314
  }
315
+ return result;
313
316
  }
314
- async function genPagePngPerSlide() {
315
- const genScreenshot = async (i, clicks) => {
316
- await go(i, clicks);
317
- await page.screenshot({
318
- omitBackground: false,
319
- path: path.join(
320
- output,
321
- `${i.toString().padStart(2, "0")}${clicks ? `-${clicks}` : ""}.png`
322
- )
323
- });
317
+ async function genPagePngPerSlide(writeToDisk) {
318
+ const result = [];
319
+ const genScreenshot = async (no, clicks) => {
320
+ await go(no, clicks);
321
+ const buffer = await page.screenshot();
322
+ result.push({ slideIndex: no - 1, buffer });
323
+ if (writeToDisk) {
324
+ await fs.writeFile(
325
+ path.join(output, `${no.toString().padStart(2, "0")}${clicks ? `-${clicks}` : ""}.png`),
326
+ buffer
327
+ );
328
+ }
324
329
  };
325
- for (const i of pages)
326
- await genPageWithClicks(genScreenshot, i);
330
+ for (const no of pages)
331
+ await genPageWithClicks(genScreenshot, no);
332
+ return result;
327
333
  }
328
334
  function genPagePdf() {
329
335
  if (!output.endsWith(".pdf"))
330
336
  output = `${output}.pdf`;
331
337
  return perSlide ? genPagePdfPerSlide() : genPagePdfOnePiece();
332
338
  }
333
- function genPagePng() {
334
- return perSlide ? genPagePngPerSlide() : genPagePngOnePiece();
339
+ function genPagePng(writeToDisk = true) {
340
+ return perSlide ? genPagePngPerSlide(writeToDisk) : genPagePngOnePiece(writeToDisk);
335
341
  }
336
- async function genPageMd(slides2) {
342
+ async function genPageMd() {
337
343
  const files = await fs.readdir(output);
338
344
  const mds = files.map((file, i, files2) => {
339
345
  const slideIndex = getSlideIndex(file);
340
- const mdImg = `![${slides2[slideIndex]?.title}](./${path.join(output, file)})
346
+ const mdImg = `![${slides[slideIndex]?.title}](./${path.join(output, file)})
341
347
 
342
348
  `;
343
- if ((i + 1 === files2.length || getSlideIndex(files2[i + 1]) !== slideIndex) && slides2[slideIndex]?.note)
344
- return `${mdImg}${slides2[slideIndex]?.note}
349
+ if ((i + 1 === files2.length || getSlideIndex(files2[i + 1]) !== slideIndex) && slides[slideIndex]?.note)
350
+ return `${mdImg}${slides[slideIndex]?.note}
345
351
 
346
352
  `;
347
353
  return mdImg;
@@ -350,6 +356,39 @@ async function exportSlides({
350
356
  output = `${output}.md`;
351
357
  await fs.writeFile(output, mds.join(""));
352
358
  }
359
+ async function genPagePptx(pngs) {
360
+ const { default: PptxGenJS } = await import("pptxgenjs");
361
+ const pptx = new PptxGenJS();
362
+ const layoutName = `${width}x${height}`;
363
+ pptx.defineLayout({
364
+ name: layoutName,
365
+ width: width / 96,
366
+ height: height / 96
367
+ });
368
+ pptx.layout = layoutName;
369
+ const titleSlide = slides[0];
370
+ pptx.author = titleSlide?.frontmatter?.author;
371
+ pptx.company = "Created using Slidev";
372
+ if (titleSlide?.title)
373
+ pptx.title = titleSlide?.title;
374
+ if (titleSlide?.frontmatter?.info)
375
+ pptx.subject = titleSlide?.frontmatter?.info;
376
+ pngs.forEach(({ slideIndex, buffer: buffer2 }) => {
377
+ const slide = pptx.addSlide();
378
+ slide.background = {
379
+ data: `data:image/png;base64,${buffer2.toString("base64")}`
380
+ };
381
+ const note = slides[slideIndex].note;
382
+ if (note)
383
+ slide.addNotes(note);
384
+ });
385
+ const buffer = await pptx.write({
386
+ outputType: "nodebuffer"
387
+ });
388
+ if (!output.endsWith(".pptx"))
389
+ output = `${output}.pptx`;
390
+ await fs.writeFile(output, buffer);
391
+ }
353
392
  function getSlideIndex(file) {
354
393
  const slideId = file.substring(0, file.indexOf(".")).split("-")[0];
355
394
  return Number(slideId) - 1;
@@ -386,7 +425,10 @@ async function exportSlides({
386
425
  await genPagePng();
387
426
  } else if (format === "md") {
388
427
  await genPagePng();
389
- await genPageMd(slides);
428
+ await genPageMd();
429
+ } else if (format === "pptx") {
430
+ const buffers = await genPagePng(false);
431
+ await genPagePptx(buffers);
390
432
  } else {
391
433
  throw new Error(`Unsupported exporting format "${format}"`);
392
434
  }
@@ -434,11 +476,11 @@ function getExportOptions(args, options, outDir, outFilename) {
434
476
  routerMode: options.data.config.routerMode,
435
477
  width: options.data.config.canvasWidth,
436
478
  height: Math.round(options.data.config.canvasWidth / options.data.config.aspectRatio),
437
- withClicks: withClicks || false,
479
+ withClicks: withClicks ?? format === "pptx",
438
480
  executablePath,
439
481
  withToc: withToc || false,
440
482
  perSlide: perSlide || false,
441
- scale: scale || 1
483
+ scale: scale || 2
442
484
  };
443
485
  }
444
486
  async function importPlaywright() {
package/dist/index.mjs CHANGED
@@ -2,10 +2,10 @@ import {
2
2
  createServer,
3
3
  parser,
4
4
  resolveOptions
5
- } from "./chunk-OL3F2SCP.mjs";
5
+ } from "./chunk-5LCF46EH.mjs";
6
6
  import {
7
7
  ViteSlidevPlugin
8
- } from "./chunk-NQBDNZ65.mjs";
8
+ } from "./chunk-TQT222QW.mjs";
9
9
  import "./chunk-LOUKLO2C.mjs";
10
10
  import "./chunk-RG2EEPCO.mjs";
11
11
  import "./chunk-BXO7ZPPU.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slidev/cli",
3
- "version": "0.49.3",
3
+ "version": "0.49.5",
4
4
  "description": "Presentation slides for developers",
5
5
  "author": "antfu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -44,15 +44,15 @@
44
44
  "dependencies": {
45
45
  "@antfu/ni": "^0.21.12",
46
46
  "@antfu/utils": "^0.7.8",
47
- "@iconify-json/carbon": "^1.1.33",
47
+ "@iconify-json/carbon": "^1.1.34",
48
48
  "@iconify-json/ph": "^1.1.13",
49
49
  "@iconify-json/svg-spinners": "^1.1.2",
50
50
  "@lillallol/outline-pdf": "^4.0.0",
51
- "@shikijs/markdown-it": "^1.5.2",
52
- "@shikijs/twoslash": "^1.5.2",
53
- "@shikijs/vitepress-twoslash": "^1.5.2",
54
- "@unocss/extractor-mdc": "^0.60.2",
55
- "@unocss/reset": "^0.60.2",
51
+ "@shikijs/markdown-it": "^1.6.1",
52
+ "@shikijs/twoslash": "^1.6.1",
53
+ "@shikijs/vitepress-twoslash": "^1.6.1",
54
+ "@unocss/extractor-mdc": "^0.60.3",
55
+ "@unocss/reset": "^0.60.3",
56
56
  "@vitejs/plugin-vue": "^5.0.4",
57
57
  "@vitejs/plugin-vue-jsx": "^3.1.0",
58
58
  "chokidar": "^3.6.0",
@@ -78,39 +78,40 @@
78
78
  "markdown-it-footnote": "^4.0.0",
79
79
  "markdown-it-mdc": "^0.2.3",
80
80
  "mlly": "^1.7.0",
81
- "monaco-editor": "^0.48.0",
81
+ "monaco-editor": "^0.49.0",
82
82
  "open": "^10.1.0",
83
83
  "pdf-lib": "^1.17.1",
84
84
  "plantuml-encoder": "^1.4.0",
85
85
  "postcss-nested": "^6.0.1",
86
+ "pptxgenjs": "^3.12.0",
86
87
  "prismjs": "^1.29.0",
87
88
  "prompts": "^2.4.2",
88
89
  "public-ip": "^6.0.2",
89
90
  "resolve-from": "^5.0.0",
90
91
  "resolve-global": "^2.0.0",
91
92
  "semver": "^7.6.2",
92
- "shiki": "^1.5.2",
93
+ "shiki": "^1.6.1",
93
94
  "shiki-magic-move": "^0.4.2",
94
95
  "sirv": "^2.0.4",
95
96
  "source-map-js": "^1.2.0",
96
97
  "typescript": "^5.4.5",
97
- "unocss": "^0.60.2",
98
+ "unocss": "^0.60.3",
98
99
  "unplugin-icons": "^0.19.0",
99
100
  "unplugin-vue-components": "^0.27.0",
100
101
  "unplugin-vue-markdown": "^0.26.2",
101
102
  "untun": "^0.1.3",
102
103
  "uqr": "^0.1.2",
103
- "vite": "^5.2.11",
104
+ "vite": "^5.2.12",
104
105
  "vite-plugin-inspect": "^0.8.4",
105
106
  "vite-plugin-remote-assets": "^0.4.1",
106
- "vite-plugin-static-copy": "^1.0.4",
107
+ "vite-plugin-static-copy": "^1.0.5",
107
108
  "vite-plugin-vue-server-ref": "^0.4.2",
108
109
  "vitefu": "^0.2.5",
109
110
  "vue": "^3.4.27",
110
111
  "yargs": "^17.7.2",
111
- "@slidev/client": "0.49.3",
112
- "@slidev/parser": "0.49.3",
113
- "@slidev/types": "0.49.3"
112
+ "@slidev/client": "0.49.5",
113
+ "@slidev/parser": "0.49.5",
114
+ "@slidev/types": "0.49.5"
114
115
  },
115
116
  "devDependencies": {
116
117
  "@hedgedoc/markdown-it-plugins": "^2.1.4",
package/template.md CHANGED
@@ -56,7 +56,7 @@ Slidev is a slides maker and presenter designed for developers, consist of the f
56
56
  - 🧑‍💻 **Developer Friendly** - code highlighting, live coding with autocompletion
57
57
  - 🤹 **Interactive** - embedding Vue components to enhance your expressions
58
58
  - 🎥 **Recording** - built-in recording and camera view
59
- - 📤 **Portable** - export into PDF, PNGs, or even a hostable SPA
59
+ - 📤 **Portable** - export into PDF, PPTX, PNGs, or even a hostable SPA
60
60
  - 🛠 **Hackable** - anything possible on a webpage
61
61
 
62
62
  <br>