forked from sphinx-doc/sphinx
-
Notifications
You must be signed in to change notification settings - Fork 1
/
sphinxlatexshadowbox.sty
152 lines (148 loc) · 6.75 KB
/
sphinxlatexshadowbox.sty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
%% TOPIC AND CONTENTS BOXES
%
% change this info string if making any custom modification
\ProvidesFile{sphinxlatexshadowbox.sty}[2022/06/30 sphinxShadowBox]
% Provides support for this output mark-up from Sphinx latex writer:
%
% - sphinxShadowBox (environment)
%
% Dependencies (they do not need to be defined at time of loading):
%
% - of course the various colour and dimension options handled via sphinx.sty
% - dimension register \spx@image@maxheight from sphinxlatexgraphics.sty
% - \savenotes/\spewnotes from sphinxpackagefootnote
% - \ifspx@inframed defined in sphinx.sty
%
% Requires:
\RequirePackage{framed}
% Let's draw the contents first, then the frame and the shadow last,
% to avoid problems with some pdf viewers.
\long\def\spx@ShadowFBox#1{%
\leavevmode\begingroup
% First we prepare a box with the contents and some reserved space for the
% frame and inner separation; with more parameters we could allow various
% border widths for top, bottom, left, right, but here all are equal.
\setbox\@tempboxa
\hbox{\kern\sphinxshadowrule
\vbox{\kern\sphinxshadowrule
\kern\sphinxshadowsep
\hbox{\kern\sphinxshadowsep #1\kern\sphinxshadowsep}%
\kern\sphinxshadowsep
\kern\sphinxshadowrule}%
\kern\sphinxshadowrule}%
% Now we rebox, adding the colored frame for which space was reserved.
\setbox\@tempboxa
\hbox{\unhcopy\@tempboxa % not \unhbox to be able to refer to \ht, \wd later
\kern-\wd\@tempboxa
{\color{sphinxshadowBorderColor}% color push here
\vrule\@width\sphinxshadowrule% TeX auto-computes the height
\vbox{\hrule\@height\sphinxshadowrule% TeX auto-computes the width
\kern\dimexpr\ht\@tempboxa-\sphinxshadowrule\relax
% This empty \hbox is here to give width used by \hrule
% As \dp\@tempboxa is zero, the \hbox location is at the
% bottom of frame.
\hbox{\kern\dimexpr\wd\@tempboxa-2\sphinxshadowrule\relax}%
\kern\dimexpr\dp\@tempboxa-\sphinxshadowrule\relax
\hrule\@height\sphinxshadowrule% TeX auto-computes the width
}%
\vrule\@width\sphinxshadowrule% TeX auto-computes the height
}% color pop will happen here
}%
% Now we add the shadow.
%
% Formerly, shadow was drawn partly on top of frame, but this was before
% both frame and shadow acquired colors. The width of the part of the
% shadow on the right is hidden, so it will stick into the right page
% margin.
%
% The frame borders are included into this final \hbox, which is sent back
% to \MakeFramed/\endMakeFramed measurements and then finally to page
% shipout. As \advance\hsize-\width appears in \MakeFramed, where \width is
% the computed extra width added by the framing plus inner separation (so
% actually 2\sphinxshadowrule+2\sphinxshadowsep), this all means that
% horizontally the frame will be perfectly adjusted to the *total* text
% width limits (i.e. independent of current list nesting; but anyhow
% Docutils does not allow nesting of topic within topics or body elements).
\hbox{\vbox{\offinterlineskip
\hbox{\copy\@tempboxa % not \box as we need \wd and \ht next
% add shadow on right side
\lower\sphinxshadowsize
\hbox{{\color{sphinxshadowShadowColor}%
\vrule\@height\ht\@tempboxa \@width\sphinxshadowsize}}%
}%
\kern-\sphinxshadowsize % shift back vertically to bottom of frame
% and add shadow at bottom
\moveright\sphinxshadowsize
\vbox{{\color{sphinxshadowShadowColor}%
\hrule\@width\wd\@tempboxa \@height\sphinxshadowsize}}%
}%
% move left by the size of right shadow so shadow adds no width, and
% will stick into right margin
% (we did not conceal of course from TeX the depth)
\kern-\sphinxshadowsize
}%
\endgroup
}
% Use framed.sty \MakeFramed/\endMakeFramed to allow page breaks for topic
% boxes. Originally Sphinx used \shadowbox from fancybox.sty but it did not
% allow pagebreaks (which was problematic for "contents" directive if there
% are many subsections).
%
% Docutils does not allow topic to be nested within topics or other body
% elements. But the LaTeX code here does allow it:
%
% - a topic inside another topic would be rendered in a minipage (thus not
% allowing pagebreaks). Its external frame would adapt perfectly to
% the *current (smaller) width for text*.
%
% - a topic inside (nested) lists or quote environments would have its frame
% take the *full width* of the page, but its text contents on the other hand
% would obey exactly the current indentation plus inner separation. This is
% in contrast with the framing used for literal blocks, also based, but in a
% more sophisticated way on usage of \MakeFramed/\endMakeFramed, and
% adjusting to current text indentation.
\newenvironment{sphinxShadowBox}
{\def\FrameCommand {\spx@ShadowFBox }%
\advance\spx@image@maxheight
-\dimexpr2\sphinxshadowrule
+2\sphinxshadowsep
+\sphinxshadowsize
+\baselineskip\relax
% configure framed.sty not to add extra vertical spacing
\ltx@ifundefined{OuterFrameSep}{}{\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}%
% use package footnote to handle footnotes
\savenotes
\trivlist\item\noindent
% use a minipage if we are already inside a framed environment
\ifspx@inframed\begin{minipage}{\linewidth}\fi
\MakeFramed {\spx@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
\let\@listdepth\@mplistdepth \@mplistdepth\z@
\@minipagerestore
\@setminipage
}%
}%
{% insert the "endminipage" code
\par\unskip
\@minipagefalse
\endMakeFramed
\ifspx@inframed\end{minipage}\fi
\endtrivlist
% output the stored footnotes
\spewnotes
}
\endinput