const puppeteer = require('puppeteer-core'); const path = require('path'); const fs = require('fs'); const HTML_DIR = __dirname; const PDF_DIR = path.join(__dirname, 'pdfs'); const files = [ { html: 'mockup.html', width: '11in', height: '8.5in' }, { html: 'mockup-generalized.html', width: '11in', height: '8.5in' }, { html: 'mockup-parent-caregiver.html', width: '11in', height: '8.5in' }, { html: 'mockup-family-member.html', width: '11in', height: '8.5in' }, { html: 'mockup-professional.html', width: '11in', height: '8.5in' }, { html: 'mockup-special-needs.html', width: '11in', height: '8.5in' }, ]; (async () => { // Ensure output directory exists fs.mkdirSync(PDF_DIR, { recursive: true }); const browser = await puppeteer.launch({ executablePath: '/usr/bin/google-chrome-stable', headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu'] }); let success = 0; let failures = 0; for (const file of files) { const htmlPath = path.resolve(HTML_DIR, file.html); const pdfName = file.html.replace('.html', '.pdf'); const pdfPath = path.join(PDF_DIR, pdfName); if (!fs.existsSync(htmlPath)) { console.log(`SKIP: ${file.html} — file not found`); failures++; continue; } try { const page = await browser.newPage(); await page.goto(`file://${htmlPath}`, { waitUntil: 'networkidle0', timeout: 30000 }); try { await page.evaluate(() => document.fonts.ready); } catch (e) { /* font API sometimes fails in headless */ } await new Promise(r => setTimeout(r, 2500)); await page.pdf({ path: pdfPath, width: file.width, height: file.height, printBackground: true, margin: { top: '0', right: '0', bottom: '0', left: '0' }, preferCSSPageSize: false }); const stats = fs.statSync(pdfPath); console.log(`OK: ${pdfName} (${(stats.size / 1024).toFixed(0)} KB)`); success++; } catch (err) { console.log(`FAIL: ${file.html} — ${err.message}`); failures++; } } await browser.close(); console.log(`\nDone: ${success} succeeded, ${failures} failed`); })();