diff --git a/.gitignore b/.gitignore index cb3a08f..670de19 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules/ output/book.html output/resized/ +output/cover-300dpi.png output/cover.html output/book-meta.json # Interior PDF is large (~100 MB with placeholder pages) — excluded from git. diff --git a/package.json b/package.json index d05f6d2..81add4b 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,9 @@ "build": "node scripts/build.js", "pdf": "node scripts/pdf.js", "cover": "node scripts/cover.js", + "cover-image": "node scripts/cover-image.js", "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" }, "pnpm": { diff --git a/scripts/cover-image.js b/scripts/cover-image.js new file mode 100644 index 0000000..6ad7246 --- /dev/null +++ b/scripts/cover-image.js @@ -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)`);