/** * Render every page of the diagnostic PDF using Chromium's built-in PDF viewer * and the pdf.js `applicationOptions` to size the viewport properly. */ import puppeteer from "puppeteer-core"; import { readFileSync, mkdirSync, readdirSync } from "fs"; import { join } from "path"; const CHROME = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; const PDF = "/tmp/rjbulk-pdfs/customer-delivery-diag.pdf"; const OUT_DIR = "/tmp/rjbulk-pdf-images"; mkdirSync(OUT_DIR, { recursive: true }); const browser = await puppeteer.launch({ executablePath: CHROME, headless: "new", args: ["--no-sandbox", "--disable-gpu"], }); // We embed the PDF in an on a blank HTML page so we can use the // `#page=N` URL fragment which Chromium's PDF viewer honours. const html = ` `; const hostPath = "/tmp/rjbulk-pdfs/_host.html"; const { writeFileSync } = await import("fs"); writeFileSync(hostPath, html); const page = await browser.newPage(); await page.setViewport({ width: 900, height: 1300 }); await page.goto(`file://${hostPath}`, { waitUntil: "networkidle2", timeout: 30000 }); await new Promise((r) => setTimeout(r, 1500)); // 1/6 means 6 pages — read it from the toolbar const totalPages = await page.evaluate(() => { const m = document.body.innerText.match(/\/\s*(\d+)/); return m ? parseInt(m[1], 10) : 1; }); console.log(`Total pages: ${totalPages}`); for (let i = 1; i <= totalPages; i++) { await page.goto(`file://${PDF}#page=${i}&zoom=100`, { waitUntil: "networkidle2" }); await new Promise((r) => setTimeout(r, 600)); await page.screenshot({ path: join(OUT_DIR, `diag-page-${String(i).padStart(2, "0")}.png`) }); console.log(` ✓ page ${i}`); } await browser.close();