Flow
Checks that belong before the photo step
1Waits that report
Each image or font comes back loaded, broken or slow, and only loaded passes.
2Fonts by name
Each declared font is checked on its own, not through one page-wide signal.
3Print the text PDF
Real text, links and named fonts still exist here.
4Look inside it
List its fonts and search it for the title before anything is rasterized.
5Flatten and keep both
Ship the image PDF for viewing and the text PDF for search and screen readers.
Pitch deck to PDF was what I needed. The deck is a web page, so I wrote a script that opens it in a hidden Chrome, switches to print styles, and saves a PDF. Then, by default, the script throws that PDF away.
That was my call. This is from reading my own script again, not from a failed export.
A hidden Chrome and a photo step
It opens the page, waits a little for the network, and flips lazy images so they load right away. Then it waits for fonts and images, each with a short timer, and prints a PDF with real text in it.
Next comes the flatten step. Each page is drawn into a big image, and the images are glued into a new PDF, while the first PDF gets deleted along with the temp folder. The last thing the script prints is the mode and the file size.
Pictures instead of text
A flattened PDF looks the same in every viewer. That's the appeal. But you can't search it, copy from it, or click its links, and screen readers get nothing. My two files came out several megabytes each.
The waits never complain
The network wait and the font and image waits give up when their timers run out, and giving up counts as success, the same as a broken image does. A slow font means Chrome prints a backup font, so lines wrap in new places. The script can't tell good from bad, so it keeps going.
In a normal PDF you could still catch that, because a font list would show the backup font and a search would still find the title. Once it's flattened, the mistake is just pixels, and nothing points at it.
Rare, but I'd never know
Probably rare. My fonts and photos are baked into the one HTML file, so there's nothing to fetch. But if it ever happens, I'd have no way to know. The same commit made the background warmer and the shadows darker. The pale ones probably looked weak in the export, but that's a guess.
Four fixes, in order
If you build something like this, the order is what matters:
- Make each wait report "loaded", "broken" or "slow", and stop on anything but "loaded".
- Check each font by name instead of trusting one page-wide signal.
- Before flattening, list the fonts in the PDF and search it for the title.
- Keep the text PDF next to the flattened one.
The first fix is small.
Now an image that is broken or too slow throws an error naming it, and only a loaded image passes.
The last one is the cheapest. The text PDF already exists for a few seconds on every run, and my script deletes it.