Add lt_export() to save tables as PDF or PNG#2
Conversation
Render an lt table in headless Chromium and write it to a file, choosing the format from the output extension: .pdf for vector PDF (Chromium's print-to-PDF) and PNG otherwise. By default the output is cropped tightly to the table, removing the surrounding page whitespace. A preliminary browser pass measures the rendered table via browser_dom() (running lt.js), reading the body's scroll size so the caption border and footer spacing are included; then: - PDF: an @page rule sets the page box to the measured size, so the table fits on a single page (measuring the table's border-box alone undercounted the height and spilled onto a second page). - PNG: Chromium's --screenshot output equals the window size and cannot be shrunk below Chromium's minimums, so we render onto a large window (table unscaled at the top-left) and crop to the exact box with magick. Without magick, PNG falls back to the full page with a warning. Chromium cannot export SVG, so no vector option beyond PDF is offered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
yihui
left a comment
There was a problem hiding this comment.
should lt_html() be merged into lt_export()? lt_html() basically exports the table to html (without relying on js to render the table)
- lt_export() now writes .html too, delegating to lt_html() for a static table (no browser). One file-export entry point for html/pdf/png. - Add width/height args to set the table size in CSS pixels for pdf/png, usable whether crop is TRUE or FALSE (crop no longer forces the measured width). - Drop the SVG discussion from the docs. - Use xfun::loadable() instead of requireNamespace() for the magick check. - Return the output path plainly (not invisibly). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Re: merging
I left |
lt_export() is now the sole public file-export API: - lt_html() becomes an internal helper. It still renders the static HTML table and still backs the `lt.lt_html` option (knit_print/record_print), but callers reach it through lt_export(x, "file.html"). The Global option doc moves to lt_export(), and its `method`/`css` extras are documented as ... passthrough for the .html path. - Drop the `height` argument: height is always derived from the content at the chosen `width`, so an explicit height only risked clipping or padding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Done in 9581b89:
|
lt_export() is now the single HTML/PDF/PNG entry point:
- Fold the former lt_html() into an internal render_html() and expose its
controls as explicit lt_export() arguments: method, css, fragment (these
apply to .html output only).
- Add method = "raw": write the JavaScript-spec HTML unchanged, so the
table is built client-side by lt.js at view time (no Node.js or browser
runs). The other methods ("node"/"browser"/"auto") bake a static <table>.
- Default output = "lt.html". When output is NA, return the HTML as a
string (xfun::raw_string) instead of writing a file.
- The lt.lt_html option path (knit_print/record_print) now calls
render_html() with the same method/css/fragment arguments.
NEWS: document lt_export() instead of lt_html().
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Show each output form: method = "raw" HTML (runs unconditionally, as it needs no external tool), a baked static table gated on Node.js/browser availability, and PDF/PNG gated on a headless browser.
What
New
lt_export(x, output = 'lt.pdf', crop = TRUE, padding = 8, ...)renders anlt_tblin headless Chromium and writes it to a file. Format follows theoutputextension:.pdf→ vector PDF (Chromium print-to-PDF), otherwise PNG.Cropping
By default the output is cropped tight to the table (no surrounding page whitespace). A preliminary
browser_dom()pass runslt.jsand measures the body's scroll size — this matters because the caption'sborder-topand footer spacing extend past the<table>border-box, so measuring the table box alone undercounts the height.@page{size:...}rule sets the page box exactly → single page, dep-free. (Measuring the table box was the cause of the two-page penguins output.)--screenshotsize equals the window size and can't go below Chromium's minimum window / reserved-chrome height, which scales overflowing content. So we render onto a generous window (table unscaled, top-left) and crop to the exact box with magick. Without magick, PNG falls back to the full page with a warning.SVG is not supported — Chromium cannot export a rendered page as SVG; PDF is the vector option.
Tests
tests/test-ci/test-js.R(browser-gated): PDF+PNG written with correct magic bytes, a large table crops to one PDF page (regression guard), and the cropped PNG matches the measured content box exactly (magick-gated).🤖 Generated with Claude Code