feat: add cover-image task to export cover PDF as 300 DPI PNG

Runs Ghostscript on output/cover.pdf to produce output/cover-300dpi.png
for visual QC and sharing. Also wired into the `pnpm all` pipeline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-12 21:42:39 +02:00
parent 3537baa230
commit 35c76656e9
3 changed files with 34 additions and 1 deletions
+1
View File
@@ -2,6 +2,7 @@
node_modules/ node_modules/
output/book.html output/book.html
output/resized/ output/resized/
output/cover-300dpi.png
output/cover.html output/cover.html
output/book-meta.json output/book-meta.json
# Interior PDF is large (~100 MB with placeholder pages) — excluded from git. # Interior PDF is large (~100 MB with placeholder pages) — excluded from git.
+2 -1
View File
@@ -9,8 +9,9 @@
"build": "node scripts/build.js", "build": "node scripts/build.js",
"pdf": "node scripts/pdf.js", "pdf": "node scripts/pdf.js",
"cover": "node scripts/cover.js", "cover": "node scripts/cover.js",
"cover-image": "node scripts/cover-image.js",
"book": "pnpm build && pnpm pdf", "book": "pnpm build && pnpm pdf",
"all": "pnpm build && pnpm pdf && pnpm cover", "all": "pnpm build && pnpm pdf && pnpm cover && pnpm cover-image",
"watch": "node --watch scripts/build.js" "watch": "node --watch scripts/build.js"
}, },
"pnpm": { "pnpm": {
+31
View File
@@ -0,0 +1,31 @@
import { access, stat } from 'fs/promises';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import { execFile } from 'child_process';
import { promisify } from 'util';
const execFileAsync = promisify(execFile);
const __dir = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dir, '..');
const pdfPath = resolve(root, 'output', 'cover.pdf');
const outPath = resolve(root, 'output', 'cover-300dpi.png');
try {
await access(pdfPath);
} catch {
console.error('output/cover.pdf not found — run `pnpm cover` first');
process.exit(1);
}
console.log('Rendering cover to PNG at 300 DPI…');
await execFileAsync('gs', [
'-dBATCH', '-dNOPAUSE', '-dQUIET',
'-sDEVICE=png16m',
'-r300',
`-sOutputFile=${outPath}`,
pdfPath,
]);
const { size } = await stat(outPath);
console.log(`Cover image: output/cover-300dpi.png (${(size / 1_048_576).toFixed(1)} MB)`);