Skip to content

Commit

Permalink
Merge pull request #10639 from jfbu/latex_roundedboxes
Browse files Browse the repository at this point in the history
LaTeX: optional rounded corners for framing of code-blocks
  • Loading branch information
jfbu committed Jul 6, 2022
2 parents c8f0112 + 34fe9d0 commit 9da25be
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 3 deletions.
5 changes: 5 additions & 0 deletions doc/conf.py
Expand Up @@ -74,6 +74,11 @@
{\footnotesize\raggedright\printindex}
{\begin{sphinxtheindex}\end{sphinxtheindex}}
''',
'sphinxsetup': """%
VerbatimColor={RGB}{242,242,242},%
VerbatimBorderColor={RGB}{32,32,32},%
verbatimradius=3pt%
""",
}
latex_show_urls = 'footnote'
latex_use_xindy = True
Expand Down
45 changes: 42 additions & 3 deletions doc/latex.rst
Expand Up @@ -8,8 +8,11 @@ LaTeX customization

\begingroup
\sphinxsetup{%
verbatimwithframe=false,
verbatimborder=2pt,
verbatimsep=5pt,
verbatimradius=5pt,
VerbatimColor={named}{OldLace},
VerbatimBorderColor={named}{Gold},
TitleColor={named}{DarkGoldenrod},
hintBorderColor={named}{LightCoral},
attentionborder=3pt,
Expand Down Expand Up @@ -580,8 +583,17 @@ start of the chapter::

\begingroup
\sphinxsetup{%
verbatimwithframe=false,
% These were used as defaults for the whole sphinx.pdf
% VerbatimColor={RGB}{242,242,242},%
% VerbatimBorderColor={RGB}{32,32,32},%
% verbatimradius=3pt,%
% New definitions for this chapter code-blocks only:
VerbatimColor={named}{OldLace},
VerbatimBorderColor={named}{Gold},
verbatimradius=5pt,
verbatimsep=5pt,
verbatimborder=2pt,
% Other configuration for this chapter only:
TitleColor={named}{DarkGoldenrod},
hintBorderColor={named}{LightCoral},
attentionborder=3pt,
Expand All @@ -593,7 +605,8 @@ start of the chapter::
cautionBorderColor={named}{Cyan},
cautionBgColor={named}{LightCyan}}

The below is included at the end of the chapter::
And this is placed at the end of the chapter source to end the scope of
the configuration::

.. raw:: latex

Expand Down Expand Up @@ -839,6 +852,32 @@ Do not use quotes to enclose values, whether numerical or strings.

Default: ``\fboxrule``

``verbatimradius``
The radius of the rounded corners of the frame around :rst:dir:`code-block`\ s.

Default: ``0pt``

.. versionadded:: 5.1.0

If non-zero, it will trigger the loading of LaTeX package pict2e_.

.. caution::

The interface will remain experimental during the 5.x cycle: the
feature itself will remain, but the interface may evolve to include
other display elements such as admonitions. For the latter it is
actually already possible for LaTeX-expert Sphinx users to use
functionalities of LaTeX packages such as tcolorbox_, via
redefinitions of the ``sphinxheavybox`` and ``sphinxlightbox``
`Environments`_. This would be more difficult for code-blocks, and
this key achieves it. The pict2e_ interface to some basic PDF
graphics operations is much more light-weight than the pgf_
framework used by tcolorbox_.

.. _pict2e: https://ctan.org/pkg/pict2e
.. _tcolorbox: https://ctan.org/pkg/tcolorbox
.. _pgf: https://ctan.org/pkg/pgf

``shadowsep``
The separation between contents and frame for :dudir:`contents` and
:dudir:`topic` boxes.
Expand Down
10 changes: 10 additions & 0 deletions sphinx/texinputs/sphinx.sty
Expand Up @@ -74,6 +74,7 @@
% dimensions, we declare the \dimen registers here.
\newdimen\sphinxverbatimsep
\newdimen\sphinxverbatimborder
\newdimen\sphinxverbatimradius
\newdimen\sphinxshadowsep
\newdimen\sphinxshadowsize
\newdimen\sphinxshadowrule
Expand All @@ -87,6 +88,12 @@
\define@key{sphinx}{verbatimsep}{\sphinxverbatimsep\dimexpr #1\relax}
\sphinxverbatimborder=\fboxrule
\define@key{sphinx}{verbatimborder}{\sphinxverbatimborder\dimexpr #1\relax}
\sphinxverbatimradius=0pt
\define@key{sphinx}{verbatimradius}{%
\sphinxverbatimradius\dimexpr #1\relax
\ifdim\sphinxverbatimradius=\z@\else\RequirePackage{sphinxpackageboxes}\fi
}
\AtBeginDocument{\define@key{sphinx}{verbatimradius}{\sphinxverbatimradius\dimexpr #1\relax}}
% topic boxes
\sphinxshadowsep =5pt
\define@key{sphinx}{shadowsep}{\sphinxshadowsep\dimexpr #1\relax}
Expand Down Expand Up @@ -274,6 +281,9 @@
\input{sphinxlatexadmonitions.sty}
\input{sphinxlatexliterals.sty}
\input{sphinxlatexshadowbox.sty}
\ifdim\sphinxverbatimradius=\z@\else
\RequirePackage{sphinxpackageboxes}
\fi


%% CONTAINERS
Expand Down
116 changes: 116 additions & 0 deletions sphinx/texinputs/sphinxpackageboxes.sty
@@ -0,0 +1,116 @@
%% COLORED BOXES
%
% change this info string if making any custom modification
\ProvidesPackage{sphinxpackageboxes}[2022/07/04 v5.1.0 advanced colored boxes]

% Currently, this file only provides a replacement to the \spx@verb@fcolorbox
% of sphinxlatexliterals.sty which will draw boxes with a frame having
% rounded corners, and a background color.
%
% It needs \sphinxverbatimsep, \sphinxverbatimborder and a new parameter
% \sphinxverbatimradius
%
% Executes \RequirePackage for:
%
% - pict2e. Ideally we would need a recent version of this package which
% allows dimensional arguments to its \moveto, \lineto, etc...
% but we add ourselves some wrapper to facilitate the usage.


% MEMO: we have also successfully tested usage of tcolorbox's \tcbox but
% decided to use pict2e.sty for the following reasons:
% 1- an order of magnitude faster for what we want to do,
% 2- orders of magnitude smaller dependency (tcolorbox uses the pgf TeX
% framework)
% 3- possibility to accomplish already quite fancy boxes with pict2e
% (and the additional coding as contributed here).

% In this first installment, the caption and continuation hints of code-blocks
% are done exactly as formerly; only difference is in the rounded corrners.
% The space occupied is same, if nothing else is changed.

\IfFileExists{pict2e.sty}
{\RequirePackage{pict2e}}
{\PackageWarningNoLine{sphinx}{%
The package pict2e is required for rounded boxes.\MessageBreak
It does not seem to be available on your system.\MessageBreak
The verbatimradius setting will thus be ignored}%
\AtEndDocument{\PackageWarningNoLine{sphinx}{%
I issued a warning which may have gotten lost in the\MessageBreak
gigantic console output: pict2e.sty was not found,\MessageBreak
and verbatimradius has been ignored}}\endinput}

% First we define some wrapper to be able to use arguments being (only)
% dimensions or dimensional expressions. The \unitlength will always be 1pt.
\def\spx@moveto(#1,#2)%
{\moveto(\strip@pt\dimexpr#1,\strip@pt\dimexpr#2)}
\def\spx@lineto(#1,#2)%
{\lineto(\strip@pt\dimexpr#1,\strip@pt\dimexpr#2)}
% attention we use here [2] always; and there are two more mandatory
% arguments, angles, we don't need to worry about them here.
\def\spx@circlearc#1#2#3{\circlearc[2]%
{\strip@pt\dimexpr#1}{\strip@pt\dimexpr#2}{\strip@pt\dimexpr#3}%
}

% TODO: add top right bottom left padding possibilities.
\long\def\spx@verb@fcolorbox #1#2#3{%
% Prepare a box with the contents and reserved space for framing.
\setbox\tw@\hbox{\kern\dimexpr\sphinxverbatimborder+\sphinxverbatimsep\relax
{#3}\kern\dimexpr\sphinxverbatimborder+\sphinxverbatimsep\relax}%
\ht\tw@ \dimexpr\ht\tw@+\sphinxverbatimsep+\sphinxverbatimborder\relax
\dp\tw@ \dimexpr\dp\tw@+\sphinxverbatimsep+\sphinxverbatimborder\relax
\vbox{%
% Prepare a macro for path to be inserted in a picture environment for stroke
% and fill; the path will be redefined for each of fill or stroke. This macro
% does nothing yet.
\def\spx@dopath{%
\spx@moveto(\sphinxverbatimradius,\z@)% \z@ not 0 as our \spx@moveto is quite dumb
\spx@lineto(\wd\tw@-\sphinxverbatimborder-\sphinxverbatimradius,\z@)%
\spx@circlearc{\wd\tw@-\sphinxverbatimborder-\sphinxverbatimradius}%
{\sphinxverbatimradius}%
{\sphinxverbatimradius}{-90}{0}%
\spx@lineto(\wd\tw@-\sphinxverbatimborder,\ht\tw@+\dp\tw@-\sphinxverbatimborder-\sphinxverbatimradius)%
\spx@circlearc{\wd\tw@-\sphinxverbatimborder-\sphinxverbatimradius}
{\ht\tw@+\dp\tw@-\sphinxverbatimborder-\sphinxverbatimradius}%
{\sphinxverbatimradius}{0}{90}%
\spx@lineto(\sphinxverbatimradius,\ht\tw@+\dp\tw@-\sphinxverbatimborder)%
\spx@circlearc{\sphinxverbatimradius}%
{\ht\tw@+\dp\tw@-\sphinxverbatimborder-\sphinxverbatimradius}%
{\sphinxverbatimradius}{90}{180}%
\spx@lineto(\z@,\sphinxverbatimradius)%
\spx@circlearc{\sphinxverbatimradius}{\sphinxverbatimradius}{\sphinxverbatimradius}{180}{270}%
}% end of definition of \spx@dopath
%
#1% continuation hint attached above frame
% there will be a small "\lineskip" space here from TeX
% draw frame border _latest_ to avoid pdf viewer issue
% be careful not to cause "color push + contents + color pop"
% MEMO: when pict2e doth a path stroke, the path is in the middle of the line
% width, i.e. the line extends by half its width to the exterior of the filled
% path. This explains some 0.5 things below.
\hbox{\setlength{\unitlength}{1pt}% attention to space token here
% work around for "old" LaTeX (we could use the "picture" package, this
% would add another dependency)
\begin{picture}%
(\strip@pt\wd\tw@,\strip@pt\dimexpr\ht\tw@+\dp\tw@)%
(\strip@pt\dimexpr-.5\sphinxverbatimborder,\strip@pt\dimexpr-.5\sphinxverbatimborder)%
\color{VerbatimColor}% color for background
\spx@dopath\fillpath
\color{VerbatimBorderColor}% color for border
\ifspx@opt@verbatimwithframe % even with \sphinxverbatimborder set to 0pt, the
% stroke will produce a visible contour, so we
% must explicitly exclude doing it.
\linethickness{\sphinxverbatimborder}%
\spx@dopath\strokepath
\fi
\end{picture}}%
% now the contents
\kern-\dimexpr\ht\tw@+\dp\tw@\relax
\copy\tw@ % attention that #2 will need \wd\tw@
\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
}%

\endinput

0 comments on commit 9da25be

Please sign in to comment.