save-as-pdf
Save as PDF
Reformat the current HTML design into a paginated, paper-ready PDF. The "Instant" export already gives the user a PDF at the design's native pixel size — this path is for when they want real pages.
Do NOT rasterize the page into a PDF. Never use jsPDF, html2canvas, dom-to-image, or any other canvas/screenshot-to-PDF approach — they produce blurry, non-selectable, oversized output, and do not generate a PDF binary yourself. PDF export is print-based: a print-ready copy is handed to show_pdf_export_dialog and the browser's own print engine renders crisp, selectable, text-based pages. The only supported way to make a copy print-ready is a component that owns its print geometry — the doc_page starter for documents, or a source already built on <deck-stage> or <doc-page>. Do not hand-author @page rules or print CSS resets, and NEVER declare <meta name="omelette-owns-print"> yourself — the starters announce print ownership at runtime, and a hand-authored meta tells the platform to trust print CSS you would then have to hand-write and maintain. Hand-rolled print CSS behind that meta is the legacy path; the doc_page starter replaces it everywhere it is available.
Steps
-
Read the current HTML design file to understand its structure and content. Re-read it on every PDF request, even if you read it or made a print copy earlier in this conversation — the user may have changed content or tweak values (the Tweaks panel writes into the source file) since then. Note the
[version: v<N>]token in the read result's header — step 2's provenance stamp needs it, and only a version read in THIS request is valid to stamp. -
Write the print copy, stamped with its provenance. Always write it fresh from the source you just read — an existing
-printcopy from an earlier request is a stale snapshot, and reusing or only partially updating it ships outdated values to the PDF. The print file path is the source path with-printinserted before the extension — same directory, same basename. If the source isslides/deck.html, writeslides/deck-print.html; if the source isweb/index.html, writeweb/index-print.html. Do NOT use the deck title or project name as the filename, and do NOT write to the project root if the source is in a subdirectory — any change in directory depth breaks every relative URL (@font-facesrc: url(...),<img src>,<link href>, CSSbackground: url(...)) and the print tab shows missing images and system-font fallbacks.Stamp the copy's provenance (required whenever the read header shows a version — every arm of this step). Include this tag in the copy's
<head>, carrying the version from step 1's read header and the source's project-relative path (for a read header of[File: designs/report.html] [version: v172]):<meta name="omelette-print-source" content="v172 designs/report.html">show_pdf_export_dialogREFUSES a copy whose stamp is missing or no longer matches the source's current version — that is what makes a stale copy un-exportable. If it refuses with a stale-copy error, go back to step 1 (re-read the source) and rewrite the copy fresh; never just add or edit the stamp on an existing copy. If the read header shows no[version: ...]token, the project isn't versioned — omit the stamp; the export tool skips the freshness check there.If the source is already built on
<deck-stage>or<doc-page>, the copy is the source plus content-level print rules only. Both components own their print geometry — never add an@pagerule or reflow their layout. For<deck-stage>decks, setdata-deck-activeon every direct-child slide (not just the current one) so[data-deck-active]-keyed entrance styles resolve on every page — each slide is already one page. For<doc-page>documents there is nothing structural to do.