@ncukondo/slide-generation 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +74 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1688,7 +1688,7 @@ var Pipeline = class {
|
|
|
1688
1688
|
};
|
|
1689
1689
|
|
|
1690
1690
|
// src/index.ts
|
|
1691
|
-
var VERSION = "0.
|
|
1691
|
+
var VERSION = "0.6.0";
|
|
1692
1692
|
|
|
1693
1693
|
// src/cli/commands/convert.ts
|
|
1694
1694
|
import { Command } from "commander";
|
|
@@ -3376,6 +3376,48 @@ function getMarpCommand(projectDir) {
|
|
|
3376
3376
|
function isMarpAvailable(projectDir) {
|
|
3377
3377
|
return getMarpCommand(projectDir) !== null;
|
|
3378
3378
|
}
|
|
3379
|
+
function parseMarpBrowserError(errorOutput) {
|
|
3380
|
+
const output = errorOutput.toLowerCase();
|
|
3381
|
+
if (output.includes("no suitable browser found")) {
|
|
3382
|
+
return {
|
|
3383
|
+
type: "browser_not_found",
|
|
3384
|
+
message: "No browser found for taking screenshots",
|
|
3385
|
+
suggestion: `Install a browser using one of these methods:
|
|
3386
|
+
1. Run: npx puppeteer browsers install chrome
|
|
3387
|
+
2. Install Chrome/Chromium system-wide
|
|
3388
|
+
3. Set CHROME_PATH environment variable to your browser path`
|
|
3389
|
+
};
|
|
3390
|
+
}
|
|
3391
|
+
if (output.includes("snap to be installed") || output.includes("requires the chromium snap")) {
|
|
3392
|
+
return {
|
|
3393
|
+
type: "snap_not_available",
|
|
3394
|
+
message: "Snap packages are not available in this environment (Docker/devcontainer)",
|
|
3395
|
+
suggestion: `Use Puppeteer's bundled Chrome instead:
|
|
3396
|
+
1. Run: npx puppeteer browsers install chrome
|
|
3397
|
+
2. Set: export PUPPETEER_ARGS="--no-sandbox --disable-setuid-sandbox"`
|
|
3398
|
+
};
|
|
3399
|
+
}
|
|
3400
|
+
if (output.includes("error while loading shared libraries") || output.includes("cannot open shared object file")) {
|
|
3401
|
+
const libMatch = errorOutput.match(/lib[\w.-]+\.so[\d.]*/i);
|
|
3402
|
+
const libName = libMatch ? libMatch[0] : "unknown library";
|
|
3403
|
+
return {
|
|
3404
|
+
type: "missing_libraries",
|
|
3405
|
+
message: `Missing Chrome dependency: ${libName}`,
|
|
3406
|
+
suggestion: `Install required libraries:
|
|
3407
|
+
sudo apt-get install -y libnss3 libatk-bridge2.0-0 libdrm2 libxkbcommon0 \\
|
|
3408
|
+
libgbm1 libasound2t64 libxfixes3 fonts-noto-cjk`
|
|
3409
|
+
};
|
|
3410
|
+
}
|
|
3411
|
+
if (output.includes("target closed") || output.includes("targetcloseerror") || output.includes("no-sandbox")) {
|
|
3412
|
+
return {
|
|
3413
|
+
type: "sandbox_error",
|
|
3414
|
+
message: "Chrome sandbox error (common in container environments)",
|
|
3415
|
+
suggestion: `Disable sandbox mode:
|
|
3416
|
+
export PUPPETEER_ARGS="--no-sandbox --disable-setuid-sandbox"`
|
|
3417
|
+
};
|
|
3418
|
+
}
|
|
3419
|
+
return null;
|
|
3420
|
+
}
|
|
3379
3421
|
function runMarp(args, options = {}) {
|
|
3380
3422
|
const { projectDir, ...execOptions } = options;
|
|
3381
3423
|
const marpCmd = getMarpCommand(projectDir);
|
|
@@ -8191,7 +8233,7 @@ function parseBlurSpec(spec) {
|
|
|
8191
8233
|
|
|
8192
8234
|
// src/cli/commands/screenshot.ts
|
|
8193
8235
|
import { Command as Command9 } from "commander";
|
|
8194
|
-
import { access as access12, mkdir as mkdir9, readdir as readdir7, unlink as unlink2 } from "fs/promises";
|
|
8236
|
+
import { access as access12, mkdir as mkdir9, readdir as readdir7, rename as rename2, unlink as unlink2 } from "fs/promises";
|
|
8195
8237
|
import { basename as basename10, dirname as dirname10, extname as extname5, join as join19 } from "path";
|
|
8196
8238
|
import chalk9 from "chalk";
|
|
8197
8239
|
import ora4 from "ora";
|
|
@@ -8225,6 +8267,20 @@ async function filterToSpecificSlide(outputDir, baseName, slideNumber, format) {
|
|
|
8225
8267
|
function checkMarpCliAvailable2(projectDir) {
|
|
8226
8268
|
return isMarpAvailable(projectDir);
|
|
8227
8269
|
}
|
|
8270
|
+
async function ensureFileExtensions(outputDir, baseName, format) {
|
|
8271
|
+
const files = await readdir7(outputDir);
|
|
8272
|
+
const slidePattern = /\.(\d{3})$/;
|
|
8273
|
+
const renamedFiles = [];
|
|
8274
|
+
for (const file of files) {
|
|
8275
|
+
if (file.startsWith(baseName) && slidePattern.test(file)) {
|
|
8276
|
+
const oldPath = join19(outputDir, file);
|
|
8277
|
+
const newPath = join19(outputDir, `${file}.${format}`);
|
|
8278
|
+
await rename2(oldPath, newPath);
|
|
8279
|
+
renamedFiles.push(`${file}.${format}`);
|
|
8280
|
+
}
|
|
8281
|
+
}
|
|
8282
|
+
return renamedFiles;
|
|
8283
|
+
}
|
|
8228
8284
|
function estimateTokens(width, height) {
|
|
8229
8285
|
return Math.ceil(width * height / 750);
|
|
8230
8286
|
}
|
|
@@ -8437,9 +8493,19 @@ async function executeScreenshot(inputPath, options) {
|
|
|
8437
8493
|
spinner?.succeed(`Screenshots saved to ${outputDir}`);
|
|
8438
8494
|
} catch (error) {
|
|
8439
8495
|
spinner?.fail("Failed to take screenshots");
|
|
8440
|
-
const
|
|
8441
|
-
|
|
8442
|
-
|
|
8496
|
+
const errorOutput = error instanceof Error ? error.message : String(error);
|
|
8497
|
+
const browserError = parseMarpBrowserError(errorOutput);
|
|
8498
|
+
if (browserError) {
|
|
8499
|
+
console.error(chalk9.red(`
|
|
8500
|
+
Error: ${browserError.message}
|
|
8501
|
+
`));
|
|
8502
|
+
console.error(chalk9.yellow(browserError.suggestion));
|
|
8503
|
+
errors.push(browserError.message);
|
|
8504
|
+
} else {
|
|
8505
|
+
const message = error instanceof Error ? error.message : "Marp CLI failed";
|
|
8506
|
+
console.error(chalk9.red(`Error: ${message}`));
|
|
8507
|
+
errors.push(message);
|
|
8508
|
+
}
|
|
8443
8509
|
process.exitCode = ExitCode.GeneralError;
|
|
8444
8510
|
await cleanupTempFile();
|
|
8445
8511
|
return { success: false, errors };
|
|
@@ -8448,12 +8514,13 @@ async function executeScreenshot(inputPath, options) {
|
|
|
8448
8514
|
const actualFormat = isAiFormat ? "jpeg" : options.format || "png";
|
|
8449
8515
|
let actualWidth = isAiFormat ? 640 : options.width || 1280;
|
|
8450
8516
|
let actualHeight = Math.round(actualWidth * 9 / 16);
|
|
8517
|
+
const mdBaseName = basename10(tempMdPath, ".md");
|
|
8518
|
+
await ensureFileExtensions(outputDir, mdBaseName, actualFormat);
|
|
8451
8519
|
if (options.slide !== void 0) {
|
|
8452
8520
|
spinner?.start(`Filtering to slide ${options.slide}...`);
|
|
8453
|
-
const mdBaseName2 = basename10(tempMdPath, ".md");
|
|
8454
8521
|
const filterResult = await filterToSpecificSlide(
|
|
8455
8522
|
outputDir,
|
|
8456
|
-
|
|
8523
|
+
mdBaseName,
|
|
8457
8524
|
options.slide,
|
|
8458
8525
|
actualFormat
|
|
8459
8526
|
);
|
|
@@ -8468,7 +8535,6 @@ async function executeScreenshot(inputPath, options) {
|
|
|
8468
8535
|
spinner?.succeed(`Kept slide ${options.slide}: ${filterResult.keptFile}`);
|
|
8469
8536
|
}
|
|
8470
8537
|
const allFiles = await readdir7(outputDir);
|
|
8471
|
-
const mdBaseName = basename10(tempMdPath, ".md");
|
|
8472
8538
|
const generatedFiles = allFiles.filter((f) => f.startsWith(mdBaseName) && f.endsWith(`.${actualFormat}`)).sort();
|
|
8473
8539
|
if (generatedFiles.length > 0) {
|
|
8474
8540
|
try {
|