Repository navigation
Conversation
A captioned figure inside a prf: directive box, numbered or :nonumber:,
broke the LaTeX/PDF build with "LaTeX Error: Not in outer par mode".
Sphinx's LaTeX writer increments no_latex_floats whenever it opens one
of its own admonitions, and visit_figure then writes
\begin{figure}[H]. The enumerable and unenumerable visitors open the
same sphinxadmonition box but never touched the counter, so figures
inside it were written as floating \begin{figure}[htbp], which LaTeX
rejects there.
Open and close the box through a small visit_latex_admonition /
depart_latex_admonition helper pair that also increments and
decrements the counter. prf:proof was already unaffected: it wraps a
docutils admonition node that Sphinx's own visitor handles. HTML output
is unchanged.
Add the tests/books/test-latexfigure root and
tests/test_latex.py::test_latex_figure_in_admonition, and a CHANGELOG
entry. Mirrors the change in executablebooks/sphinx-exercise#95.
Fixes #169
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WT8bMZoSvoQTbzkdmZiMnd
Contributor
There was a problem hiding this comment.
Note
Copilot was unable to complete this review at the selected tier due to model policy or plan restrictions.
🟡 Changes recommended
The change still has an unresolved moderate test robustness issue where latex_figures can silently drop earlier figures on duplicate or missing names, along with a minor changelog style inconsistency that should be corrected.
2 open issues
What changed in this PR
Fixes LaTeX/PDF build failures when captioned figures appear inside prf: directive boxes by aligning sphinx-proof’s LaTeX admonition handling with Sphinx’s float-suppression behavior to avoid “Not in outer par mode”.
Changes:
- Add LaTeX admonition helper functions to open/close
sphinxadmonitionboxes while updatingno_latex_floatsforprf:nodes. - Add a LaTeX regression test root and a test that inspects generated
.texto verify in-box figures use[H]and floats resume after boxes. - Document the fix under
CHANGELOG.md(Unreleased).
| File | Description |
|---|---|
| tests/test_latex.py | Adds a regression test that parses generated LaTeX to verify figure float behavior inside and outside proof/admonition boxes (including nesting). |
| tests/books/test-latexfigure/index.rst | Introduces a new test root index/toctree to drive the LaTeX figure-in-admonition regression scenario. |
| tests/books/test-latexfigure/figures.rst | Adds test content covering figures inside numbered/unnumbered prf: boxes, Sphinx admonitions, nested boxes, and a figure outside boxes. |
| tests/books/test-latexfigure/conf.py | Provides a minimal Sphinx configuration enabling sphinx_proof for the new LaTeX regression test root. |
| sphinx_proof/nodes.py | Refactors LaTeX visitor logic to open/close admonition environments via helpers that manage no_latex_floats so figures inside prf: boxes are emitted as non-floating. |
| CHANGELOG.md | Adds an Unreleased changelog entry documenting the LaTeX fix for figures inside prf: directive boxes. |
Review effort: Balanced
Comment on lines
+37
to
+38
| name = LATEX_FIGURE_NAME.search(figure["body"]) | ||
| figures[name["name"] if name else None] = (figure["align"], depth) |
Comment on lines
+7
to
+9
| - Captioned figures inside `prf:` directive boxes breaking the LaTeX/PDF build with `LaTeX Error: Not in outer par mode`, fixing [\#169](https://github.com/executablebooks/sphinx-proof/issues/169). | ||
| - Figures inside every `prf:` box, numbered or `:nonumber:`, are now written as `\begin{figure}[H]` so they stay in place, as Sphinx already does for figures inside its own admonitions | ||
| - HTML output is unchanged |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Fixes #169
A captioned figure inside a
prf:directive box, such asprf:theoremor a:nonumber:prf:lemma, breaks the LaTeX/PDF build withLaTeX Error: Not in outer par mode. Sphinx's LaTeX writer incrementsno_latex_floatswhenever it opens one of its own admonitions, andvisit_figurethen writes\begin{figure}[H]instead of a float. sphinx-proof opens the samesphinxadmonitionbox invisit_enumerable_nodeandvisit_unenumerable_nodebut never touched the counter, so figures inside it were written as\begin{figure}[htbp], which LaTeX rejects inside the box. This mirrors the change in executablebooks/sphinx-exercise#95, released in sphinx-exercise 1.2.2.Changes
sphinx_proof/nodes.py: the LaTeX branches of the enumerable and unenumerable visit/depart pairs now open and close the box through a smallvisit_latex_admonition/depart_latex_admonitionhelper pair that also increments and decrementsself.no_latex_floats. This covers every directive inPROOF_TYPES, numbered or:nonumber:. The helpers still append the exactlatex_admonition_startstring that thedepart_*functions search for to place the box title.prf:proofneeded no change, because it wraps a docutilsadmonitionnode that Sphinx's own visitor already handles. HTML output is unchanged.tests/books/test-latexfigure/andtests/test_latex.py::test_latex_figure_in_admonition: figures in a numbered theorem, an unnumbered lemma, aprf:proof, anote, nested boxes, and one figure after all the boxes that must still be[htbp], which shows the counter is restored. The test reads only the generated.tex, so CI needs no TeX installation.CHANGELOG.md: entry underUnreleased.Testing
mainand passes with this change on Sphinx 7.2.6, 7.4.7, 8.1.3, 9.0.4 and 9.1.1, and on 5.3.0 and 6.2.1 with a local shim for the suite'sconftest.py, which needs Sphinx 7.2 or later. Full suite: 15 passed onmain, 16 with this change.latexmk -pdfon Sphinx 7.4.7: the new test root stops at the first in-box figure onmainand compiles with this change.prf:boxes andprf:boxes inside others all write their figures as[H], the counter returns to zero at the end of the document, and the PDF compiles.Not addressed here: when one
prf:box contains another, the LaTeX output still places the outer box's title in the inner box, the LaTeX counterpart of #165.🤖 Generated with Claude Code
https://claude.ai/code/session_01WT8bMZoSvoQTbzkdmZiMnd