Skip to content

Commit

Permalink
Fix #10638: LaTeX code-blocks when highlighted token uses \fcolorbox
Browse files Browse the repository at this point in the history
This commit also does some internal refactoring in order to ease up
projected PRs.
  • Loading branch information
jfbu committed Jul 4, 2022
1 parent 7e76f2c commit d4c8e84
Showing 1 changed file with 78 additions and 74 deletions.
152 changes: 78 additions & 74 deletions sphinx/texinputs/sphinxlatexliterals.sty
Expand Up @@ -111,83 +111,87 @@
\let\spx@original@set@color\set@color
% About the produced output:
% - it obeys current indentation,
% - frame of width \fboxrule is \fboxsep-separated from the contents,
% - the contents use the full available text width,
% - #1 = color of frame, #2 = color of background,
% - #3 = will be typeset above frame, in a non detachable way,
% - #4 = will be typeset below frame, in a non detachable way,
% - #5 = will be typeset within frame,
% #3 and #4 are expected to be already typeset \hbox'es.
% #5 are the contents, and in the context of usage of fancyvrb+framed by
% Sphinx, it will arrive here already transformed into horizontal boxes,
% as well as some interline penalties and glues.
\long\def\spx@fcolorbox #1#2#3#4#5{%
% - frame of width \sphinxverbatimborder is \sphinxverbatimsep -arated
% from the contents,
% - the contents use the full available text width, limited by indentation,
% - #1 = will be typeset above frame, in a non detachable way,
% - #2 = will be typeset below frame, in a non detachable way,
% - #3 = will be typeset within the frame.
% #1 and #2 are expected to be already typeset \hbox'es.
% #3 are the contents, and in the context of usage of fancyvrb+framed,
% it will arrive here already transformed into horizontal boxes,
% interline penalties and glues.
\long\def\spx@verb@FrameCommand #1#2#3{%
% These \hskips are for fancyvrb.sty measuring and will make the
% framing "adapt" to an indented context.
\ifspx@opt@verbatimwithframe\else\sphinxverbatimborder\z@\fi
\hskip\@totalleftmargin
\hskip-\fboxsep\hskip-\fboxrule
% MEMO: this code is modified from color.sty's \color@b@x which has some
% features making it problematic when #5, as will be here the case in the
% context of usage of fancyvrb+framed+\spx@verb@@PreProcessLine may contain
% an unbalanced "color push". We must avoid an extra "color pop" located at
% a page break location. For this reason we do not add a \set@color or
% \normalcolor at start of #5.
\setbox\z@\hbox{\kern\fboxsep{#5}\kern\fboxsep}%
\dimen@\ht\z@ \advance\dimen@\fboxsep \ht\z@\dimen@
\dimen@\dp\z@ \advance\dimen@\fboxsep \dp\z@\dimen@
% \spx@CustomFbox uses already scope-limiting group, no need for one more
\spx@CustomFBox{#1}% frame color
{#3}% above frame, already a box
{#4}% below frame, already a box
{\def\set@color{\let\set@color\spx@original@set@color}%
\color{#2}% above trick avoids a color pop *after* \box\z@
% MEMO: it is very very improbable that \color/\color@block
% will ever change (even if we raised some ticket at
% their issue tracker), but if they do, perhaps a
% change here could be needed in some distant future.
% MEMO: the \color@block "push + pop" happens *before* \box\z@
\color@block{\wd\z@}{\ht\z@}{\dp\z@}%
\box\z@}%
\hskip-\fboxsep\hskip-\fboxrule
\hskip-\sphinxverbatimsep\hskip-\sphinxverbatimborder
\spx@verb@fcolorbox {#1}{#2}{#3}%
\hskip-\sphinxverbatimsep\hskip-\sphinxverbatimborder
\hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth
}%
% #1 = color of frame
% #2 = for material above frame, such as a caption or a "continued" hint
% #3 = for material below frame, such as a caption or "continues on next page"
% #4 = contents; or rather if called from \spx@fcolorbox (only supported use
% case here), the contents are in \box\z@ and #4 are the instructions to
% "fill background color then draw contents \box\z@"
\long\def\spx@CustomFBox#1#2#3#4{%
\begingroup
% formerly, we used \@tempboxa, but let's use private box for maximal safety
\setbox\spx@verb@tempboxa\hbox{#4}% no (more) need for extra grouping (now)
\vbox{#2% above frame
\long\def\spx@verb@fcolorbox #1#2#3{%
% MEMO: in the context of framed.sty this will always expand inside some
% \hbox isolated from other code, so we can use \box\z@, \box\tw@,...
% with no need of extra group.
%
% MEMO: this code was originally using \color@b@x but the latter has
% problematic features regarding color in a context like here where #3
% may contain an unbalanced "color push".
%
% MEMO: Some PDF viewers have (or had) issues when the external frame is
% drawn first, then the background color is added. So we will draw first
% the background color (and let it extend to the frame area) then, hence
% on top of it the frame. And we draw the contents latest.
%
% TODO: add top right bottom left padding possibilities.
% Prepare a box with the contents and reserved space for framing.
\setbox\z@\hbox{\kern\dimexpr\sphinxverbatimborder+\sphinxverbatimsep\relax
{#3}\kern\dimexpr\sphinxverbatimborder+\sphinxverbatimsep\relax}%
\ht\z@ \dimexpr\ht\z@+\sphinxverbatimsep+\sphinxverbatimborder\relax
\dp\z@ \dimexpr\dp\z@+\sphinxverbatimsep+\sphinxverbatimborder\relax
% Prepare colored background
\setbox\tw@\hbox{{\color{VerbatimColor}\vrule\@width\wd\z@\@height\ht\z@\@depth\dp\z@}}%
\vbox{#1% continuation hint attached above frame
% draw frame border _latest_ to avoid pdf viewer issue
% be careful not to cause "color push + contents + color pop"
\kern\fboxrule
\hbox{\kern\fboxrule
\copy\spx@verb@tempboxa% \copy to keep \wd, \dp, \ht for later
{\color{#1}% frame color
\kern-\wd\spx@verb@tempboxa\kern-\fboxrule
\vrule\@width\fboxrule
\kern\wd\spx@verb@tempboxa
\vrule\@width\fboxrule}%
}%
{\color{#1}% frame color
\kern-\dimexpr\ht\spx@verb@tempboxa+\dp\spx@verb@tempboxa+\fboxrule\relax
\hrule\@height\fboxrule
\kern\dimexpr\ht\spx@verb@tempboxa+\dp\spx@verb@tempboxa\relax
\hrule\@height\fboxrule}%
#3% below frame
}%
\endgroup
% there will be a small "\lineskip" space here from TeX
% the colored background
\copy\tw@
% stroke the frame
\kern-\dimexpr\ht\tw@+\dp\tw@\relax
{\color{VerbatimBorderColor}% frame color
\hrule\@height\sphinxverbatimborder % width computed by TeX
\setbox\tw@\hb@xt@\wd\z@
{% the vrule height will be auto computed later by TeX
\vrule\@width\sphinxverbatimborder
\hss
\vrule\@width\sphinxverbatimborder
}%
\ht\tw@\dimexpr\ht\z@-\sphinxverbatimborder\relax
\dp\tw@\dimexpr\dp\z@-\sphinxverbatimborder\relax
\box\tw@
\hrule\@height\sphinxverbatimborder
}% color pop here
% now the contents
\kern-\dimexpr\ht\tw@+\dp\tw@\relax
\box\z@
% Former code had a \hrule here so we need to suppress interline glue
% to keep exact same output now that it is a \hbox above
\nointerlineskip
% TODO: add some \lineskip glue here, this is all in a \vbox so can't split
#2% continuation hint attached below frame
}% end of \vbox
}%
\def\spx@fcolorbox@put@c#1{% hide width from framed.sty measuring
\moveright\dimexpr\fboxrule+.5\wd\spx@verb@tempboxa\hb@xt@\z@{\hss#1\hss}%
\moveright.5\wd\tw@\hb@xt@\z@{\hss#1\hss}%
}%
\def\spx@fcolorbox@put@r#1{% right align with contents, width hidden
\moveright\dimexpr\fboxrule+\wd\spx@verb@tempboxa-\fboxsep\hb@xt@\z@{\hss#1}%
\moveright\dimexpr\wd\tw@-\sphinxverbatimsep-\sphinxverbatimborder\hb@xt@\z@{\hss#1}%
}%
\def\spx@fcolorbox@put@l#1{% left align with contents, width hidden
\moveright\dimexpr\fboxrule+\fboxsep\hb@xt@\z@{#1\hss}%
\moveright\dimexpr\sphinxverbatimborder+\sphinxverbatimsep\hb@xt@\z@{#1\hss}%
}%
%
\def\sphinxVerbatim@Continued
Expand All @@ -204,15 +208,14 @@
\newcommand*\literalblockcontinuedname{continued from previous page}%
\newcommand*\literalblockcontinuesname{continues on next page}%
%
\def\spx@verbatimfcolorbox{\spx@fcolorbox{VerbatimBorderColor}{VerbatimColor}}%
\def\sphinxVerbatim@FrameCommand
{\spx@verbatimfcolorbox\sphinxVerbatim@Before\sphinxVerbatim@After}%
{\spx@verb@FrameCommand\sphinxVerbatim@Before\sphinxVerbatim@After}%
\def\sphinxVerbatim@FirstFrameCommand
{\spx@verbatimfcolorbox\sphinxVerbatim@Before\sphinxVerbatim@Continues}%
{\spx@verb@FrameCommand\sphinxVerbatim@Before\sphinxVerbatim@Continues}%
\def\sphinxVerbatim@MidFrameCommand
{\spx@verbatimfcolorbox\sphinxVerbatim@Continued\sphinxVerbatim@Continues}%
{\spx@verb@FrameCommand\sphinxVerbatim@Continued\sphinxVerbatim@Continues}%
\def\sphinxVerbatim@LastFrameCommand
{\spx@verbatimfcolorbox\sphinxVerbatim@Continued\sphinxVerbatim@After}%
{\spx@verb@FrameCommand\sphinxVerbatim@Continued\sphinxVerbatim@After}%

% For linebreaks inside Verbatim environment from package fancyvrb.
\newbox\sphinxcontinuationbox
Expand Down Expand Up @@ -675,8 +678,6 @@
\fi
\global\let\sphinxLiteralBlockLabel\empty
\global\let\sphinxVerbatimTitle\empty
\fboxsep\sphinxverbatimsep \fboxrule\sphinxverbatimborder
\ifspx@opt@verbatimwithframe\else\fboxrule\z@\fi
\let\FrameCommand \sphinxVerbatim@FrameCommand
\let\FirstFrameCommand\sphinxVerbatim@FirstFrameCommand
\let\MidFrameCommand \sphinxVerbatim@MidFrameCommand
Expand Down Expand Up @@ -756,8 +757,11 @@
\dp\sphinxVerbatim@ContentsBox+
\ht\sphinxVerbatim@TitleBox+
\dp\sphinxVerbatim@TitleBox+
2\fboxsep+2\fboxrule+
2\sphinxverbatimsep+\ifspx@opt@verbatimwithframe 2\sphinxverbatimborder+\fi
% try to account for external frame parameters
% MEMO: this is because the sphinxheavybox (for warning admonitions)
% environment sets \FrameSep and \FrameRule
% TODO: fix this bad implicit dependency
\FrameSep+\FrameRule+
% Usage here of 2 baseline distances is empirical.
% In border case where code-block fits barely in remaining space,
Expand Down

0 comments on commit d4c8e84

Please sign in to comment.