@slidev/cli 0.38.7 → 0.38.8

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.
@@ -724,7 +724,7 @@ async function build(options, viteConfig = {}, args) {
724
724
  await fs2.writeFile(redirectsPath, `${config.base}* ${config.base}index.html 200
725
725
  `, "utf-8");
726
726
  if ([true, "true", "auto"].includes(options.data.config.download)) {
727
- const { exportSlides, getExportOptions } = await Promise.resolve().then(() => __toESM(__require("./export-LL3DLTJH.mjs")));
727
+ const { exportSlides, getExportOptions } = await Promise.resolve().then(() => __toESM(__require("./export-P6VFSLAQ.mjs")));
728
728
  const port = 12445;
729
729
  const app = connect();
730
730
  const server = http.createServer(app);
@@ -724,7 +724,7 @@ async function build(options, viteConfig = {}, args) {
724
724
  await _fsextra2.default.writeFile(redirectsPath, `${config.base}* ${config.base}index.html 200
725
725
  `, "utf-8");
726
726
  if ([true, "true", "auto"].includes(options.data.config.download)) {
727
- const { exportSlides, getExportOptions } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./export-BWNX2QVG.js")));
727
+ const { exportSlides, getExportOptions } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./export-2BM4EQEA.js")));
728
728
  const port = 12445;
729
729
  const app = _connect2.default.call(void 0, );
730
730
  const server = _http2.default.createServer(app);
@@ -2450,7 +2450,7 @@ _chunkOVFYMGU6js.init_cjs_shims.call(void 0, );
2450
2450
  var _fs = require('@slidev/parser/fs'); var parser = _interopRequireWildcard(_fs);
2451
2451
 
2452
2452
  // package.json
2453
- var version = "0.38.7";
2453
+ var version = "0.38.8";
2454
2454
 
2455
2455
  // node/themes.ts
2456
2456
  _chunkOVFYMGU6js.init_cjs_shims.call(void 0, );
@@ -2451,7 +2451,7 @@ init_esm_shims();
2451
2451
  import * as parser from "@slidev/parser/fs";
2452
2452
 
2453
2453
  // package.json
2454
- var version = "0.38.7";
2454
+ var version = "0.38.8";
2455
2455
 
2456
2456
  // node/themes.ts
2457
2457
  init_esm_shims();
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
 
11
11
 
12
- var _chunk35GWFKPPjs = require('./chunk-35GWFKPP.js');
12
+ var _chunkLC4O3TXIjs = require('./chunk-LC4O3TXI.js');
13
13
 
14
14
 
15
15
 
@@ -24,7 +24,6 @@ var _chunkOVFYMGU6js = require('./chunk-OVFYMGU6.js');
24
24
  _chunkOVFYMGU6js.init_cjs_shims.call(void 0, );
25
25
  var import_fast_deep_equal = _chunkOVFYMGU6js.__toESM.call(void 0, _chunkHHR7Q56Zjs.require_fast_deep_equal.call(void 0, ));
26
26
  var _path = require('path'); var _path2 = _interopRequireDefault(_path);
27
- var _net = require('net'); var _net2 = _interopRequireDefault(_net);
28
27
  var _os = require('os'); var _os2 = _interopRequireDefault(_os);
29
28
  var _child_process = require('child_process');
30
29
  var _readline = require('readline'); var readline = _interopRequireWildcard(_readline);
@@ -36,6 +35,7 @@ var _kolorist = require('kolorist');
36
35
  var _isinstalledglobally = require('is-installed-globally'); var _isinstalledglobally2 = _interopRequireDefault(_isinstalledglobally);
37
36
  var _parser = require('@slidev/parser');
38
37
  var _fs = require('@slidev/parser/fs');
38
+ var _getportplease = require('get-port-please');
39
39
  var CONFIG_RESTART_FIELDS = [
40
40
  "highlighter",
41
41
  "monaco",
@@ -47,14 +47,14 @@ _fs.injectPreparserExtensionLoader.call(void 0, async (headmatter, filepath) =>
47
47
  var _a;
48
48
  const addons = (_a = headmatter == null ? void 0 : headmatter.addons) != null ? _a : [];
49
49
  const roots = [
50
- _chunk35GWFKPPjs.getUserRoot.call(void 0, {}).userRoot,
51
- ..._chunk35GWFKPPjs.getAddonRoots.call(void 0, addons, ""),
52
- _chunk35GWFKPPjs.getClientRoot.call(void 0, )
50
+ _chunkLC4O3TXIjs.getUserRoot.call(void 0, {}).userRoot,
51
+ ..._chunkLC4O3TXIjs.getAddonRoots.call(void 0, addons, ""),
52
+ _chunkLC4O3TXIjs.getClientRoot.call(void 0, )
53
53
  ];
54
54
  const mergeArrays = (a, b) => a.concat(b);
55
55
  return await _chunkHHR7Q56Zjs.loadSetups.call(void 0, roots, "preparser.ts", { filepath, headmatter }, [], false, mergeArrays);
56
56
  });
57
- var cli = _yargs2.default.scriptName("slidev").usage("$0 [args]").version(_chunk35GWFKPPjs.version).strict().showHelpOnFail(false).alias("h", "help").alias("v", "version");
57
+ var cli = _yargs2.default.scriptName("slidev").usage("$0 [args]").version(_chunkLC4O3TXIjs.version).strict().showHelpOnFail(false).alias("h", "help").alias("v", "version");
58
58
  cli.command(
59
59
  "* [entry]",
60
60
  "Start a local server for Slidev",
@@ -105,9 +105,9 @@ cli.command(
105
105
  async function initServer() {
106
106
  if (server)
107
107
  await server.close();
108
- const options = await _chunk35GWFKPPjs.resolveOptions.call(void 0, { entry, remote, theme, inspect }, "dev");
108
+ const options = await _chunkLC4O3TXIjs.resolveOptions.call(void 0, { entry, remote, theme, inspect }, "dev");
109
109
  port = userPort || await findFreePort(3030);
110
- server = await _chunk35GWFKPPjs.createServer.call(void 0,
110
+ server = await _chunkLC4O3TXIjs.createServer.call(void 0,
111
111
  options,
112
112
  {
113
113
  server: {
@@ -121,7 +121,7 @@ cli.command(
121
121
  },
122
122
  {
123
123
  onDataReload(newData, data) {
124
- if (!theme && _chunk35GWFKPPjs.resolveThemeName.call(void 0, newData.config.theme) !== _chunk35GWFKPPjs.resolveThemeName.call(void 0, data.config.theme)) {
124
+ if (!theme && _chunkLC4O3TXIjs.resolveThemeName.call(void 0, newData.config.theme) !== _chunkLC4O3TXIjs.resolveThemeName.call(void 0, data.config.theme)) {
125
125
  console.log(_kolorist.yellow.call(void 0, "\n restarting on theme change\n"));
126
126
  initServer();
127
127
  } else if (CONFIG_RESTART_FIELDS.some((i) => !(0, import_fast_deep_equal.default)(newData.config[i], data.config[i]))) {
@@ -208,8 +208,8 @@ cli.command(
208
208
  }).strict().help(),
209
209
  async (args) => {
210
210
  const { entry, theme, watch, base, download, out, inspect } = args;
211
- const { build } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./build-S6XIJ3EO.js")));
212
- const options = await _chunk35GWFKPPjs.resolveOptions.call(void 0, { entry, theme, inspect }, "build");
211
+ const { build } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./build-XTITLXMQ.js")));
212
+ const options = await _chunkLC4O3TXIjs.resolveOptions.call(void 0, { entry, theme, inspect }, "build");
213
213
  if (download && !options.data.config.download)
214
214
  options.data.config.download = download;
215
215
  printInfo(options);
@@ -227,9 +227,9 @@ cli.command(
227
227
  "Format the markdown file",
228
228
  (args) => commonOptions(args).strict().help(),
229
229
  async ({ entry }) => {
230
- const data = await _chunk35GWFKPPjs.parser.load(entry);
231
- _chunk35GWFKPPjs.parser.prettify(data);
232
- await _chunk35GWFKPPjs.parser.save(data);
230
+ const data = await _chunkLC4O3TXIjs.parser.load(entry);
231
+ _chunkLC4O3TXIjs.parser.prettify(data);
232
+ await _chunkLC4O3TXIjs.parser.save(data);
233
233
  }
234
234
  );
235
235
  cli.command(
@@ -244,17 +244,17 @@ cli.command(
244
244
  default: "theme"
245
245
  }),
246
246
  async ({ entry, dir, theme: themeInput }) => {
247
- const data = await _chunk35GWFKPPjs.parser.load(entry);
248
- const theme = _chunk35GWFKPPjs.resolveThemeName.call(void 0, themeInput || data.config.theme);
247
+ const data = await _chunkLC4O3TXIjs.parser.load(entry);
248
+ const theme = _chunkLC4O3TXIjs.resolveThemeName.call(void 0, themeInput || data.config.theme);
249
249
  if (theme === "none") {
250
250
  console.error('Cannot eject theme "none"');
251
251
  process.exit(1);
252
252
  }
253
- if (_chunk35GWFKPPjs.isPath.call(void 0, theme)) {
253
+ if (_chunkLC4O3TXIjs.isPath.call(void 0, theme)) {
254
254
  console.error("Theme is already ejected");
255
255
  process.exit(1);
256
256
  }
257
- const roots = _chunk35GWFKPPjs.getThemeRoots.call(void 0, theme, entry);
257
+ const roots = _chunkLC4O3TXIjs.getThemeRoots.call(void 0, theme, entry);
258
258
  if (!roots.length) {
259
259
  console.error(`Could not find theme "${theme}"`);
260
260
  process.exit(1);
@@ -266,7 +266,7 @@ cli.command(
266
266
  const dirPath = `./${dir}`;
267
267
  data.slides[0].frontmatter.theme = dirPath;
268
268
  data.slides[0].raw = null;
269
- await _chunk35GWFKPPjs.parser.save(data);
269
+ await _chunkLC4O3TXIjs.parser.save(data);
270
270
  console.log(`Theme "${theme}" ejected successfully to "${dirPath}"`);
271
271
  }
272
272
  );
@@ -283,10 +283,10 @@ cli.command(
283
283
  async (args) => {
284
284
  const { entry, theme } = args;
285
285
  process.env.NODE_ENV = "production";
286
- const { exportSlides, getExportOptions } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./export-BWNX2QVG.js")));
286
+ const { exportSlides, getExportOptions } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./export-2BM4EQEA.js")));
287
287
  const port = await findFreePort(12445);
288
- const options = await _chunk35GWFKPPjs.resolveOptions.call(void 0, { entry, theme }, "export");
289
- const server = await _chunk35GWFKPPjs.createServer.call(void 0,
288
+ const options = await _chunkLC4O3TXIjs.resolveOptions.call(void 0, { entry, theme }, "export");
289
+ const server = await _chunkLC4O3TXIjs.createServer.call(void 0,
290
290
  options,
291
291
  {
292
292
  server: { port },
@@ -295,7 +295,7 @@ cli.command(
295
295
  );
296
296
  await server.listen(port);
297
297
  printInfo(options);
298
- _chunk35GWFKPPjs.parser.filterDisabled(options.data);
298
+ _chunkLC4O3TXIjs.parser.filterDisabled(options.data);
299
299
  const output = await exportSlides({
300
300
  port,
301
301
  ...getExportOptions(args, options)
@@ -327,12 +327,12 @@ cli.command(
327
327
  timeout
328
328
  }) => {
329
329
  process.env.NODE_ENV = "production";
330
- const { exportNotes } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./export-BWNX2QVG.js")));
330
+ const { exportNotes } = await Promise.resolve().then(() => _chunkOVFYMGU6js.__toESM.call(void 0, _chunkOVFYMGU6js.__require.call(void 0, "./export-2BM4EQEA.js")));
331
331
  const port = await findFreePort(12445);
332
- const options = await _chunk35GWFKPPjs.resolveOptions.call(void 0, { entry }, "export");
332
+ const options = await _chunkLC4O3TXIjs.resolveOptions.call(void 0, { entry }, "export");
333
333
  if (!output)
334
334
  output = options.data.config.exportFilename ? `${options.data.config.exportFilename}-notes` : `${_path2.default.basename(entry, ".md")}-export-notes`;
335
- const server = await _chunk35GWFKPPjs.createServer.call(void 0,
335
+ const server = await _chunkLC4O3TXIjs.createServer.call(void 0,
336
336
  options,
337
337
  {
338
338
  server: { port },
@@ -341,7 +341,7 @@ cli.command(
341
341
  );
342
342
  await server.listen(port);
343
343
  printInfo(options);
344
- _chunk35GWFKPPjs.parser.filterDisabled(options.data);
344
+ _chunkLC4O3TXIjs.parser.filterDisabled(options.data);
345
345
  output = await exportNotes({
346
346
  port,
347
347
  output,
@@ -392,13 +392,16 @@ function exportOptions(args) {
392
392
  }).option("with-toc", {
393
393
  type: "boolean",
394
394
  describe: "export pages with outline"
395
+ }).option("per-slide", {
396
+ type: "boolean",
397
+ describe: "slide slides slide by slide. Works better with global components, but will break cross slide links and TOC in PDF"
395
398
  });
396
399
  }
397
400
  function printInfo(options, port, remote) {
398
401
  console.log();
399
402
  console.log();
400
403
  console.log(` ${_kolorist.cyan.call(void 0, "\u25CF") + _kolorist.blue.call(void 0, "\u25A0") + _kolorist.yellow.call(void 0, "\u25B2")}`);
401
- console.log(`${_kolorist.bold.call(void 0, " Slidev")} ${_kolorist.blue.call(void 0, `v${_chunk35GWFKPPjs.version}`)} ${_isinstalledglobally2.default ? _kolorist.yellow.call(void 0, "(global)") : ""}`);
404
+ console.log(`${_kolorist.bold.call(void 0, " Slidev")} ${_kolorist.blue.call(void 0, `v${_chunkLC4O3TXIjs.version}`)} ${_isinstalledglobally2.default ? _kolorist.yellow.call(void 0, "(global)") : ""}`);
402
405
  console.log();
403
406
  console.log(_kolorist.dim.call(void 0, " theme ") + (options.theme ? _kolorist.green.call(void 0, options.theme) : _kolorist.gray.call(void 0, "none")));
404
407
  console.log(_kolorist.dim.call(void 0, " entry ") + _kolorist.dim.call(void 0, _path2.default.dirname(options.entry) + _path2.default.sep) + _path2.default.basename(options.entry));
@@ -428,24 +431,8 @@ function printInfo(options, port, remote) {
428
431
  _parser.verifyConfig.call(void 0, options.data.config, options.data.themeMeta, (v) => console.warn(_kolorist.yellow.call(void 0, ` ! ${v}`)));
429
432
  console.log();
430
433
  }
431
- function isPortFree(port) {
432
- return new Promise((resolve) => {
433
- const server = _net2.default.createServer((socket) => {
434
- socket.write("Echo server\r\n");
435
- socket.pipe(socket);
436
- });
437
- server.listen(port, "127.0.0.1");
438
- server.on("error", () => {
439
- resolve(false);
440
- });
441
- server.on("listening", () => {
442
- server.close();
443
- resolve(true);
444
- });
445
- });
446
- }
447
434
  async function findFreePort(start) {
448
- if (await isPortFree(start))
435
+ if (await _getportplease.checkPort.call(void 0, start) !== false)
449
436
  return start;
450
437
  return findFreePort(start + 1);
451
438
  }
package/dist/cli.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  resolveOptions,
10
10
  resolveThemeName,
11
11
  version
12
- } from "./chunk-5HOW7RNS.mjs";
12
+ } from "./chunk-S7VB5HAT.mjs";
13
13
  import {
14
14
  loadSetups,
15
15
  require_fast_deep_equal
@@ -25,7 +25,6 @@ import {
25
25
  init_esm_shims();
26
26
  var import_fast_deep_equal = __toESM(require_fast_deep_equal());
27
27
  import path from "path";
28
- import net from "net";
29
28
  import os from "os";
30
29
  import { exec } from "child_process";
31
30
  import * as readline from "readline";
@@ -37,6 +36,7 @@ import { blue, bold, cyan, dim, gray, green, underline, yellow } from "kolorist"
37
36
  import isInstalledGlobally from "is-installed-globally";
38
37
  import { verifyConfig } from "@slidev/parser";
39
38
  import { injectPreparserExtensionLoader } from "@slidev/parser/fs";
39
+ import { checkPort } from "get-port-please";
40
40
  var CONFIG_RESTART_FIELDS = [
41
41
  "highlighter",
42
42
  "monaco",
@@ -209,7 +209,7 @@ cli.command(
209
209
  }).strict().help(),
210
210
  async (args) => {
211
211
  const { entry, theme, watch, base, download, out, inspect } = args;
212
- const { build } = await Promise.resolve().then(() => __toESM(__require("./build-2WSKFKOA.mjs")));
212
+ const { build } = await Promise.resolve().then(() => __toESM(__require("./build-GNCYENZG.mjs")));
213
213
  const options = await resolveOptions({ entry, theme, inspect }, "build");
214
214
  if (download && !options.data.config.download)
215
215
  options.data.config.download = download;
@@ -284,7 +284,7 @@ cli.command(
284
284
  async (args) => {
285
285
  const { entry, theme } = args;
286
286
  process.env.NODE_ENV = "production";
287
- const { exportSlides, getExportOptions } = await Promise.resolve().then(() => __toESM(__require("./export-LL3DLTJH.mjs")));
287
+ const { exportSlides, getExportOptions } = await Promise.resolve().then(() => __toESM(__require("./export-P6VFSLAQ.mjs")));
288
288
  const port = await findFreePort(12445);
289
289
  const options = await resolveOptions({ entry, theme }, "export");
290
290
  const server = await createServer(
@@ -328,7 +328,7 @@ cli.command(
328
328
  timeout
329
329
  }) => {
330
330
  process.env.NODE_ENV = "production";
331
- const { exportNotes } = await Promise.resolve().then(() => __toESM(__require("./export-LL3DLTJH.mjs")));
331
+ const { exportNotes } = await Promise.resolve().then(() => __toESM(__require("./export-P6VFSLAQ.mjs")));
332
332
  const port = await findFreePort(12445);
333
333
  const options = await resolveOptions({ entry }, "export");
334
334
  if (!output)
@@ -393,6 +393,9 @@ function exportOptions(args) {
393
393
  }).option("with-toc", {
394
394
  type: "boolean",
395
395
  describe: "export pages with outline"
396
+ }).option("per-slide", {
397
+ type: "boolean",
398
+ describe: "slide slides slide by slide. Works better with global components, but will break cross slide links and TOC in PDF"
396
399
  });
397
400
  }
398
401
  function printInfo(options, port, remote) {
@@ -429,24 +432,8 @@ function printInfo(options, port, remote) {
429
432
  verifyConfig(options.data.config, options.data.themeMeta, (v) => console.warn(yellow(` ! ${v}`)));
430
433
  console.log();
431
434
  }
432
- function isPortFree(port) {
433
- return new Promise((resolve) => {
434
- const server = net.createServer((socket) => {
435
- socket.write("Echo server\r\n");
436
- socket.pipe(socket);
437
- });
438
- server.listen(port, "127.0.0.1");
439
- server.on("error", () => {
440
- resolve(false);
441
- });
442
- server.on("listening", () => {
443
- server.close();
444
- resolve(true);
445
- });
446
- });
447
- }
448
435
  async function findFreePort(start) {
449
- if (await isPortFree(start))
436
+ if (await checkPort(start) !== false)
450
437
  return start;
451
438
  return findFreePort(start + 1);
452
439
  }
@@ -122,7 +122,8 @@ async function exportSlides({
122
122
  height = 1080,
123
123
  withClicks = false,
124
124
  executablePath = void 0,
125
- withToc = false
125
+ withToc = false,
126
+ perSlide = false
126
127
  }) {
127
128
  if (!_chunkOVFYMGU6js.packageExists.call(void 0, "playwright-chromium"))
128
129
  throw new Error("The exporting for Slidev is powered by Playwright, please installed it via `npm i -D playwright-chromium`");
@@ -134,12 +135,12 @@ async function exportSlides({
134
135
  const context = await browser.newContext({
135
136
  viewport: {
136
137
  width,
137
- height: height * pages.length
138
+ height: perSlide ? height : height * pages.length
138
139
  },
139
140
  deviceScaleFactor: 1
140
141
  });
141
142
  const page = await context.newPage();
142
- const progress = createSlidevProgress(true);
143
+ const progress = createSlidevProgress(!perSlide);
143
144
  async function go(no, clicks) {
144
145
  const path2 = `${no}?print${withClicks ? "=clicks" : ""}${clicks ? `&clicks=${clicks}` : ""}${range ? `&range=${range}` : ""}`;
145
146
  const url = routerMode === "hash" ? `http://localhost:${port}${base}#${path2}` : `http://localhost:${port}${base}${path2}`;
@@ -149,20 +150,20 @@ async function exportSlides({
149
150
  });
150
151
  await page.waitForLoadState("networkidle");
151
152
  await page.emulateMedia({ colorScheme: dark ? "dark" : "light", media: "screen" });
152
- const elements = await page.locator("[data-waitfor]");
153
+ const elements = page.locator("[data-waitfor]");
153
154
  const count = await elements.count();
154
155
  for (let index = 0; index < count; index++) {
155
- const element = await elements.nth(index);
156
+ const element = elements.nth(index);
156
157
  const attribute = await element.getAttribute("data-waitfor");
157
158
  if (attribute)
158
159
  await element.locator(attribute).waitFor();
159
160
  }
160
- const frames = await page.frames();
161
+ const frames = page.frames();
161
162
  await Promise.all(frames.map((frame) => frame.waitForLoadState()));
162
163
  }
163
164
  async function getSlidesIndex() {
164
165
  const clicksBySlide = {};
165
- const slides2 = await page.locator(".slide-container");
166
+ const slides2 = page.locator(".print-slide-container");
166
167
  const count = await slides2.count();
167
168
  for (let i = 0; i < count; i++) {
168
169
  const id = await slides2.nth(i).getAttribute("id") || "";
@@ -176,10 +177,56 @@ async function exportSlides({
176
177
  }, []));
177
178
  return slideIndexes;
178
179
  }
179
- async function genPagePdf() {
180
+ function getClicksFromUrl(url) {
181
+ var _a;
182
+ return (_a = url.match(/clicks=([1-9][0-9]*)/)) == null ? void 0 : _a[1];
183
+ }
184
+ async function genPageWithClicks(fn, i, clicks) {
185
+ await fn(i, clicks);
186
+ if (withClicks) {
187
+ await page.keyboard.press("ArrowRight", { delay: 100 });
188
+ const _clicks = getClicksFromUrl(page.url());
189
+ if (_clicks && clicks !== _clicks)
190
+ await genPageWithClicks(fn, i, _clicks);
191
+ }
192
+ }
193
+ async function genPagePdfPerSlide() {
194
+ const buffers = [];
195
+ const genPdfBuffer = async (i, clicks) => {
196
+ await go(i, clicks);
197
+ const pdf = await page.pdf({
198
+ width,
199
+ height,
200
+ margin: {
201
+ left: 0,
202
+ top: 0,
203
+ right: 0,
204
+ bottom: 0
205
+ },
206
+ pageRanges: "1",
207
+ printBackground: true,
208
+ preferCSSPageSize: true
209
+ });
210
+ buffers.push(pdf);
211
+ };
212
+ let idx = 0;
213
+ for (const i of pages) {
214
+ await genPageWithClicks(genPdfBuffer, i);
215
+ progress.update(++idx);
216
+ }
217
+ const mergedPdf = await _pdflib.PDFDocument.create({});
218
+ for (const pdfBytes of buffers) {
219
+ const pdf = await _pdflib.PDFDocument.load(pdfBytes);
220
+ const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
221
+ copiedPages.forEach((page2) => {
222
+ mergedPdf.addPage(page2);
223
+ });
224
+ }
225
+ const buffer = await mergedPdf.save();
226
+ await _fsextra2.default.writeFile(output, buffer);
227
+ }
228
+ async function genPagePdfOnePiece() {
180
229
  var _a;
181
- if (!output.endsWith(".pdf"))
182
- output = `${output}.pdf`;
183
230
  await go("print");
184
231
  const slideIndexes = await getSlidesIndex();
185
232
  await page.pdf({
@@ -214,10 +261,10 @@ async function exportSlides({
214
261
  pdfData = Buffer.from(await pdf.save());
215
262
  await _fsextra2.default.writeFile(output, pdfData);
216
263
  }
217
- async function genPagePng() {
264
+ async function genPagePngOnePiece() {
218
265
  await go("print");
219
266
  await _fsextra2.default.emptyDir(output);
220
- const slides2 = await page.locator(".slide-container");
267
+ const slides2 = await page.locator(".print-slide-container");
221
268
  const count = await slides2.count();
222
269
  for (let i = 0; i < count; i++) {
223
270
  progress.update(i + 1);
@@ -227,6 +274,28 @@ async function exportSlides({
227
274
  await _fsextra2.default.writeFile(_path2.default.join(output, `${id}.png`), buffer);
228
275
  }
229
276
  }
277
+ async function genPagePngPerSlide() {
278
+ const genScreenshot = async (i, clicks) => {
279
+ await go(i, clicks);
280
+ await page.screenshot({
281
+ omitBackground: false,
282
+ path: _path2.default.join(
283
+ output,
284
+ `${i.toString().padStart(2, "0")}${clicks ? `-${clicks}` : ""}.png`
285
+ )
286
+ });
287
+ };
288
+ for (const i of pages)
289
+ await genPageWithClicks(genScreenshot, i);
290
+ }
291
+ function genPagePdf() {
292
+ if (!output.endsWith(".pdf"))
293
+ output = `${output}.pdf`;
294
+ return perSlide ? genPagePdfPerSlide() : genPagePdfOnePiece();
295
+ }
296
+ function genPagePng() {
297
+ return perSlide ? genPagePngPerSlide() : genPagePngOnePiece();
298
+ }
230
299
  async function genPageMd(slides2) {
231
300
  const files = await _fsextra2.default.readdir(output);
232
301
  const mds = files.map((file, i, files2) => {
@@ -270,7 +339,8 @@ function getExportOptions(args, options, outDir, outFilename) {
270
339
  ...args,
271
340
  withClicks: args["with-clicks"],
272
341
  executablePath: args["executable-path"],
273
- withToc: args["with-toc"]
342
+ withToc: args["with-toc"],
343
+ perSlide: args["per-slide"]
274
344
  };
275
345
  const {
276
346
  entry,
@@ -281,7 +351,8 @@ function getExportOptions(args, options, outDir, outFilename) {
281
351
  dark,
282
352
  withClicks,
283
353
  executablePath,
284
- withToc
354
+ withToc,
355
+ perSlide
285
356
  } = config;
286
357
  outFilename = output || options.data.config.exportFilename || outFilename || `${_path2.default.basename(entry, ".md")}-export`;
287
358
  if (outDir)
@@ -292,14 +363,15 @@ function getExportOptions(args, options, outDir, outFilename) {
292
363
  total: options.data.slides.length,
293
364
  range,
294
365
  format: format || "pdf",
295
- timeout: timeout || 3e4,
366
+ timeout: timeout != null ? timeout : 3e4,
296
367
  dark: dark || options.data.config.colorSchema === "dark",
297
368
  routerMode: options.data.config.routerMode,
298
369
  width: options.data.config.canvasWidth,
299
370
  height: Math.round(options.data.config.canvasWidth / options.data.config.aspectRatio),
300
371
  withClicks: withClicks || false,
301
372
  executablePath,
302
- withToc: withToc || false
373
+ withToc: withToc || false,
374
+ perSlide: perSlide || false
303
375
  };
304
376
  }
305
377
 
@@ -122,7 +122,8 @@ async function exportSlides({
122
122
  height = 1080,
123
123
  withClicks = false,
124
124
  executablePath = void 0,
125
- withToc = false
125
+ withToc = false,
126
+ perSlide = false
126
127
  }) {
127
128
  if (!packageExists("playwright-chromium"))
128
129
  throw new Error("The exporting for Slidev is powered by Playwright, please installed it via `npm i -D playwright-chromium`");
@@ -134,12 +135,12 @@ async function exportSlides({
134
135
  const context = await browser.newContext({
135
136
  viewport: {
136
137
  width,
137
- height: height * pages.length
138
+ height: perSlide ? height : height * pages.length
138
139
  },
139
140
  deviceScaleFactor: 1
140
141
  });
141
142
  const page = await context.newPage();
142
- const progress = createSlidevProgress(true);
143
+ const progress = createSlidevProgress(!perSlide);
143
144
  async function go(no, clicks) {
144
145
  const path2 = `${no}?print${withClicks ? "=clicks" : ""}${clicks ? `&clicks=${clicks}` : ""}${range ? `&range=${range}` : ""}`;
145
146
  const url = routerMode === "hash" ? `http://localhost:${port}${base}#${path2}` : `http://localhost:${port}${base}${path2}`;
@@ -149,20 +150,20 @@ async function exportSlides({
149
150
  });
150
151
  await page.waitForLoadState("networkidle");
151
152
  await page.emulateMedia({ colorScheme: dark ? "dark" : "light", media: "screen" });
152
- const elements = await page.locator("[data-waitfor]");
153
+ const elements = page.locator("[data-waitfor]");
153
154
  const count = await elements.count();
154
155
  for (let index = 0; index < count; index++) {
155
- const element = await elements.nth(index);
156
+ const element = elements.nth(index);
156
157
  const attribute = await element.getAttribute("data-waitfor");
157
158
  if (attribute)
158
159
  await element.locator(attribute).waitFor();
159
160
  }
160
- const frames = await page.frames();
161
+ const frames = page.frames();
161
162
  await Promise.all(frames.map((frame) => frame.waitForLoadState()));
162
163
  }
163
164
  async function getSlidesIndex() {
164
165
  const clicksBySlide = {};
165
- const slides2 = await page.locator(".slide-container");
166
+ const slides2 = page.locator(".print-slide-container");
166
167
  const count = await slides2.count();
167
168
  for (let i = 0; i < count; i++) {
168
169
  const id = await slides2.nth(i).getAttribute("id") || "";
@@ -176,10 +177,56 @@ async function exportSlides({
176
177
  }, []));
177
178
  return slideIndexes;
178
179
  }
179
- async function genPagePdf() {
180
+ function getClicksFromUrl(url) {
181
+ var _a;
182
+ return (_a = url.match(/clicks=([1-9][0-9]*)/)) == null ? void 0 : _a[1];
183
+ }
184
+ async function genPageWithClicks(fn, i, clicks) {
185
+ await fn(i, clicks);
186
+ if (withClicks) {
187
+ await page.keyboard.press("ArrowRight", { delay: 100 });
188
+ const _clicks = getClicksFromUrl(page.url());
189
+ if (_clicks && clicks !== _clicks)
190
+ await genPageWithClicks(fn, i, _clicks);
191
+ }
192
+ }
193
+ async function genPagePdfPerSlide() {
194
+ const buffers = [];
195
+ const genPdfBuffer = async (i, clicks) => {
196
+ await go(i, clicks);
197
+ const pdf = await page.pdf({
198
+ width,
199
+ height,
200
+ margin: {
201
+ left: 0,
202
+ top: 0,
203
+ right: 0,
204
+ bottom: 0
205
+ },
206
+ pageRanges: "1",
207
+ printBackground: true,
208
+ preferCSSPageSize: true
209
+ });
210
+ buffers.push(pdf);
211
+ };
212
+ let idx = 0;
213
+ for (const i of pages) {
214
+ await genPageWithClicks(genPdfBuffer, i);
215
+ progress.update(++idx);
216
+ }
217
+ const mergedPdf = await PDFDocument.create({});
218
+ for (const pdfBytes of buffers) {
219
+ const pdf = await PDFDocument.load(pdfBytes);
220
+ const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
221
+ copiedPages.forEach((page2) => {
222
+ mergedPdf.addPage(page2);
223
+ });
224
+ }
225
+ const buffer = await mergedPdf.save();
226
+ await fs.writeFile(output, buffer);
227
+ }
228
+ async function genPagePdfOnePiece() {
180
229
  var _a;
181
- if (!output.endsWith(".pdf"))
182
- output = `${output}.pdf`;
183
230
  await go("print");
184
231
  const slideIndexes = await getSlidesIndex();
185
232
  await page.pdf({
@@ -214,10 +261,10 @@ async function exportSlides({
214
261
  pdfData = Buffer.from(await pdf.save());
215
262
  await fs.writeFile(output, pdfData);
216
263
  }
217
- async function genPagePng() {
264
+ async function genPagePngOnePiece() {
218
265
  await go("print");
219
266
  await fs.emptyDir(output);
220
- const slides2 = await page.locator(".slide-container");
267
+ const slides2 = await page.locator(".print-slide-container");
221
268
  const count = await slides2.count();
222
269
  for (let i = 0; i < count; i++) {
223
270
  progress.update(i + 1);
@@ -227,6 +274,28 @@ async function exportSlides({
227
274
  await fs.writeFile(path.join(output, `${id}.png`), buffer);
228
275
  }
229
276
  }
277
+ async function genPagePngPerSlide() {
278
+ const genScreenshot = async (i, clicks) => {
279
+ await go(i, clicks);
280
+ await page.screenshot({
281
+ omitBackground: false,
282
+ path: path.join(
283
+ output,
284
+ `${i.toString().padStart(2, "0")}${clicks ? `-${clicks}` : ""}.png`
285
+ )
286
+ });
287
+ };
288
+ for (const i of pages)
289
+ await genPageWithClicks(genScreenshot, i);
290
+ }
291
+ function genPagePdf() {
292
+ if (!output.endsWith(".pdf"))
293
+ output = `${output}.pdf`;
294
+ return perSlide ? genPagePdfPerSlide() : genPagePdfOnePiece();
295
+ }
296
+ function genPagePng() {
297
+ return perSlide ? genPagePngPerSlide() : genPagePngOnePiece();
298
+ }
230
299
  async function genPageMd(slides2) {
231
300
  const files = await fs.readdir(output);
232
301
  const mds = files.map((file, i, files2) => {
@@ -270,7 +339,8 @@ function getExportOptions(args, options, outDir, outFilename) {
270
339
  ...args,
271
340
  withClicks: args["with-clicks"],
272
341
  executablePath: args["executable-path"],
273
- withToc: args["with-toc"]
342
+ withToc: args["with-toc"],
343
+ perSlide: args["per-slide"]
274
344
  };
275
345
  const {
276
346
  entry,
@@ -281,7 +351,8 @@ function getExportOptions(args, options, outDir, outFilename) {
281
351
  dark,
282
352
  withClicks,
283
353
  executablePath,
284
- withToc
354
+ withToc,
355
+ perSlide
285
356
  } = config;
286
357
  outFilename = output || options.data.config.exportFilename || outFilename || `${path.basename(entry, ".md")}-export`;
287
358
  if (outDir)
@@ -292,14 +363,15 @@ function getExportOptions(args, options, outDir, outFilename) {
292
363
  total: options.data.slides.length,
293
364
  range,
294
365
  format: format || "pdf",
295
- timeout: timeout || 3e4,
366
+ timeout: timeout != null ? timeout : 3e4,
296
367
  dark: dark || options.data.config.colorSchema === "dark",
297
368
  routerMode: options.data.config.routerMode,
298
369
  width: options.data.config.canvasWidth,
299
370
  height: Math.round(options.data.config.canvasWidth / options.data.config.aspectRatio),
300
371
  withClicks: withClicks || false,
301
372
  executablePath,
302
- withToc: withToc || false
373
+ withToc: withToc || false,
374
+ perSlide: perSlide || false
303
375
  };
304
376
  }
305
377
  export {
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
 
11
11
 
12
- var _chunk35GWFKPPjs = require('./chunk-35GWFKPP.js');
12
+ var _chunkLC4O3TXIjs = require('./chunk-LC4O3TXI.js');
13
13
 
14
14
 
15
15
 
@@ -36,4 +36,4 @@ _chunkOVFYMGU6js.init_cjs_shims.call(void 0, );
36
36
 
37
37
 
38
38
 
39
- exports.ViteSlidevPlugin = _chunkHHR7Q56Zjs.ViteSlidevPlugin; exports.createServer = _chunk35GWFKPPjs.createServer; exports.createWindiCSSPlugin = _chunkHHR7Q56Zjs.createWindiCSSPlugin; exports.getAddonRoots = _chunk35GWFKPPjs.getAddonRoots; exports.getCLIRoot = _chunk35GWFKPPjs.getCLIRoot; exports.getClientRoot = _chunk35GWFKPPjs.getClientRoot; exports.getRoot = _chunk35GWFKPPjs.getRoot; exports.getThemeRoots = _chunk35GWFKPPjs.getThemeRoots; exports.getUserRoot = _chunk35GWFKPPjs.getUserRoot; exports.isPath = _chunk35GWFKPPjs.isPath; exports.parser = _chunk35GWFKPPjs.parser; exports.resolveOptions = _chunk35GWFKPPjs.resolveOptions;
39
+ exports.ViteSlidevPlugin = _chunkHHR7Q56Zjs.ViteSlidevPlugin; exports.createServer = _chunkLC4O3TXIjs.createServer; exports.createWindiCSSPlugin = _chunkHHR7Q56Zjs.createWindiCSSPlugin; exports.getAddonRoots = _chunkLC4O3TXIjs.getAddonRoots; exports.getCLIRoot = _chunkLC4O3TXIjs.getCLIRoot; exports.getClientRoot = _chunkLC4O3TXIjs.getClientRoot; exports.getRoot = _chunkLC4O3TXIjs.getRoot; exports.getThemeRoots = _chunkLC4O3TXIjs.getThemeRoots; exports.getUserRoot = _chunkLC4O3TXIjs.getUserRoot; exports.isPath = _chunkLC4O3TXIjs.isPath; exports.parser = _chunkLC4O3TXIjs.parser; exports.resolveOptions = _chunkLC4O3TXIjs.resolveOptions;
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  isPath,
10
10
  parser,
11
11
  resolveOptions
12
- } from "./chunk-5HOW7RNS.mjs";
12
+ } from "./chunk-S7VB5HAT.mjs";
13
13
  import {
14
14
  ViteSlidevPlugin,
15
15
  createWindiCSSPlugin
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slidev/cli",
3
- "version": "0.38.7",
3
+ "version": "0.38.8",
4
4
  "description": "Presentation slides for developers",
5
5
  "author": "antfu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -56,6 +56,7 @@
56
56
  "debug": "^4.3.4",
57
57
  "fast-glob": "^3.2.12",
58
58
  "fs-extra": "^11.1.0",
59
+ "get-port-please": "^3.0.1",
59
60
  "global-dirs": "^3.0.1",
60
61
  "import-from": "^4.0.0",
61
62
  "is-installed-globally": "^0.4.0",
@@ -90,9 +91,9 @@
90
91
  "vue": "^3.2.45",
91
92
  "windicss": "^3.5.6",
92
93
  "yargs": "^17.6.2",
93
- "@slidev/client": "0.38.7",
94
- "@slidev/parser": "0.38.7",
95
- "@slidev/types": "0.38.7"
94
+ "@slidev/client": "0.38.8",
95
+ "@slidev/parser": "0.38.8",
96
+ "@slidev/types": "0.38.8"
96
97
  },
97
98
  "devDependencies": {
98
99
  "@types/plantuml-encoder": "^1.4.0",