From 68becb118e8b051605dc5483e2e187ea097b8f4d Mon Sep 17 00:00:00 2001 From: jfbu Date: Fri, 15 Apr 2016 18:48:28 +0200 Subject: [PATCH 1/3] Fix #2446: latex(pdf) sets local tables of contents in unbreakable boxes Allow page breaks in topic contents (e.g. local tables of contents) from replacing \shadowbox of non anymore used package framebox by a custom framed package environment. Formerly, topic boxes extended into right margin; put only the shadow in margin, locate the right frame exactly at the margin. Use framed.sty also for framing admonitions of the warning type. Make vertical spacing more coherent with the one for hint type notices. Handle case with warning notices getting nested; the inner ones use a minipage, only the outer one allows pagebreaks. --- sphinx/texinputs/sphinx.sty | 148 +++++++++++++++++++++++++++++++----- sphinx/writers/latex.py | 7 +- 2 files changed, 131 insertions(+), 24 deletions(-) diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 9166a9509..37aa7176d 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -11,14 +11,16 @@ \@ifclassloaded{memoir}{}{\RequirePackage{fancyhdr}} \RequirePackage{textcomp} +% fancybox not used anymore and will be removed at Sphinx-1.5 \RequirePackage{fancybox} \RequirePackage{titlesec} \RequirePackage{tabulary} \RequirePackage{makeidx} +% For framing code-blocks and warning type notices, and shadowing topics \RequirePackage{framed} +\newif\ifSphinx@inframed % flag set if we are in a framed environment \RequirePackage{ifthen} -%The xcolor package draws better fcolorboxes -%around verbatim code +% The xcolor package draws better fcolorboxes around verbatim code \IfFileExists{xcolor.sty}{ \RequirePackage{xcolor} }{ @@ -241,17 +243,102 @@ \setlength\partopsep{0pt}% \setlength\leftmargin{0pt}% }% - \item\MakeFramed {\FrameRestore}% + \item + % use a minipage if we are already inside a framed environment + \relax\ifSphinx@inframed\noindent\begin{\minipage}{\linewidth}\fi + \MakeFramed {\FrameRestore}% \small \OriginalVerbatim[#1]% } \renewcommand{\endVerbatim}{% \endOriginalVerbatim \endMakeFramed + \ifSphinx@inframed\end{minipage}\fi \endlist % LaTeX environments always revert local changes on exit, here e.g. \parskip } +% define macro to frame contents and add shadow on right and bottom +\def\Sphinx@shadowsep {5\p@} % \p@ means "pt " +\def\Sphinx@shadowsize {4\p@} +\def\Sphinx@shadowrule {\fboxrule} +\long\def\Sphinx@ShadowFBox#1{% + \leavevmode\begingroup + % first we frame the box #1 + \setbox\@tempboxa + \hbox{\vrule\@width\Sphinx@shadowrule + \vbox{\hrule\@height\Sphinx@shadowrule + \kern\Sphinx@shadowsep + \hbox{\kern\Sphinx@shadowsep #1\kern\Sphinx@shadowsep}% + \kern\Sphinx@shadowsep + \hrule\@height\Sphinx@shadowrule}% + \vrule\@width\Sphinx@shadowrule}% + % Now we add the shadow, like \shadowbox from fancybox.sty would do + \dimen@\dimexpr.5\Sphinx@shadowrule+\Sphinx@shadowsize\relax + \hbox{\vbox{\offinterlineskip + \hbox{\copy\@tempboxa\kern-.5\Sphinx@shadowrule + % add shadow on right side + \lower\Sphinx@shadowsize + \hbox{\vrule\@height\ht\@tempboxa \@width\dimen@}% + }% + \kern-\dimen@ % shift back vertically to bottom of frame + % and add shadow at bottom + \moveright\Sphinx@shadowsize + \vbox{\hrule\@width\wd\@tempboxa \@height\dimen@}% + }% + % move left by the size of right shadow so shadow adds no width + \kern-\Sphinx@shadowsize + }% + \endgroup +} + +% use framed.sty to allow page breaks in frame+shadow +% works well inside Lists and Quote-like environments +% produced by ``topic'' directive (or local contents) +% could nest if LaTeX writer authorized it +\newenvironment{SphinxShadowBox} + {\def\FrameCommand {\Sphinx@ShadowFBox }% + % configure framed.sty not to add extra vertical spacing + \OuterFrameSep \z@skip + % the \trivlist will add the vertical spacing on top and bottom which is + % typical of center environment as used in Sphinx <= 1.4.1 + % the \noindent has the effet of an extra blank line on top, to + % imitate closely the layout from Sphinx <= 1.4.1; the \FrameHeightAdjust + % will put top part of frame on this baseline. + \def\FrameHeightAdjust {\baselineskip}% + \trivlist\item\noindent + % use a minipage if we are already inside a framed environment + \ifSphinx@inframed\begin{minipage}{\linewidth}\fi + \MakeFramed {\Sphinx@inframedtrue + % framed.sty puts into "\width" the added width (=2shadowsep+2shadowrule) + % adjust \hsize to what the contents must use + \advance\hsize-\width + % adjust LaTeX parameters to behave properly in indented/quoted contexts + \FrameRestore + % typeset the contents as in a minipage (Sphinx <= 1.4.1 used a minipage and + % itemize/enumerate are therein typeset more tightly, we want to keep + % that). We copy-paste from LaTeX source code but don't do a real minipage. + \@pboxswfalse + \@parboxrestore + % for footnotes, but Sphinx inactivates footnotes in topics + \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@ + \let\@footnotetext\@mpfootnotetext + \let\@listdepth\@mplistdepth \@mplistdepth\z@ + \@minipagerestore + \@setminipage + }% + }% + {% insert the "endminipage" code + \par\unskip + % handle (currently non existing) minipage style footnotes + \ifvoid\@mpfootins\else + \vskip\skip\@mpfootins\normalcolor\footnoterule\unvbox\@mpfootins + \fi + \@minipagefalse + \endMakeFramed + \ifSphinx@inframed\end{minipage}\fi + \endtrivlist + } % \moduleauthor{name}{email} \newcommand{\moduleauthor}[2]{} @@ -315,23 +402,46 @@ % Notices / Admonitions % -\newlength{\py@noticelength} -\newcommand{\py@heavybox}{ - \setlength{\fboxrule}{1pt} - \setlength{\fboxsep}{6pt} - \setlength{\py@noticelength}{\linewidth} - \addtolength{\py@noticelength}{-2\fboxsep} - \addtolength{\py@noticelength}{-2\fboxrule} - %\setlength{\shadowsize}{3pt} - \noindent\Sbox - \minipage{\py@noticelength} -} -\newcommand{\py@endheavybox}{ - \endminipage - \endSbox - \fbox{\TheSbox} -} +% Code adapted from framed.sty's "snugshade" environment. +% Nesting works (inner frames do not allow page breaks). +\newcommand{\py@heavybox}{\par + \setlength{\FrameRule}{\p@}% 1pt + \setlength{\FrameSep}{\dimexpr.6\baselineskip-\FrameRule\relax} + % configure framed.sty's parameters to obtain same vertical spacing + % as for "light" boxes. We need for this to manually insert parskip glue and + % revert a skip done by framed before the frame. + \setlength{\OuterFrameSep}{0pt} + \vspace{\dimexpr\FrameHeightAdjust+\parskip\relax} + % copied/adapted from framed.sty's snugshade + \def\FrameCommand##1{\hskip\@totalleftmargin + \fboxsep\FrameSep \fboxrule\FrameRule\fbox{##1}% + \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}% + % use a minipage if we are already inside a framed environment + \ifSphinx@inframed\noindent\begin{minipage}{\linewidth}\fi + \MakeFramed {\Sphinx@inframedtrue + \advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize + % minipage initialization copied from LaTeX source code. + \@pboxswfalse + \@parboxrestore + % for footnotes + \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@ + \let\@footnotetext\@mpfootnotetext + \let\@listdepth\@mplistdepth \@mplistdepth\z@ + \@minipagerestore + \@setminipage }% + } +\newcommand{\py@endheavybox}{% + \par\unskip + % handles footnotes + \ifvoid\@mpfootins\else + \vskip\skip\@mpfootins\normalcolor\footnoterule\unvbox\@mpfootins + \fi + \@minipagefalse\endMakeFramed + \ifSphinx@inframed\end{minipage}\fi + % arrange for similar spacing below frame as for "light" boxes. + \vskip .4\baselineskip + } \newcommand{\py@lightbox}{% \par\allowbreak diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index d08ab77a1..7ce35b80f 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -706,14 +706,11 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_topic(self, node): self.in_minipage = 1 - self.body.append('\\setbox0\\vbox{\n' - '\\begin{minipage}{0.95\\linewidth}\n') + self.body.append('\n\\begin{SphinxShadowBox}\n') def depart_topic(self, node): self.in_minipage = 0 - self.body.append('\\end{minipage}}\n' - '\\begin{center}\\setlength{\\fboxsep}{5pt}' - '\\shadowbox{\\box0}\\end{center}\n') + self.body.append('\\end{SphinxShadowBox}\n') visit_sidebar = visit_topic depart_sidebar = depart_topic From 75992bc831b28f3d38cbb444cb364453496fe881 Mon Sep 17 00:00:00 2001 From: jfbu Date: Wed, 20 Apr 2016 12:49:43 +0200 Subject: [PATCH 2/3] Update CHANGES for PR #2453 --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 0ac6985f5..bc8aa8b4c 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,10 @@ Features added -------------- * Now :confval:`suppress_warnings` accepts following configurations: ``app.add_node``, ``app.add_directive``, ``app.add_role`` and ``app.add_generic_role`` (ref: #2451) +* LaTeX writer allows page breaks in topic contents; and their horizontal + extent now fits in the line width (shadow in margin). Warning-type + admonitions allow page breaks (if very long) and their vertical spacing + has been made more coherent with the one for Hint-type notices. Bugs fixed ---------- @@ -16,6 +20,7 @@ Bugs fixed * #2397: Setup shorthandoff for turkish documents * #2447: VerbatimBorderColor wrongly used also for captions of PDF * #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders). +* #2446: latex(pdf) sets local tables of contents (or more generally topic nodes) in unbreakable boxes, causes overflow at bottom Release 1.4.1 (released Apr 12, 2016) From d8b4ce585de8d355ababe0ce1d07124eb07010d4 Mon Sep 17 00:00:00 2001 From: jfbu Date: Wed, 20 Apr 2016 13:59:37 +0200 Subject: [PATCH 3/3] fix a latex issue of vertical space modified: sphinx/texinputs/sphinx.sty --- sphinx/texinputs/sphinx.sty | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 20dea3ad7..9c289a578 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -326,7 +326,6 @@ % itemize/enumerate are therein typeset more tightly, we want to keep % that). We copy-paste from LaTeX source code but don't do a real minipage. \@pboxswfalse - \@parboxrestore % for footnotes, but Sphinx inactivates footnotes in topics \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@ \let\@footnotetext\@mpfootnotetext @@ -419,18 +418,21 @@ % as for "light" boxes. We need for this to manually insert parskip glue and % revert a skip done by framed before the frame. \setlength{\OuterFrameSep}{0pt} - \vspace{\dimexpr\FrameHeightAdjust+\parskip\relax} + \vspace{\FrameHeightAdjust} % copied/adapted from framed.sty's snugshade \def\FrameCommand##1{\hskip\@totalleftmargin \fboxsep\FrameSep \fboxrule\FrameRule\fbox{##1}% \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}% % use a minipage if we are already inside a framed environment - \ifSphinx@inframed\noindent\begin{minipage}{\linewidth}\fi + \ifSphinx@inframed + \noindent\begin{minipage}{\linewidth} + \else + \vspace{\parskip} + \fi \MakeFramed {\Sphinx@inframedtrue \advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize % minipage initialization copied from LaTeX source code. \@pboxswfalse - \@parboxrestore % for footnotes \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@ \let\@footnotetext\@mpfootnotetext