Fix PDF compilation for packages needing 3+ LaTeX passes#2827
Fix PDF compilation for packages needing 3+ LaTeX passes#2827saustinp wants to merge 2 commits intoPreTeXtBook:masterfrom
Conversation
a8e4ac7 to
bc81d16
Compare
The pdf() function hardcoded exactly 2 LaTeX passes. Packages like nicematrix (which uses TikZ "remember picture" for cell coloring) require 3+ passes to correctly position overlay nodes. With only 2 passes, colored cell backgrounds could expand to fill the entire page. Replace the hardcoded 2-pass approach with a rerun loop that checks the .log file for "Rerun" requests after each pass, matching the strategy already used for standalone latex-image compilation. Documents not needing extra passes still get exactly 2 passes (the loop checks the log after pass 2 and breaks immediately). Fixes PreTeXtBook#2825
bc81d16 to
fe9fc59
Compare
|
I sense a family effort here. ;-) Thanks very much, @saustinp. Will Claude be joining the family? Back in a few. |
|
Yes, Claude has certainly come in handy :) Thanks for taking a look! |
rbeezer
left a comment
There was a problem hiding this comment.
Good catch — the two-pass hardcoding has been a known limitation, and this is the right fix. The PR description is thorough and the change is well-scoped.
A few observations:
-
Log search string is broader than the existing pattern. The latex-image loop at line 703 checks for
"Rerun to get", which is the standard LaTeX message. This PR checks for both"Rerun"and"rerun"(case-sensitive substring matches). That's more permissive — it will catch more package-specific messages, which is probably fine, but it also risks false positives on strings like "Do not rerun" or informational messages that mention rerun without requesting one. Consider matching"Rerun to get"(matching the existing latex-image loop) or at least"Rerun"alone (capital R, which is the convention for LaTeX rerun requests). -
No
returncodecheck. The existing latex-image loop checksresult.returncode == 0before rerunning — if LaTeX errors out, it stops. This loop doesn't capture the return code and will keep running even after a fatal error, potentially repeating a failing compilation up to 10 times. Should checksubprocess.run(...).returncodeand break on failure. -
No max-loop warning. The latex-image loop logs an error and sets a nonzero return code when
MAX_LOOPSis hit (lines 709-711). This loop silently exits after 10 passes with no indication that something may be wrong. -
Style:
MAX_PASSESas a local constant. The existing code usesMAX_LOOPSat module scope or function scope similarly, so this is consistent, though both could arguably be a module-level constant. Not worth changing here. -
pass_numis unused. Minor — the loop variable exists only to drive the count. Could use_to signal intent, but not important.
Overall this is a straightforward and correct improvement. Items 2 and 3 are the substantive ones — matching the existing error handling from the latex-image loop would make this robust.
Claude Opus 4.6, acting as a review assistant for Rob Beezer
|
Let me know what you would like to address and when you feel this is ready. |
- Narrow log search to "Rerun to get" (matching latex-image loop at line 703) instead of broad "Rerun"/"rerun" substring match, avoiding false positives on informational messages - Check subprocess returncode and break on failure, preventing repeated compilation of a fatally errored document - Log a warning when MAX_PASSES is exhausted without convergence - Rename unused loop variable to _
|
Thanks for the thorough review. All four points addressed in the latest push: |
Summary
pdf()with a log-checking rerun loop\cellcoloroverlay nodes expanding to fill the entire page in the sample article PDF (page 60, Figure 10.12)Root cause
The
pdf()function inpretext/lib/pretext.pyran exactly 2 LaTeX passes (subprocess.runcalled twice). Thenicematrixpackage'scode-beforedirective uses TikZremember picture, overlaynodes internally to position colored cell backgrounds. These nodes require 3 passes to resolve their final page coordinates. With only 2 passes, the overlay rectangles are mis-positioned and can cover the entire page.The standalone
latex-imageextraction pipeline (pretext/lib/pretext.py:696-707) already had a proper rerun loop that checks for "Rerun" in the.logfile, which is why the generated image files (latex-three-pass.pdf/.svg/.png) rendered correctly. The main document compilation was missing this same logic.Change
pretext/lib/pretext.py—pdf()function (line ~5250)Before:
After:
The loop always runs at least 2 passes (matching previous behavior), then checks the
.logfor rerun requests before each additional pass, up to a maximum of 10. This matches the existing strategy used for standalone latex-image compilation.Test plan
examples/sample-articlePDF — page 60 (Figure 10.12, "A matrix with colored entries") now renders correctly with properly bounded colored cellsgen/latex-image/latex-three-pass.pdfwas already correct (confirming the issue was isolated to main document compilation)Fixes #2825