Skip to content

gotex: wire go-tex/pdfrender behind GOTEX_PDFRENDER for real PDF-figure height - #191

Merged
tannevaled merged 1 commit into
mainfrom
float-pdfrender-combined
Sep 2, 2026
Merged

gotex: wire go-tex/pdfrender behind GOTEX_PDFRENDER for real PDF-figure height#191
tannevaled merged 1 commit into
mainfrom
float-pdfrender-combined

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

What

Wires the engine's existing RasterizePDF seam (image.go) to go-tex/pdfrender v0.1.0 in cmd/gotex, so \includegraphics of a vector .pdf — the commonest figure on arXiv — rasterises to a real raster with its true height instead of a placeholder box. The renderer call is fenced against a panic so a bad figure costs the figure, not the document (the engine already answers the error with a placeholder that keeps the figure's aspect).

Gating — default is byte-identical

The wiring is OFF by default, behind GOTEX_PDFRENDER. With the variable clear the seam stays nil, exactly as on the engine core, so a PDF figure frames the same placeholder and the CLI output is byte-for-byte unchanged from main. Verified cmp-identical (SVG output, flags off) on 2201.04865, 2206.00339, 2201.02101 (17/30/25 pages, matching SHA-256 vs a main build).

Real figure height is a deliberate pagination change; its intended companion is GOTEX_FLOATS, so a real-height figure floats to a page top as TeXLive does. The faithful mode is GOTEX_PDFRENDER=1 GOTEX_FLOATS=1.

Honest measured result (page count vs tectonic reference)

paper tectonic base (off) +pdfrender +floats combined note
2201.04865 22 17 19 17 19 10 real rasters embedded; figures named {x.pdf}, no width override
2206.00339 34 30 30 30 30 figures don't resolve on disk (missing .pdf / extension-less refs) — 0 rasters
2201.02101 27 25 25 26 26 extension-less refs ({fig1}) never load; floats add +1

Partial convergence win. Where figures both (a) resolve on disk under their exact referenced name and (b) carry no width=X\linewidth-style override, real-height rasterisation converges toward tectonic (2201.04865: delta −5 → −3, ten real rasters). No regression: combined page count ≥ baseline everywhere.

The dominant residual is upstream of this PR, not the seam:

  1. loadImage does no graphicx extension search, so extension-less refs ({fig1}) never load — the whole reason 2201.02101 and much of 2206.00339 don't move;
  2. one-column \linewidth-relative width collapse (the documented legacy raw-text dimen read) binds a figure's height regardless of real pixels;
  3. float-page whitespace that placement conserves rather than adds (the known 5th-confirmation on GOTEX_FLOATS).

Verification

  • go build ./cmd/gotex/, go vet ./..., gofmt -l clean
  • go test -count=1 . and go test -count=1 ./cmd/gotex/ green
  • pdfrender confirmed to rasterise the real figure PDFs directly (e.g. 3059×1025)

🤖 Generated with Claude Code

…t real height

The engine core exposes a RasterizePDF seam (image.go) but leaves it nil, so a
\includegraphics of a vector .pdf — the commonest figure on arXiv — frames a
placeholder with no real height. This wires the seam in the CLI to
go-tex/pdfrender v0.1.0 (Rasterize matches the hook signature), fenced against a
panic in the third-party renderer so a bad figure costs the figure, not the
document.

It is GATED behind GOTEX_PDFRENDER and OFF by default: with the variable clear
the seam stays nil, exactly as on the engine core, so the default CLI output is
byte-for-byte identical to current main (verified cmp-identical on 2201.04865,
2206.00339, 2201.02101 with flags off). Wiring it gives figures their real
HEIGHT, a deliberate pagination change; its intended companion is GOTEX_FLOATS,
so a real-height figure floats to a page top as TeXLive does — the faithful mode
is GOTEX_PDFRENDER=1 GOTEX_FLOATS=1.

Measured (page count vs tectonic reference): 2201.04865 — figures named with an
explicit .pdf and no width override rasterise (10 real rasters embedded),
17 -> 19 pages toward tectonic's 22 (delta -5 -> -3). Where a figure carries a
width=X\linewidth (collapsed to X pt by the documented one-column raw-text dimen
read) or is referenced without a file extension (loadImage does no graphicx
extension search), it does not rasterise and the count is unchanged — those are
upstream gaps, not this seam. No regression: combined page count >= baseline in
every case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 1b30e51 into main Sep 2, 2026
18 checks passed
@tannevaled
tannevaled deleted the float-pdfrender-combined branch September 2, 2026 17:45
tannevaled added a commit that referenced this pull request Sep 2, 2026
…193)

loadImage read the reference name verbatim, so a figure written without its
extension — \includegraphics{fig}, the form real papers use — never found
fig.pdf/fig.png on disk and collapsed to a placeholder. This was the dominant
reason figures did not load even after a PDF rasteriser was wired (#191).

Resolve the reference the way graphicx does: an exact hit wins; otherwise, when
the name carries no known graphics extension, each extension is appended in turn
— pdf first, matching pdftex's \Gin@extensions, both cases for a case-sensitive
filesystem — and the first that exists is used. Existing-file resolution is
unchanged (os.Stat of the exact name still wins), so papers that already loaded
their figures are unaffected; only previously-failing extension-less references
now resolve.

Effect (GOTEX_PDFRENDER=1 GOTEX_FLOATS=1): 2206.00339's \includegraphics skips
fall 10 -> 0 and its page count reaches 34, exactly tectonic; 2201.02101's fall
11 -> 0. Where figures now load oversized (no \linewidth scaling yet) the page
count overshoots — a separate, isolated residual — but every figure that should
render now does. Tests cover exact hit, extension search, pdf-first ordering, an
honoured explicit extension, no-match, and a directory not counting as a file.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant