-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LaTeX: compatibility with caption package #5630
Conversation
This compatibility is mainly re-instored for convenience of user to style the fonts used for the caption, and also possibly influence the horizontal position via "width" or "margin" option of caption package (attention that caption package obeys the document class tacit "twoside" option, so if left and right margins are not set-up to be the same, positioning of caption will depend on parity of the page number). Regarding vertical skips, for captions placed on top (which is the table templates default and also the literalblockcappos default), this commit ensures that the vertical spacing separating the caption last baseline to the top of framing is governed by \sphinxbelowcaptionspace in all these three cases: tabular(y), longtable, literal blocks; the "skip" option of caption package is ignored for them. The "skip" is obeyed for the spacing between an image and its caption, which currently in Sphinx is always below the image (no customization of the figure caption vertical placement is currently available). If literalblockcappos is "b" (captions follow code-blocks), this commit removes the caption-package added \abovecaptionskip, so that "skip" is also ignored for code-blocks in this case. This looks better due to the extra space already added by the framing of the code-block and achieves same spacing as without caption package (presumably loaded mainly to style the fonts used for the caption). However in future maybe caption's package "skip" should be obeyed for "literalblock" caption type. Fixes: 5520
Codecov Report
@@ Coverage Diff @@
## 1.8 #5630 +/- ##
=========================================
+ Coverage 82.09% 82.1% +<.01%
=========================================
Files 300 300
Lines 40102 40102
Branches 6192 6192
=========================================
+ Hits 32923 32924 +1
Misses 5803 5803
+ Partials 1376 1375 -1
Continue to review full report at Codecov.
|
@@ -13,7 +13,7 @@ | |||
<% if table.caption -%> | |||
\sphinxcapstartof{table} | |||
\sphinxcaption{<%= ''.join(table.caption) %>}<%= labels %> | |||
\sphinxaftercaption | |||
\sphinxaftertopcaption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This macro was never publicly documented; I changed its name for clarification that it should not be used if caption is moved to after the table body.
% so we do the same for tabular(y) tables (see their templates) | ||
\def\sphinxtablecapwidth{\LTcapwidth}% (default is 4in: max width of caption) | ||
% TODO: add alignment options? but user can employ caption package instead. | ||
\newcommand\sphinxcaption{\@dblarg\spx@caption}% |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
\sphinxcaption
is used in the tabular and tabulary templates, its role is to imitate the longtable caption which has a maximal width (4in per default). The \sphinxcaption
allowed possibility of optional argument to use something else than \LTcapwidth
, but this was bad because usually optional argument of \caption
serves to specify a "short" title for making an entry in the corresponding "\listof<tables, figures>". Notice that \sphinxcaption
so far is not known to LaTeX writers (figures) but only used via the table templates or via the sphinx.sty code (sphinxVerbatim environment, \sphinxSetupCaptionForVerbatim
) for literal blocks. So it is still non-public internal tool and this change will not modify any existing project.
\noindent\hb@xt@\linewidth{\hss | ||
\vtop{\@tempdima\dimexpr#1\relax | ||
\vtop{\@tempdima\dimexpr\sphinxtablecapwidth\relax |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new undocumented macro only serves to implement functioning of \sphinxcaption
for maximal width of captions of tabular/tabulary to be same as longtable, because \sphinxtablecapwidth
by default will simply be the longtable variable \LTcapwidth
.
sphinx/texinputs/sphinx.sty
Outdated
{\strut\ignorespaces#2\ifhmode\unskip\@finalstrut\strutbox\fi}% | ||
}\hss}% | ||
\par\prevdepth\dp\strutbox | ||
}% | ||
\def\spx@abovecaptionskip{\abovecaptionskip} | ||
\def\spx@abovecaptionskip{\abovecaptionskip}% for literal blocks captions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The title of a literal block caption is set in a minipage (see \sphinxVerbatim@TitleBox
) and the insertion of (wrong comment) so the \abovecaptionskip
from standard expansion of LaTeX \caption
is without effect, sphinxVerbatim
environment does the skip itself on top of a caption which is positioned above a code-block (following standard but somewhat faulty LaTeX behaviour which always uses \abovecaptionskip
even if caption is on top, although of course it was intended primarily to be used when caption is at bottom; see the caption
package documentation for more on this incoherency of LaTeX2e). This \spx@abovecaptionskip
is given meaning \sphinxverbatimsmallskipamount
inside sphinxVerbatimintable
to reduce this spacing without modifying \abovecaptionskip
itself (I don't remember why I preferred sphinxVerbatimintable
not to give locally new value to \abovecaptionskip
).
see #5630 (comment) for corrections to the above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah sorry
and the insertion of \abovecaptionskip from standard expansion of LaTeX
\caption
is without effect,
this is plain wrong comment. The \abovecaptionskip
would work even at start of minipage, but I had forgotten when writing up that comment that by default Sphinx uses not \caption
but its own \sphinxcaption
inside the sphinxVerbatim@TitleBox
, and this sets locally \abovecaptionskip
to \sphinxabovecaptionskip
which by default is 0pt
. So the real reason for \spx@abovecaptionskip
is because \abovecaptionskip
is set locally to 0pt
inside the TitleBox, when \sphinxcaption
is made use of. As this is also the case for sphinxVerbatimintable
it would have remained without effect to set \abovecaptionskip
to another value there locally, because this is overruled by \sphinxcaption
(in absence of caption
package of course, now).
|
||
\newcommand\sphinxaftercaption | ||
% | ||
\newcommand\sphinxaftertopcaption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As explained above I have modified name of this non-documented LaTeX variable for clarity of future maintenance.
\sphinxbelowcaptionspace\relax}% this is the vspace we want | ||
}% | ||
{\let\spx@ifcaptionpackage\@secondoftwo}% | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LaTeX code comments explain what this does. This is compatibility layer with caption package: if detected, do not use \sphinxcaption
own code at all and slightly adjust corrective measure for longtable because caption
package patches longtable code and makes it use an other vertical spacing.
Some other modifications of behaviour in presence of caption
package are implemented in the sphinxVerbatim
environement and use the \spx@ifcaptionpackage
conditional defined here.
\kern\dimexpr-\dp\strutbox+\sphinxbelowcaptionspace | ||
% if no frame (code-blocks inside table cells), remove | ||
% the "verbatimsep" whitespace from the top (better visually) | ||
\ifspx@opt@verbatimwithframe\else-\sphinxverbatimsep\fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This removal of some vertical space in case the literal-block is in a table cell (so Sphinx uses no framing but still uses \sphinxverbatimsep
whitespace on the 4 sides) is unrelated to handling caption package, but it improves the PDF, and it was occasion to do so.
% the "verbatimsep" whitespace from the top (better visually) | ||
\ifspx@opt@verbatimwithframe\else-\sphinxverbatimsep\fi | ||
% caption package adds \abovecaptionskip vspace, remove it | ||
\spx@ifcaptionpackage{-\abovecaptionskip}{}\relax}% |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If caption package is active and caption is on top, it adds \abovecaptionskip
below the caption, contrarily to standard LaTeX. We remove it for consistency and then only \sphinxbelowcaptionspace
governs for all four: tabular, tabulary, longtable, and literalblock the spacing to frame of object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When one uses caption
package it succeeds in achieving same spacing for positioning of a top caption for both table
environment (with a tabular) or longtable
. But Sphinx does not use table
environment for a tabular
, I have observed that in such non-table environment, the caption
package does not succeed in positioning vertically the caption exactly like it does for longtable. Thus, the necessity remains to keep the \sphinxaftertopcaption
macro (especially because parskip
package is loaded) and its way of achieving \sphinxbelowcaptionspace
vertical spacing. So we also need to achieve this for literal blocks, which is done here.
The situation is thus completely different between the status of \abovecaptionskip
(used with caption
package between caption and object) and the one of \belowcaptionskip
(used on external side if caption
package used). In the former case Sphinx needs special corrective measures for achieving identical result with tabular(y), longtable and literal blocks, in the latter case, it does not have to worry.
\fi | ||
\def\@captype{literalblock}% | ||
\capstart | ||
% \sphinxVerbatimTitle must reset color | ||
\setbox\sphinxVerbatim@TitleBox | ||
\hbox{\begin{minipage}{\linewidth}% | ||
% caption package may detect wrongly if top or bottom, so we help it | ||
\spx@ifcaptionpackage | ||
{\caption@setposition{\spx@opt@literalblockcappos}}{}% |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inside the minipage, the caption package fails to detect automatically if caption is before or after. As we know exactly which is the case, we inform caption package here. Its version of \caption
will thus put \abovecaptionskip
(default 10pt) between the caption and the object, and \belowcaptionskip
(default 0pt) on the other side.
@@ -4,7 +4,7 @@ | |||
\centering | |||
\sphinxcapstartof{table} | |||
\sphinxcaption{caption for table}\label{\detokenize{tabular:id1}} | |||
\sphinxaftercaption | |||
\sphinxaftertopcaption |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I don't think this change of name is breaking. There was no reason to use custom template with \sphinxaftercaption
elsewhere: if user has custom table template with caption at bottom, there was no reason to use \sphinxaftercaption
at all.
@@ -1049,17 +1072,28 @@ | |||
\vskip\spx@abovecaptionskip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If caption package is loaded it will add a \vskip\belowcaptionskip
above a top caption, as is the case here. By default \belowcaptionskip
is 0pt
so this changes nothing. If non-zero, there will be extra vertical space above caption. And for a bottom caption, this extra space will be after it. The same will apply to table captions (because Sphinx then does not use its own \sphinxcaption
but the standard \caption
as patched by caption
package). So the behaviour of captions for tables, figures, and literal-blocks remains coherent even then regarding spacing before a top caption or after a bottom caption, so I decided not to add any "corrective" measure here.
% the "verbatimsep" whitespace from the top (better visually) | ||
\ifspx@opt@verbatimwithframe\else-\sphinxverbatimsep\fi | ||
% caption package adds \abovecaptionskip vspace, remove it | ||
\spx@ifcaptionpackage{-\abovecaptionskip}{}\relax}% |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When one uses caption
package it succeeds in achieving same spacing for positioning of a top caption for both table
environment (with a tabular) or longtable
. But Sphinx does not use table
environment for a tabular
, I have observed that in such non-table environment, the caption
package does not succeed in positioning vertically the caption exactly like it does for longtable. Thus, the necessity remains to keep the \sphinxaftertopcaption
macro (especially because parskip
package is loaded) and its way of achieving \sphinxbelowcaptionspace
vertical spacing. So we also need to achieve this for literal blocks, which is done here.
The situation is thus completely different between the status of \abovecaptionskip
(used with caption
package between caption and object) and the one of \belowcaptionskip
(used on external side if caption
package used). In the former case Sphinx needs special corrective measures for achieving identical result with tabular(y), longtable and literal blocks, in the latter case, it does not have to worry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know caption package so much. But I trust you :-)
Thanks @tk0miya! I got verbose in my comments/review as usual, let's say that this could prove useful in some years if everybody at Sphinx has forgotten why the LaTeX code got like that. I too wasn't too familiar with I'll wait a bit in case @jessetan has any comment before merging this. It will still be possible to add in future some The principle point to improve in Sphinx LaTeX currently regarding captions is placement of figure captions which is not under user control. Tables and literal-blocks are under user control (for tables via the templates). |
This solves my reported incompatibility with the captions package, thanks! |
@jessetan thanks, yes you are right. This is due to the fact that Investigating this, it reminded me that I had not unified spacing to captions between tables and literal-blocks. They never coincided I think, and I sort of remember working hard during various literal-block evolutions to maintain exact legacy spacing of literal blocks. Anyway, this may be occasion to unify literal blocks with tables. Here is minimal example to play with.
This image was obtained with The same source without caption would give the same result with the sole difference that the first table caption would match the blue line, not the red line. (as you reported) The green line indicates exact distance to caption of code-block. It is the same whether or not I think it could be worthwile to unify Listings with tables (assuming captions are on top), at the same time that the By the way |
Ensure same vertical spaces above caption for tabular(y) and longtable rendered tables. Fixes: sphinx-doc#5520
@jessetan Updated. I decided to only fix #5520 and not unify with captions of literal blocks, this will be done on another occasion. edit: unfortunately it is still not perfect, there is a slight discrepancy when the caption occupies multiple lines, between table and longtable, with caption package loaded. Looks as if I must dig more into caption package code... If I get time I will do, else I will merge this for 1.8.3. No problem I could see with captions on only one line. |
Make sure vertiale spacing is the same for tabular(y)/longtable also for multi-line captions
This compatibility is mainly re-instored for convenience of user to
style the fonts used for the caption, and also possibly influence the
horizontal position via "width" or "margin" option of caption package
(attention that caption package obeys the document class tacit "twoside"
option, so if left and right margins are not set-up to be the same,
positioning of caption will depend on parity of the page number).
Regarding vertical skips, for captions placed on top (which is the table
templates default and also the literalblockcappos default), this commit
ensures that the vertical spacing separating the caption last baseline
to the top of framing is governed by \sphinxbelowcaptionspace in all
these three cases: tabular(y), longtable, literal blocks; the "skip"
option of caption package is ignored for them.
The "skip" is obeyed for the spacing between an image and its caption,
which currently in Sphinx is always below the image (no customization of
the figure caption vertical placement is currently available).
If literalblockcappos is "b" (captions follow code-blocks), this commit
removes the caption-package added \abovecaptionskip, so that "skip" is
also ignored for code-blocks in this case. This looks better due to the
extra space already added by the framing of the code-block and achieves
same spacing as without caption package (presumably loaded mainly to
style the fonts used for the caption). However in future maybe caption's
package "skip" should be obeyed for "literalblock" caption type.
For testing with caption package I mainly used this:
I checked in particular behaviour of captions of code-blocks inside table cells whether
is made use of or if the default of top positioning of captions for code-blokcs is obeyed.
I made very quick check that hyperlinks to captions still work with
caption
package loaded as above.Feature or Bugfix
Fixes #5520