From cf5dbf70c6bd40b1959580618f178b3f3fee09a0 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 6 Dec 2015 23:50:41 +0000 Subject: longfbox (6dec15) git-svn-id: svn://tug.org/texlive/trunk@39028 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/longfbox/README | 54 + Master/texmf-dist/doc/latex/longfbox/longfbox.html | 1401 ++++++++++++++++++++ Master/texmf-dist/doc/latex/longfbox/longfbox.pdf | Bin 0 -> 104733 bytes Master/texmf-dist/tex/latex/longfbox/longbox.sty | 853 ++++++++++++ Master/texmf-dist/tex/latex/longfbox/longfbox.sty | 1344 +++++++++++++++++++ 5 files changed, 3652 insertions(+) create mode 100644 Master/texmf-dist/doc/latex/longfbox/README create mode 100644 Master/texmf-dist/doc/latex/longfbox/longfbox.html create mode 100644 Master/texmf-dist/doc/latex/longfbox/longfbox.pdf create mode 100644 Master/texmf-dist/tex/latex/longfbox/longbox.sty create mode 100644 Master/texmf-dist/tex/latex/longfbox/longfbox.sty (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/latex/longfbox/README b/Master/texmf-dist/doc/latex/longfbox/README new file mode 100644 index 00000000000..d1e8c5f40e1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/longfbox/README @@ -0,0 +1,54 @@ +This is the README file for the longfbox package. + +VERSION + +Version 1.0, December 2015 + +SUMMARY + +The `longfbox` package provides convenient framed boxes that can be customized +using standard CSS attributes and broken over multiple pages. +It was written to support precise rendering of Madoko documents in LaTeX. +Notable features are: + +* Specify the boxes using standard CSS attributes like `border-style=dashed` + or `border-top-left-radius=10pt`. Almost all of the CSS 2.0 attributes + with regard to borders, background, padding, and margins are supported. + +* Fast and portable: only uses the standard LaTeX `picture` + environment for drawing and does not depend on loading big packages + like `tikz` or `pstricks`, which makes running LaTeX much faster. + +* Supports breakable boxes that span multiple columns or pages. This package + builds on the `longbox` package to break boxes over multiple pages. + +* Much care has been put in precise rendering with proper baseline + alignment and no spurious extra whitespace. + +* In contrast to larger packages like `mdframed` or `tcolorbox`, the + `longfbox` package does not have more extensive features like frame + titles, middle lines, skins, etc. The focus of this package + is on rendering boxes well with full CSS support where every + corner and side can be styled separately with good looking transitions + (and where we only depend on the standard `picture` environment). + +LICENSE + +Copyright (c) 2015 Daan Leijen. + +This software is author-maintained. Permission is granted to copy, +distribute and/or modify this software under the terms of the +LaTeX Project Public License, version 1.3 or higher. This software +is provided 'as it is', without warranty of any kind, either +expressed or implied, including, but not limited to, the implied +warranties of merchantability and fitness for any particular purpose. + +RELATED PACKAGES + +options, ellipse, pict2e, mdframed, tcolorbox + +AUTHOR + +Daan Leijen (daan@microsoft.com) + + diff --git a/Master/texmf-dist/doc/latex/longfbox/longfbox.html b/Master/texmf-dist/doc/latex/longfbox/longfbox.html new file mode 100644 index 00000000000..250a296cd5c --- /dev/null +++ b/Master/texmf-dist/doc/latex/longfbox/longfbox.html @@ -0,0 +1,1401 @@ + + + + + + + + The $\mbox{\lfbox[rounded]{longfbox}}${math-needpdf=true} package + + + + + + +
+ +
+
+
The $\mbox{\lfbox[rounded]{longfbox}}$ package
+
Breakable boxes with standard CSS attributes.
+
+
+
Daan Leijen
+
2015-12-05
+ +

1. Introduction

+

The longfbox package provides framed boxes that can be customized +using standard CSS attributes. It was written to support precise rendering +of Madoko documents in $\mbox{\LaTeX}$. Notable features are: +

+ +

2. Overview

+

There are two ways to create a framed +box, the environment longfbox and the command \lfbox. +

+
\lfbox[options]{content}
+
+

The options are optional and specify CSS attributes. Just +like the regular \fbox command, the \lfbox +command sets the content in a horizontal box and cannot break +the content over multiple lines (but it can contain other boxes +like a \parbox or minipage environment.). The default width +of an \lfbox is the natural width of its content. This +corresponds to a CSS inline element. +

+
+ +
Here is an \lfbox{inline} box, just like an \fbox{fbox}.
+
Here is an \lfbox{inline} box, just like an \fbox{fbox}.
+
\begin{longfbox}[options]content\end{longfbox}
+
+

The longfbox environment sets the content in a long vertical +box and can break content over multiple columns or pages. The +default width is the current \linewidth. This corresponds +to a CSS block element. +

+
+ +
\begin{longfbox}
+The \textsf{longfbox} can contain much
+longer content and will by default be 
+as wide as the current line width. 
+\end{longfbox}
+
\begin{longfbox}
+The \textsf{longfbox} can contain much
+longer content and will by default be 
+as wide as the current line width. 
+\end{longfbox}
+
\newfboxstyle{name}{options}
+
+

Defines a new style that can be used to specify commonly used +options. For example, the package defines: +

+
\newfboxstyle{tight}{padding=0pt,margin=0pt,baseline-skip=false}
+

The new style tight can now be used to render a tight box: +

+
+ +
Here is a \lfbox[tight]{tight} box. 
+
Here is a \lfbox[tight]{tight} box.
+

The \lfbox and longfbox environment can replace many +commands in $\mbox{\LaTeX}$ through the rich CSS interface. +In particular: +

+ + +
\fboxset{options}
+
+

Options can be set for the current scope through this declaration. +For example, to make all borders rounded and red by default, use: +

+
+ +
\fboxset{rounded,border-color=red}%
+Here is a \lfbox{rounded} box. 
+
\fboxset{rounded,border-color=red}%
+Here is a \lfbox{rounded} box.

3. Styling with CSS

+
+
\newcommand\showindex{% 
+  \sffamily\small\roundcap
+  \put(0,-18){%
+  %\put(0,0){\circle*{2}}
+  \put(140,9){\udvector{9}{\put(2,-3){margin-bottom}}}%
+  \put(140,195){\udvector{9}{\put(2,-3){margin-top}}}%
+  \put(140,22){%
+    \put(0,20){\udvector{20}{\put(0,1){ padding-bottom}}}%
+    \put(0,140){\udvector{20} {\put(2,-6){padding-top}}}%
+    \put(10,80){\udvector{40} {\put(3,15){height}}}%
+  }% 
+  \put(45,100){%
+    \rlvector{30}{\put(-22,3){padding-left}}%
+    \put(240,0){\rlvector{30}{\put(-25,3){padding-right}}}%
+    \put(120,-10){\rlvector{90}{\put(10,3){width}}}
+  }%
+  \put(60,126){%
+    \line(0,1){60}%
+    \put(-30,30){\colorbox{white}{top-left-radius}}%
+    \vector(-1,0){60}\vector(-1,1){42.42}%\circle*{1}%
+  }%
+  \put(-9,100){%
+    \rlvector{9}{\put(4,3){\llap{margin-left}}}%
+  }
+  \put(328,100){% 
+    \rlvector{9}{\put(-4,3){\rlap{margin-right}}}%
+  }%
+  \put(20,43){border-left-width}%
+  \put(-10,52){\vector(1,0){10}}
+  \put(25,52){\vector(-1,0){10}}
+  %
+  \put(300,43){\llap{border-right-style}}%  
+  \put(300,48){\line(1,1){11.7}}%
+  \put(317,65){\circle{15}}
+  %
+  \put(10,33){\circle{6}}
+  \put(10,6){\put(0,2){\line(0,1){22}}$\,$border-left-color}
+  %
+  \put(240,192){border-top-width}
+  \put(238,196){\vector(0,-1){10}}
+  \put(238,172){\vector(0,1){10}}
+  }%
+}%
+\lfbox[tight,border-color=silver]{%
+\noindent\begin{longfbox}[width=180pt,height=80pt,
+      vertical-align=top,
+      padding={40pt,60pt},margin=18pt,
+      show-markers=false,
+      marker-color=black,
+      border-width=4pt,
+      border-radius=25pt,
+      border-top-left-radius=60pt,
+      border-left-width=15pt,
+      border-left-color=teal,
+      %border-left-style=dashed,
+      %border-bottom-style=dashed,
+      border-right-style=double,
+      background-color=silver,
+      background-clip=content-box,
+      picture-insert-after={\showindex},
+    ]
+    \iffalse
+      \color{white}\small There is more in you of good than you know, child of the kindly West. Some courage and some wisdom, blended in measure. If more of us valued food and cheer and song above hoarded gold, it would be a merrier world. But sad or merry, I must leave it now. Farewell!
+    \else
+    \strut\hfill\textsf{\small content-box }
+    \fi
+\end{longfbox}%
+}
+
+ +
Figure 1. Attributes of the longfbox are modeled after the corresponding CSS attributes. Borders are drawn using the standard picture environment.
+

In the options you can specify standard CSS attributes to style +your boxes. Figure 1 shows the basic CSS attributes that +determine how a box is rendered. If you have used CSS boxes before +specifying a box in $\mbox{\LaTeX}$ is straightforward. Here is +an example with an \lfbox: +

+
+ +
Here is a 
+\lfbox[
+  border-width=0.8pt,
+  border-left-color=red,
+  border-style=dotted,
+  padding={0.2ex,0.4ex}, %top&bottom, right&left
+]{fancy} box.
+
Here is a 
+\lfbox[
+  border-width=0.8pt,
+  border-left-color=red,
+  border-style=dotted,
+  padding={0.2ex,0.4ex}, %top&bottom, right&left
+]{fancy} box.
+

Here is another example using the longfbox environment: +

+
+ +
\begin{longfbox}[ 
+  margin-right=6em,
+  padding=1.5em,
+  background-color=floralwhite,
+  background-clip=padding-box,
+  border-width=2pt, 
+  border-radius=15pt,
+  border-top-left-radius=30pt,
+  border-left-width=8pt,
+  border-left-color=teal,
+  border-right-style=double,
+]
+A \textsf{longfbox} example. A longfbox can contain much
+longer content and will by default be as 
+wide as the current line width. 
+\end{longfbox}
+
\begin{longfbox}[ 
+  margin-right=6em,
+  padding=1.5em,
+  background-color=floralwhite,
+  background-clip=padding-box,
+  border-width=2pt, 
+  border-radius=15pt,
+  border-top-left-radius=30pt,
+  border-left-width=8pt,
+  border-left-color=teal,
+  border-right-style=double,
+]
+A \textsf{longfbox} example. A longfbox can contain much
+longer content and will by default be as 
+wide as the current line width. 
+\end{longfbox}

3.1. Borders

+

The border options determine how the frame of the +box is rendered. +

3.1.1. Border style

+

Each border can have an individual style: +

+
border-style=style sides
+​border-top-style=style (=solid)
+​border-right-style=style (=solid)
+​border-bottom-style=style (=solid)
+​border-left-style=style (=solid)
+
+

where all CSS styles are supported: +

+
style= none | hidden | solid | dotted | dashed | double
+​| inset | outset | groove | ridge
+
+

The style sides value can take 1 to 4 style arguments +just like in CSS: +

+
attr sides= attr
+​| {top-bottom attr , left-right attr}
+​| {top-attr, left-right attr, bottom-attr}
+​| {top-attr, right-attr, bottom-attr, left-attr}
+
+

Here are some examples of each CSS style: +

+
+ +
\lfbox[border-style=solid]{solid},
+\lfbox[border-style=dashed]{dashed},
+\lfbox[border-style=dotted]{dotted},
+\lfbox[border-style=double,border-width=2pt]{double},
+\lfbox[border-style={solid,none,dashed,none}]{various}.
+
\lfbox[border-style=solid]{solid},
+\lfbox[border-style=dashed]{dashed},
+\lfbox[border-style=dotted]{dotted},
+\lfbox[border-style=double,border-width=2pt]{double},
+\lfbox[border-style={solid,none,dashed,none}]{various}.
+

Note, for a dotted border, it is often nicer to use the dotted style +(Section 3.7) since it makes the dots a bit larger, e.g. +

+
+ +
Compare \lfbox[dotted]{dotted} versus \lfbox[border-style=dotted]{dotted}.
+
Compare \lfbox[dotted]{dotted} versus \lfbox[border-style=dotted]{dotted}.
+

The final CSS styles darken sides of the border to give a 3D effect: +

+
+ +
\lfbox[border-style=inset,border-color=red,border-width=3pt]{inset},
+\lfbox[border-style=outset,border-color=red,border-width=3pt]{outset},
+\lfbox[border-style=groove,border-color=teal,border-width=4pt]{\strut groove},
+\lfbox[border-style=ridge,border-color=teal,border-width=4pt]{\strut ridge}.
+
\lfbox[border-style=inset,border-color=red,border-width=3pt]{inset},
+\lfbox[border-style=outset,border-color=red,border-width=3pt]{outset},
+\lfbox[border-style=groove,border-color=teal,border-width=4pt]{\strut groove},
+\lfbox[border-style=ridge,border-color=teal,border-width=4pt]{\strut ridge}.
+

The darkness can be controlled using the border-dark-mix attribute (Section 3.1.3). +

+

Beyond CSS, there are also styles for the border top and +bottom when a box is broken over multiple pages +(see Section 3.5): +

+
border-break-style=style break-sides
+​border-break-top-style=style (=none)
+​border-break-bottom-style=style (=none)
+
+

where style break-sides takes one or two arguments: +

+
attr break-sides=attr
+​| {break-top-attr, break-bottom-attr}
+
+

See Figure 2 in Section 3.5 for +more information. +

3.1.2. Border width

+
border-width=width sides
+​border-top-width=dimen (=\fboxrule)
+​border-right-width=dimen (=\fboxrule)
+​border-bottom-width=dimen (=\fboxrule)
+​border-left-width=dimen (=\fboxrule)
+
+

This sets the width of each border. By default the \fboxrule width is used which +is normally 0.4pt. +

+
+ +
A \lfbox[border-width=3pt,border-left-color=red]{thick} border,
+and 
+\lfbox[border-top-width=0pt,border-bottom-width=1pt]{varied}.
+
A \lfbox[border-width=3pt,border-left-color=red]{thick} border,
+and 
+\lfbox[border-top-width=0pt,border-bottom-width=1pt]{varied}.
+
border-break-width=width break-sides
+​border-break-top-width=dimen (=0pt)
+​border-break-bottom-width=dimen (=0pt)
+
+

These specify border width around page breaks. +See Figure 2 in Section 3.5 for +more information. +

3.1.3. Border color

+
border-color=color sides
+​border-top-color=color (=black)
+​border-right-color=color (=black)
+​border-bottom-color=color (=black)
+​border-left-color=color (=black)
+
+

Sets the color of each border. +

+
color= color name
+​| xcolor spec
+​| \#RRGGBB
+​| {}
+
+

Colors can be specified by a name (e.g. red), and xcolor package color +specification (e.g. red!60), a direct HTML color (e.g. \#800080) or as +an empty value. The empty value is used for transparency on backgrounds. +

+
+ +
Strange 
+\lfbox[border-width=3pt,
+  border-top-color=red!50,
+  border-bottom-color=\#800080,
+]{colors}.
+
+\noindent\begin{longfbox}[border-style=none,
+  border-left-style=solid,
+  border-left-width=5pt,
+  border-color=blue, 
+  padding-left=1ex,
+]This is a definition
+\end{longfbox}
+
Strange 
+\lfbox[border-width=3pt,
+  border-top-color=red!50,
+  border-bottom-color=\#800080,
+]{colors}.
+
+\noindent\begin{longfbox}[border-style=none,
+  border-left-style=solid,
+  border-left-width=5pt,
+  border-color=blue, 
+  padding-left=1ex,
+]This is a definition
+\end{longfbox}
+

Besides the regular CSS attributes, colors for borders around a page break +are set as: +

+
border-break-color=color break-sides
+​border-break-top-color=color (=black)
+​border-break-bottom-color=color (=black)
+
+

See Section 3.5 for further information. +

+
border-dark-mix=color mix (=!70!black)
+
+

The border-dark-mix is used to make a color darker and is used for +the inset, outset, groove and ridge styles. This value is basically +appended to the main color of the border. The default takes 70% of the main +color and mixes in 30% black. +

3.1.4. Border corner radius

+
border-radius=radius corners
+​border-top-left-radius=radius (=0pt)
+​border-top-right-radius=radius (=0pt)
+​border-bottom-left-radius=radius (=0pt)
+​border-bottom-right-radius=radius (=0pt)
+
+

The above attributes specify the corner radius to enable rounded corners. +

+
radius=dimen | {x-radius,y-radius}
+
+

A radius value is either a dimension, or a separate x- and y-radius for +elliptical borders. Here are some examples: +

+
+ +
\lfbox[border-radius=0.5ex]{rounded},
+\lfbox[border-radius=100ex, background-color=floralwhite]{\strut elliptical},
+\lfbox[border-radius=0.5em,height=1em,width=1em,tight,
+       text-align=center,height-align=middle]{1}.
+
\lfbox[border-radius=0.5ex]{rounded},
+\lfbox[border-radius=100ex, background-color=floralwhite]{\strut elliptical},
+\lfbox[border-radius=0.5em,height=1em,width=1em,tight,
+       text-align=center,height-align=middle]{1}.
+

Here is an example of a longfbox with an elliptical corner: +

+
+ +
\begin{longfbox}[
+   border-radius=15pt,
+   border-width=2pt,
+   border-top-left-radius={50pt,25pt},
+   border-right-style=dashed,
+   border-left-style=double,
+   border-left-color=teal,
+   padding={1em,15pt},
+   width=0.6\linewidth,
+]
+\hobbit[7]
+\end{longfbox}
+
\begin{longfbox}[
+   border-radius=15pt,
+   border-width=2pt,
+   border-top-left-radius={50pt,25pt},
+   border-right-style=dashed,
+   border-left-style=double,
+   border-left-color=teal,
+   padding={1em,15pt},
+   width=0.6\linewidth,
+]
+\hobbit[7]
+\end{longfbox}

3.2. Alignment

+

Much care has been taken to ensure proper alignment and preservation +of the baseline. In our examples, we use the following definition where we enable +show-markers so we can see the baseline and dimensions of the longbox: +

+
+
\newcommand\alignbox[1]{%
+  \begin{longfbox}[width=2em,height=4.25em,show-markers,
+                   baseline-skip=false,#1] 
+    foo,\\ bar,\\ gnu.
+  \end{longfbox}%
+}
+
baseline= bottom | middle | top
+
+

The baseline attribute is not a CSS attribute, but we can use it to control +the baseline of the content of a box. For example: +

+
+ +
Aligning \alignbox{baseline=bottom}, 
+\alignbox{baseline=middle}, 
+\alignbox{baseline=top} done.
+
Aligning \alignbox{baseline=bottom}, 
+\alignbox{baseline=middle}, 
+\alignbox{baseline=top} done.
+

The vertical-align property aligns a box: +

+
vertical-align= baseline | bottom | middle | top
+​| text-bottom | text-top | super | sub
+
+

The default baseline attribute aligns the baseline +of the box with the baseline of the text. +The bottom attribute aligns the bottom of the box with +the bottom of the text, middle aligns the middle of the box +with the middle of the text, and top aligns the top of the box +with the top of the text. +

+

Here are the various attributes in action (compare +this to the examples for different baselines): +

+
+ +
Aligning \alignbox{vertical-align=bottom}, 
+\alignbox{vertical-align=middle}, 
+\alignbox{vertical-align=top} done. 
+
Aligning \alignbox{vertical-align=bottom}, 
+\alignbox{vertical-align=middle}, 
+\alignbox{vertical-align=top} done.
+

Finally, the super and sub attributes align the +baseline of the box with the baseline of super- and sub-scripts: +

+
+ +
$x^x_x$ \alignbox{vertical-align=super}, \alignbox{vertical-align=sub} $x^x_x$. 
+
$x^x_x$ \alignbox{vertical-align=super}, \alignbox{vertical-align=sub} $x^x_x$.
+

Unfortunately, in $\mbox{\LaTeX}$ we cannot determine +the height or depth of the current text line easily so these +values are fixed at 0.7\baselineskip and 0.3\baselineskip. +The text-bottom and text-top are equal to bottom and +top for that reason. +

+
raise=dimen
+
+

In CSS it is also possible to assign a length to the +vertical-align attribute. In $\mbox{\LaTeX}$ we use the raise +attribute instead which raises an aligned box by the assigned value. +

+
+ +
Aligning \alignbox{raise=1em}, \alignbox{raise=-1em}, 
+done.
+
Aligning \alignbox{raise=1em}, \alignbox{raise=-1em}, 
+done.
+
height-align= top | middle | bottom
+
+

This is another non-CSS attribute (but probably one of the most desired :-)): +it specifies the vertical alignment of the content inside the box. This +attribute only has an effect for boxes where the height is specified. +This attribute keeps the baseline unchanged and does not influence the +vertical alignment directly. +

+
+ +
Aligning \alignbox{height-align=bottom}, 
+\alignbox{height-align=middle},
+\alignbox{height-align=top},
+\alignbox{height-align=middle,baseline=top},
+done.
+
Aligning \alignbox{height-align=bottom}, 
+\alignbox{height-align=middle},
+\alignbox{height-align=top},
+\alignbox{height-align=middle,baseline=top},
+done.
+
text-align= default | left | center | right | justify
+
+

Specifies the alignment of the content horizontally. +The default is left for a horizontal \lfbox +and justify for a longfbox environment. +

+
+ +
Here is \lfbox[width=6em,text-align=center]{centered} text.
+
+And vertical 
+\alignbox{text-align=center,baseline=middle,width=4em} too.
+
Here is \lfbox[width=6em,text-align=center]{centered} text.
+
+And vertical 
+\alignbox{text-align=center,baseline=middle,width=4em} too.
+

Just like with \makebox we can use a narrow width to let +the text overlay to the left or right: +

+
+ +
\lfbox[width=1.7em,text-align=right]{bummer, too long}.
+
\lfbox[width=1.7em,text-align=right]{bummer, too long}.

3.3. Background

+
background-color=color (={})
+​background-clip=border-box | padding-box | content-box
+
+

Specifies the background color. The background-clip attribute +determines if the background color spans all the way out to the +border (default), just the padding box, or only the content box +itself. +

+
+ +
\newcommand\bgbox[2]{%
+  \lfbox[rounded,border-style=double,border-width=3pt,
+    border-color=teal,
+    background-color=#1,background-clip=#2]%
+}
+a\rlap{b}\bgbox{teal!30}{border-box}{foo},
+a\rlap{b}\bgbox{teal!30}{padding-box}{foo},
+a\rlap{b}\bgbox{teal!30}{content-box}{foo}.
+
\newcommand\bgbox[2]{%
+  \lfbox[rounded,border-style=double,border-width=3pt,
+    border-color=teal,
+    background-color=#1,background-clip=#2]%
+}
+a\rlap{b}\bgbox{teal!30}{border-box}{foo},
+a\rlap{b}\bgbox{teal!30}{padding-box}{foo},
+a\rlap{b}\bgbox{teal!30}{content-box}{foo}.
+
background-padding-color=color (=\option{background-color})
+​background-border-color=color (=\option{background-color})
+​background-content-color=color (=\option{background-color})
+
+

Going beyond CSS, we can also specify the colors for the +background at the border and padding separately. +

+
+ +
A \lfbox[rounded,
+  background-color=teal!30,
+  background-padding-color=floralwhite,
+  background-border-color=gray!50,
+  border-style=double,border-width=3pt
+]{too colorful} box.
+
A \lfbox[rounded,
+  background-color=teal!30,
+  background-padding-color=floralwhite,
+  background-border-color=gray!50,
+  border-style=double,border-width=3pt
+]{too colorful} box.

3.4. Padding and margins

+
padding=padding sides
+​padding-top=dimen (=\fboxsep)
+​padding-right=dimen (=\fboxsep)
+​padding-bottom=dimen (=\fboxsep)
+​padding-left=dimen (=\fboxsep)
+
+

The padding is the space between the content and the border +of a box. By default the padding is equal to the \fboxsep value. +

+
margin=margin sides
+​margin-top=dimen (=0pt)
+​margin-right=dimen (=0pt)
+​margin-bottom=dimen (=0pt)
+​margin-left=dimen (=0pt)
+
+

The margin is the transparent area outside the borders. In contrast +to the CSS attribute, the margins do not overlap. Please use +the standard \addvspace command for adding overlapping top- and +bottom-margins. +

+
+ +

+\begin{longfbox}[width=6.8em]
+Here is a longer paragraph with a 
+\lfbox[margin={1em,0.5em,1em},padding=1ex,show-markers]{box} 
+inside with margins.
+\end{longfbox}
+
\begin{longfbox}[width=6.8em]
+Here is a longer paragraph with a 
+\lfbox[margin={1em,0.5em,1em},padding=1ex,show-markers]{box} 
+inside with margins.
+\end{longfbox}
+
padding-break-top=dimen (=0.5em)
+​padding-break-bottom=dimen (=0.5em)
+​margin-break-top=dimen (=0pt)
+​margin-break-bottom=dimen (=0pt)
+
+

These attributes determine the margin and padding around +a page break. By default, there is some padding set around +a break such that the vertical borders of a box `stick out' a +bit giving the reader a hint that the box continues at the +next page (see Figure 2) +

3.5. Breaking content

+
+
\newcommand\showindexbreaks{%
+  \small\sffamily\roundcap
+  \ontoggle{/longbox/@part-needtop}{% 
+    \put(10,0){\circle{8}}%
+    \put(54,11){%
+      \udvector{10}%
+      \put(0,-2){ padding-break-bottom}
+    }
+    \put(64,-5.5){%
+      \udvector{5.5}%
+      \put(0,-2){ margin-break-bottom}
+    }
+    \put(64,-16){%
+      \udvector{5.25}%
+      \put(0,-2){ margin-break-top}
+    }
+    \put(54,-32){%
+      \udvector{10}%
+      \put(0,-2){ padding-break-top}    
+    }
+    %
+    \put(-10,20){% 
+      \line(1,-1){17}%
+      \put(0,-2){\llap{border-break-bottom-style$\,$}}
+      \put(0,-12){\llap{width,color$\,$}}
+    }
+    %
+    \ontoggle{/longbox/@part-needbottom}{%
+      \put(54,11){% 
+        \udvector{10}\put(0,-2){ padding-break-bottom}%
+      }
+    } 
+  }
+  \ontoggle{/longbox/@part-needbottom}{%
+    \put(-10,80){\line(1,-1){16.5}%
+      \put(0,-1){\llap{border-break-top-style$\,$}}
+      \put(0,-11){\llap{width,color$\,$}}
+    }  
+    \put(-10,82){\line(1,2.65){18.5}}    
+    \put(10,61){\circle{8}}
+    \put(10,135){\circle{8}}
+    \put(54,50){%
+      \udvector{10}\put(0,-2){ padding-break-top}%
+    }
+  }
+}
+
+\begin{longfbox}[breakable,breakat={75pt},
+  width=210pt,
+  border-width=1pt,
+  margin-break-top=10pt,
+  margin-break-bottom=10pt,
+  margin-left=0.3\linewidth,
+  padding-break=20pt,
+  border-break-style=dashed,
+  border-break-color=teal,
+  picture-insert-after=\showindexbreaks,
+  background-color=floralwhite,
+  background-clip=content-box,
+]
+\hobbit[4]
+\end{longfbox}
+
+ +
Figure 2. A box that has been broken in three parts. The border style and the padding and margin of each break can be set separately. Use the breakable option to make boxes breakable over page boundaries. In the above example we also used the breakat={75pt} option to break at specific heights, and the background-clip=content-box to limit the background color to the content only.
+
breakable=bool (=false)
+
+

When the option breakable is present, a longfbox environment +can be broken at page boundaries. All the borders, margins, padding, +etc. are preserved over the page break. Moreover, the border, padding, +and margin for each break at the top and bottom can be set +separately, as shown in in Figure 2. +

+
extra-split=dimen (=1.5\baselineskip)
+
+

(Advanced) This option determines the minimal height of a box that is broken. +If the height would be less the box is not broken and moved to the next page. +This prevents for example to have just the top border and padding on one page +followed by content on the next page. +

+
breakat={dimen1,,dimenn}
+
+

(Advanced) This option lets you break a box manually at specific heights. +The breakable option must be set for this to work. Usually a box is broken +to fit the space available on the page, but when breakat is given, the box +breaks at dimen1. After the break, the first dimension is removed from +the list and the box is broken again at dimen2 until only one element +(dimenn) is left. After that the box is repeatedly broken at dimenn +until all content is processed. For example, in Figure 2 we used +breakat={75pt} to break the box at three 75pt heights. Note that when a box +breaks, it chooses the largest height that is less than 75pt where the content +can be broken nicely, i.e. a box never breaks in the middle of a line for example. +

+

The breakat can also be used to break a box in a multicols environment. +

3.6. Height and width

+
height=dimen
+​width=dimen
+
+

Specifies the height or width of the inner content box, see +Figure 1. By default, the width of horizontal \lfbox +is the natural width of its content. In contrast, the default width +of a vertical longfbox environment is the current \linewidth. +The default height is always the natural height of the content. +When the height is fixed, you can use height-align to align +the content in the available area. +

+
outer-height=dimen
+​outer-width=dimen
+
+

For convenience, there are also these non-CSS attributes that +let you specify the width and height of the entire box including +the padding, border, and margins. Internally translated to +the height or width before processing the box. +

3.7. Predefined styles

+
tight={padding=0pt,margin=0pt,padding-break=0pt}
+​rounded={border-radius=1ex}
+​dotted={border-width=0.8pt,border-style=dotted}
+
+

Some predefined convenient styles. tight puts the box +tightly around the content. The rounded style uses a border +radius that looks nice relative to the font size, and +dotted uses a slightly larger border width which looks better +with dots. +

+
+ +
A \lfbox[tight]{tight}, \lfbox[dotted]{dotted},
+and \lfbox[rounded]{rounded} box.
+
A \lfbox[tight]{tight}, \lfbox[dotted]{dotted},
+and \lfbox[rounded]{rounded} box.

4. Advanced topics

4.1. Hooks and rendering

+
render=default | plain | picture
+
+

There are two ways to render a box border: using just plain +$\mbox{\LaTeX}$ and the $\mbox{\LaTeX}$ picture environment. +The plain renderer just uses \hrule etc. and can only +render simple boxes with solid or dashed styles without +rounded corners. The default will pick the plain renderer +if a box is simple, and use the picture renderer otherwise. +This is mostly to make the rendering more efficient but there +should be no other difference. +

+
insert-before=value
+​insert-after=value
+
+

These are hooks to insert content just before or after +the content box. +

+
+ +
A \lfbox[insert-before={``\bgroup\itshape}, 
+         insert-after={\/\egroup''}]{quoted}
+box.
+
A \lfbox[insert-before={``\bgroup\itshape}, 
+         insert-after={\/\egroup''}]{quoted}
+box.
+
render-insert-before=value
+​render-insert-after=value
+
+

These are hooks to insert content just before or after +the border-box is rendered. +

+
+ +
\newcommand\makecircle{%
+  \setlength\unitlength{1pt}%
+  \begin{picture}(0,0)% make it occupy no space
+    \color{red}%
+    \put(0,0){\circle*{5}}%
+  \end{picture}%
+}
+\lfbox[render-insert-before=\makecircle]{funny}.
+
\newcommand\makecircle{%
+  \setlength\unitlength{1pt}%
+  \begin{picture}(0,0)% make it occupy no space
+    \color{red}%
+    \put(0,0){\circle*{5}}%
+  \end{picture}%
+}
+\lfbox[render-insert-before=\makecircle]{funny}.
+
picture-insert-before=value
+​picture-insert-after=value
+
+

These insert content just before or after rendering the frame +in a picture environment. In both case, the origin is +at the bottom-right corner. Here is an example where we cross-out +a box: +

+
+ +
\newcommand\crossout{%
+  \color{red}\linethickness{1pt}\roundcap%
+  \moveto(0,0)
+  \lineto(\optionunit{/fbox/@border-box-width},
+          \optionunit{/fbox/@border-box-height})
+  \strokepath
+}
+This is 
+\lfbox[rounded,picture-insert-after=\crossout]{crossed out}.
+
\newcommand\crossout{%
+  \color{red}\linethickness{1pt}\roundcap%
+  \moveto(0,0)
+  \lineto(\optionunit{/fbox/@border-box-width},
+          \optionunit{/fbox/@border-box-height})
+  \strokepath
+}
+This is 
+\lfbox[rounded,picture-insert-after=\crossout]{crossed out}.
+
plain-side-insert-before=value
+​plain-side-insert-after=value
+​picture-side-insert-before=value
+​picture-side-insert-after=value
+
+

These attributes insert content just before rendering +a border side. +

4.2. Internal attributes

+
baseline-skip=bool (=true)
+
+

Usually, the library adds a small vertical skip in front of a +vertical longfbox such that it content aligns to a \baselineskip. +Similarly, it adds such skip just after the box. This generally makes text +align better, especially on a double column layout. Setting it to false +disables such vertical spacing. +

+ + + +
show-markers=bool
+​marker-color=color (=gray)
+​marker-width=dimen (=0.1pt)
+
+

If show-markers is true it will show the padding, baseline, +margin and border markers using marker-color and marker-width. +

+
eject=value (={\protect\vfill\protect\eject})
+
+

After breaking a box, this command is issued which normally +ends the current page. The breakat command sets this to +empty so no page break occurs in that case. +

+
debug=bool (=false)
+​verbose=bool (=false)
+
+

Enable debug and verbose log messages. +

4.3. Customizing border dashes and dots

+

The following attributes are used to render +dashes and dots for the dashed and dotted border styles. +

+
border-dash=dash sides
+​border-top-dash=dimen (=0.7ex)
+​border-right-dash=dimen (=0.7ex)
+​border-bottom-dash=dimen (=0.7ex)
+​border-left-dash=dimen (=0.7ex)
+​border-break-top-dash=dimen (=\option{border-top-dash})
+​border-break-bottom-dash=dimen (=\option{border-bottom-dash})
+
+
border-dashskip=dashskip sides
+​border-top-dashskip=dimen (=0.7\option{border-top-dash})
+​border-right-dashskip=dimen (=0.7\option{border-right-dash})
+​border-bottom-dashskip=dimen (=0.7\option{border-bottom-dash})
+​border-left-dashskip=dimen (=0.7\option{border-left-dash})
+​border-break-top-dashskip=dimen (=\option{border-top-dashskip})
+​border-break-bottom-dashskip=dimen (=\option{border-bottom-dashskip})
+
+
border-dotskip=dotskip sides
+​border-top-dotskip=dimen (=0.7\option{border-top-width})
+​border-right-dotskip=dimen (=0.7\option{border-right-width})
+​border-bottom-dotskip=dimen (=0.7\option{border-bottom-width})
+​border-left-dotskip=dimen (=0.7\option{border-left-width})
+​border-break-top-dotskip=dimen (=\option{border-top-dotskip})
+​border-break-bottom-dotskip=dimen (=\option{border-bottom-dotskip})
+
+
Created with Madoko.net.
+ + + diff --git a/Master/texmf-dist/doc/latex/longfbox/longfbox.pdf b/Master/texmf-dist/doc/latex/longfbox/longfbox.pdf new file mode 100644 index 00000000000..14706c4a1d9 Binary files /dev/null and b/Master/texmf-dist/doc/latex/longfbox/longfbox.pdf differ diff --git a/Master/texmf-dist/tex/latex/longfbox/longbox.sty b/Master/texmf-dist/tex/latex/longfbox/longbox.sty new file mode 100644 index 00000000000..9d373895f2b --- /dev/null +++ b/Master/texmf-dist/tex/latex/longfbox/longbox.sty @@ -0,0 +1,853 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages] +\RequirePackage{options} + +\@ifclassloaded{beamer}{% + \newcommand\lb@savefootnotes{}% + \newcommand\lb@restorefootnotes{}% +}% +{\RequirePackage{footnote}% + \newcommand\lb@savefootnotes{\savenotes}% + \newcommand\lb@restorefootnotes{\spewnotes}% +} + + +% -------------------------------------------------------- +% Debugging +% -------------------------------------------------------- + +\newcommand*\lb@debug[1]{% + \ontoggle{lb@debug}{\typeout{longbox debug: #1}}% +} +\newcommand*\lb@typeout[1]{% + \ontoggle{lb@verbose}{\typeout{longbox: #1}}% +} +\newcommand*\lb@warncannotsplit{% + \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}% +} +\newcommand*\lb@warnbadsplit[1]{% + \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}% +} + + +% -------------------------------------------------------- +% Utilities for LaTeX internals +% -------------------------------------------------------- + +% Suppress the indentation on the following paragraph +\providecommand\nofirstindent{\@afterindentfalse\@afterheading} + +% Suppress the paragraph skip on the following paragraph +\providecommand\nofirstparskip{\addvskip{-\parskip}} + +% In contrast to addvspace, addvskip is not suppressed in a minipage +\providecommand\addvskip[1]{% + \ifvmode + \ifdim\lastskip=\z@ + \vskip #1\relax + \else + \@tempskipb#1\relax\@xaddvskip + \fi + \else\@noitemerr\fi +} + + +% Skip to 0.3\baselineskip multiple taking prevdepth into account. +\newskip\lb@prevdepth +\newcommand\lb@skiptobaseline{% + \global\lb@prevdepth=-\@m\p@\relax + \ifvmode + \ifdim\lastskip=\z@\relax + \ifdim\prevdepth=-\@m\p@\else + \dimen@\prevdepth + % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|. + \@tempcnta\prevdepth + \@tempskipa=0.3\baselineskip\relax + \@tempcntb=\@tempskipa\relax + \divide \@tempcnta by \@tempcntb + \dimen@\prevdepth + \advance\dimen@ -\@tempcnta\@tempskipa + % Skip back by that amount, and then skip by 0.3|\baselineskip|. + \vskip -\dimen@ + \vskip \@tempskipa\relax + \global\lb@prevdepth=\@tempskipa\relax + \fi + \fi + \fi +} + +% unvbox a box, and return a vbox with a given background color +% \unvcolorbox{}{} +\newcommand\unvcolorbox[2]{% + \ifoptionblank{#1}{\vbox{\unvbox#2}}{% + \lb@debug{vcolorbox: #1}% + \vbox{\offinterlineskip + \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}% + \unvbox#2% + }% + }% +} + +% create a vbox with a given background color +\newcommand\vcolorbox[2]{% + \eifblank{#1}{\vbox{#2}}{% + \setbox\z@=\vbox{#2}\relax + \unvcolorbox{#1}{\z@}% + }% +}% + +% -------------------------------------------------------- +% The following macros come from mdframed +% -------------------------------------------------------- + +% Determine the amount of free space left on the current page +\newlength\lb@freevspace +\newcommand*\lb@setfreevspace@page{% + \lb@debug{ determine free space}% + \bgroup\@nobreakfalse\addpenalty\z@\egroup% + \penalty\@M\relax\vskip 2\baselineskip\relax% + \penalty9999\relax\vskip -2\baselineskip\relax% + \penalty9999% + \ifdim\pagegoal=\maxdimen\relax% + \lb@freevspace=\vsize% + \else + \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax% + \fi + \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}% +} + +\newcommand*\lb@shiftdim[2]{% + %\letoption{#1}\lb@list + \expandafter\lb@setheadtail@#1,\relax + \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}% + #2\option{/longbox/@breakat-previous}% + \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail +} +\def\lb@comma{,}% +\def\lb@setheadtail@#1,#2\relax{% + \def\lb@head{#1}% + \def\lb@tail{#2}% adds commas! +} + +\newcommand*\lb@setfreevspace{% + \eifblank{\lb@breakat}{\lb@setfreevspace@page}{% + \def\lb@eject{\par}%no eject + \lb@extrasplit=\z@\relax% + \lb@shiftdim{\lb@breakat}\lb@freevspace + \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi + }% +} + + +% Suppress overfull-underfull vbox messages +\newcommand*\lb@ignorevbadness{% + \edef\lb@currentvbadness{\the\vbadness}% + \edef\lb@currentvfuzz{\the\vfuzz}% + \vbadness=\@M\relax% + \vfuzz=\maxdimen\relax% + \afterassignment\lb@restorevbadness +} +\newcommand*\lb@restorevbadness{% + \vbadness=\lb@currentvbadness\relax + \vfuzz=\lb@currentvfuzz\relax +} + + +% -------------------------------------------------------- +% The 'long vbox' (lvbox) environment collects long material +% into a long \vbox, instead of a \hbox like a lrbox in latex. +% The collected box can contain any box, minipage, lrbox, fbox etc, +% but not outer-par material like a figure. Footnotes can be +% dealt with useing lb@savefootnotes. +% +% The material is typeset in a \vbox according to a given width. +% inside the environment, the boolean 'inlvbox' is true. +% +% \begin{lvbox}{}{} +% -------------------------------------------------------- + +\newif\ifinlvbox +\newcommand\lvbox[4]{% + \setbox#1\vbox\bgroup + \begingroup + \inlvboxtrue + % reset defaults + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % set margin and linewidth + \leftmargin=#2\relax\rightmargin=#4\relax + \@totalleftmargin=\leftmargin% + %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax + \linewidth=#3\relax + % set primitive tex margins + \leftskip=\@totalleftmargin% + \rightskip=\rightmargin% + \@rightskip=\rightmargin% + \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax + \columnwidth\hsize + \textwidth\hsize + \nofirstindent + %\nofirstparskip +} +\def\endlvbox{\endgroup\egroup} + + + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + + +\newsavebox\lb@headbox +\newsavebox\lb@savebox +\newsavebox\lb@mainbox + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@setbaseline[1]{% + %\typeout{ set baseline, \the\dp#1,\the\ht#1}% + \ifcase\lb@baseline% + \relax%bottom + \or%middle + \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}% + \or%top + \setbox#1=\vtop{\unvbox#1}% + \fi + %\typeout{ .new dim: \the\dp#1, \the\ht#1}% +} + + +\@ifundefined{define@key}{}% + {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}% + +\newcommand*\lb@render@breakbox{% + %\typeout{render breakbox entry (in output routine), height=\the\bb@height}% + \bb@restorekeys{longbox}% + \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax + \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax + \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi + \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi + %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}% + \options{% + /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom, + /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width, + /longbox/@part-depth=0pt, + /longbox/@part-needtop=\ifbb@isfirst true\else false\fi, + /longbox/@part-needbottom=\ifbb@islast true\else false\fi, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-depth=\option{/longbox/@part-depth}, + }% + %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}% + \vbox{% + \kern -\lb@skipbreaktop% todo: move to breakbox? + \option{/longbox/render}% + \kern -\lb@skipbreakbottom + }% +} + +\newcommand*\lb@render@vbox[1]{% + \lb@debug{render vbox entry}% + \lb@restoreoptions + \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax + \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax + %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}% + % add top skip while maintaining the baseline. + \ifdim\lb@skiptop=\z@\relax\else + \setbox\z@=\vtop{\unvcopy#1}% + \dimen@=\ht\z@ + \setbox#1=\vbox{\offinterlineskip + \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@ + \unvbox#1% + }% + \fi + % add bottom skip while maintaining the baseline. + \ifdim\lb@skipbottom=\z@\relax\else + \dimen@=\dp#1% + \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}% + \fi + \lb@setbaseline{#1}% + \options{% + /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax, + /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax, + /longbox/@part-depth=\dp#1, + /longbox/@content-box-width=\option{/longbox/width}, + /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom, + /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom, + }% + %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}% + % lower the box depending on vertical alignment + \ifcase\option{/longbox/vertical-align/@ord}\relax + \@tempdima\z@ + \or + %bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%middle + \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax + \or%top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%text-bottom + \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax + \or%text-top + \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax + \or%super + \@tempdima=-0.9ex% + \or%sub + \@tempdima=0.7ex% + \else + \@tempdima\z@ + \fi + \advance\@tempdima by -\option{/longbox/raise}% + \option@invoke{/longbox/@lower}{\@tempdima}% + \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip + \hbox to \z@{% + \vbox to \z@{% + \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}% + \vss}% + \hss + }% + \hbox{% + \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi + \box#1% + \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi + %$\box#1% + }% + }}% +} + +\newcommand*\lb@single@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} +\newcommand*\lb@first@[1]{% + \begingroup + \toggletrue{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@middle@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \togglefalse{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \lb@eject + \endgroup +} +\newcommand*\lb@last@[1]{% + \begingroup + \togglefalse{/longbox/@part-needtop}% + \toggletrue{/longbox/@part-needbottom}% + \lb@render@vbox{#1}% + \endgroup +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand*\lb@env@start{% + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore +} + +\newcount\lb@usevbox +\newlength\lb@width +\newlength\lb@height +\newlength\lb@skiptop +\newlength\lb@skipright +\newlength\lb@skipbottom +\newlength\lb@skipleft +\newlength\lb@skipbreaktop +\newlength\lb@skipbreakbottom +\newlength\lb@outerwidth +\newlength\lb@extrasplit +\newcount\lb@textalign +\newcount\lb@baseline +\newtoggle{lb@baselineskip}% +\newtoggle{lb@breakable}% +\newtoggle{lb@debug}% +\newtoggle{lb@verbose}% +\def\lb@breakat{}% +\def\lb@halign{}% +\def\lb@eject{}% +\def\lb@insertafter{} +\def\lb@insertbefore{} + +\newcommand*\lb@peekoptions[1]{% + % process options inside a group and just set necessary parameters + % this way, nested boxes don't influence each other's parameters + \begingroup + \options{#1}% + \option{/longbox/adjust-options}% + \protected@edef\lb@temp{\endgroup + \lb@width=\the\dimexpr\option{/longbox/width}\relax + \lb@height=\the\dimexpr\option{/longbox/height}\relax + \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax + \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax + \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax + \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax + \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax + \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax + \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax + \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax + \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax + \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax + \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax + \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}% + \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}% + \def\noexpand\lb@breakat{\option{/longbox/breakat}}% + \def\noexpand\lb@halign{\option{/longbox/height-align}}% + \def\noexpand\lb@eject{\option{/longbox/eject}}% + \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}% + \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}% + \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}% + \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}% + }% + \lb@temp +} + +\newenvironment{longbox@env}[2]{% + % save options + \lb@peekoptions{#1,#2}% + % + \ifnum\lb@usevbox=0\relax + \lb@debug{start breakbox}% + \let\bb@render\lb@render@breakbox + \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}% + \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}% + \begin{breakbox}% + \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi% + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \begin{bb@margins}{\lb@skipleft}{\dimen@}% + \else + \lb@debug{start vbox}% + \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}% + \lb@savefootnotes + \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax + \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}% + \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}% + \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}% + \prevdepth=\lb@prevdepth + \fi + \ifcase\lb@textalign\relax + %default + \or\raggedright + \or\centering + \or\raggedleft + \else\relax% justify=default + \fi + \lb@insertbefore + \begingroup +}{% + \par\unskip + \endgroup + \lb@insertafter + %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi% + \ifnum\lb@usevbox=0\relax + \end{bb@margins}% + \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi% + \iftoggle{lb@baselineskip}{}{\vskip 1sp}% + \end{breakbox}% + \lb@debug{end breakbox}% + \else + \ontoggle{lb@baselineskip}{\lb@skiptobaseline}% + \endlvbox% + \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@processbox + %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}% + \lb@restorefootnotes + \lb@debug{end vbox}% + \fi +} + +\newcommand\longbox@cmd[3]{% + \begingroup + %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first + %\option{/longbox/scoped/@adjust-options}% + \lb@peekoptions{#1,#2}% + \leavevmode + %\setbox\lb@mainbox=\hbox{% + % \begingroup + % #3% + % \endgroup + %}% + \setbox\lb@mainbox=\hbox{% + \begingroup + \ifcase\lb@textalign\relax + %default=left + \or%left + \or\hss%center + \or\hss%right + \else%justify + \fi + \lb@insertbefore + #3% + \lb@insertafter + \ifnum\lb@textalign<3\relax\hss\fi% default,left,center + \endgroup + }% + \options{#1,#2}% + \ifdim\option{/longbox/width}=-1sp\relax + \options{/longbox/width=\wd\lb@mainbox}%set to natural width + \fi + \option{/longbox/adjust-options}% + % make it a vbox + \setbox\lb@mainbox=\vbox{\offinterlineskip% + \hbox to \option{/longbox/width}{% + \unhbox\lb@mainbox + }% + }% + \def\lb@restoreoptions{}% + \letoption{/longbox/height-align}\lb@halign + \lb@height=\option{/longbox/height}\relax + \lb@baseline=\option{/longbox/baseline/@ord}\relax + \lb@processbox + \endgroup +} + +\newcommand\lb@processbox{% + \ifdim\lb@height<0pt\relax + \lb@setbaseline{\lb@mainbox}% + \else + \lb@restrictheight + \fi + \lb@typesetbox +} + +\newcommand\lb@typesetbox{% + \ifinlvbox + \iftoggle{lb@breakable}{% + %\lb@debug{disable breakable due to nesting of long-boxes}% + \togglefalse{lb@breakable}% + }{}% + \fi + \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newcommand\lb@restrictheight{% + \lb@typeout{restrict height to \the\lb@height}% + \lb@splitheight=\lb@height% + %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + %split failed.. do nothing + \lb@debug{could not restrict height}% + \else + % store splitted off content in the mainbox (and discard the rest) + \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}% + \lb@debug{restricted height to \the\ht\lb@mainbox}% + \fi + % set baseline + \lb@setbaseline{\lb@mainbox}% + % height align + %\letoption{/longbox/height-align}\lb@halign + \eifstrequal{\lb@halign}{bottom}% + {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}% + {\eifstrequal{\lb@halign}{middle}% + {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\hbox{% + \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax% + \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}% + {% default is top + \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax + \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}% + }% + }% +} + +% -------------------------------------------------------- +% +% -------------------------------------------------------- + +\newlength\lb@neededvspace +\newcommand\lb@typeset[1][0pt]{% + \iftoggle{lb@breakable}{% + \lb@setfreevspace + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}% + \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@single@{\lb@mainbox}% + \else + \lb@typeout{longbox needs splitting}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion) + \lb@debug{failed to split the box, inserting a page break}% + \hrule \@height\z@ \@width\hsize + \lb@eject% + \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion + \else + % on a fresh page we should not fail anymore.. just output as is.. + % lb@warncannotsplit + \lb@single@{\lb@mainbox}% + \fi + \else + % first part success + \lb@typeout{first part splitted}% + \lb@first@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest + \fi + \fi + }{%\else + \lb@debug{unbreakable box}% + \lb@single@{\lb@mainbox}% always directly output an unbreakable box + }% +} + +\newcommand\lb@typesetrest{% + \lb@setfreevspace% + \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}% + \ifdim\lb@neededvspace<\lb@freevspace\relax + \lb@typeout{output last part of box}% + \lb@last@{\lb@mainbox}% + \else + \lb@debug{split box further}% + \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}% + \lb@splitbox + \ifdim\ht\lb@headbox=0pt\relax + % failed to split + \lb@typeout{failed to split box!}% + \lb@last@{\lb@mainbox}% + \else + % middle part success + \lb@typeout{output middle part of box}% + \lb@middle@{\lb@headbox}% + \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration... + \fi + \fi +} + +% -------------------------------------------------------- +% Split a long vbox over multiple pages. +% This code is based on similar code in the mdframed package +% -------------------------------------------------------- + +\newlength\lb@splitheight +\newlength\lb@insurance % tiny extra space to ensure our box will really fit +\setlength\lb@insurance{1pt} + +% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox +\newcommand\lb@splitbox{% + \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax + % the main box is larger than our target split height.. + \ifdim\lb@extrasplit>\lb@splitheight\relax + % not enough space to bother + \lb@typeout{not enough space on page for a split}% + \setbox\lb@headbox=\vbox{}% empty head + \else + % try a split; lower the split height a bit so we are sure to fit + \advance\lb@splitheight -\lb@insurance\relax + \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}% + \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original + \lb@trysplit{\lb@splitheight}% + \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax + % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up + \dimen@=\lb@splitheight\relax + \@tempcnta=\z@\relax + \loop + \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax + \ifnum\@tempcnta<50% + \advance\dimen@ by -\p@\relax% try a slightly smaller height.. + \else + \advance\dimen@ by -5\p@\relax% try larger increase after 50pt.. + \fi + \advance\@tempcnta by \@ne\relax + \lb@ignorevbadness + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \lb@trysplit{\dimen@}% + \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small + \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts + \repeat% + \ifnum\@tempcnta<100\relax + \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax + \ifdim\dimen@>\option{/longbox/split-badness}\relax + \lb@warnbadsplit{\dimen@}% + \fi + \fi + \fi + \fi + \else + % mainbox fits in our target lb@splitheight + \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}% + \setbox\lb@mainbox=\vbox{}% + \fi +} + +\newcommand\lb@splitstop{% + \lb@typeout{cannot find a good split}% + \let\iterate\relax + \lb@warncannotsplit + \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore + \setbox\lb@headbox=\vbox{}% empty head + \@tempcnta=\@M\relax +} + +\newcommand\lb@trysplit[1]{% try to split at given height + \lb@typeout{try to split at: \the\dimexpr #1\relax}% + \lb@ignorevbadness + \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax% + \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}% + \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}% +} + +% -------------------------------------------------------- +% The longbox environment uses options to set its options +% -------------------------------------------------------- + + +% keys and styles that can be set once globally +\options{% + /longbox/.new family, +}% + +\options{/longbox,% + % computed + @part-needtop/.new toggle, + @part-needbottom/.new toggle, + @part-height/.new length, + @part-width/.new length, + @part-depth/.new length, + @content-box-height/.new length, + @content-box-width/.new length, + @content-box-depth/.new length, + @breakat-previous/.new length, + @lower/.new length, + % + debug/.new toggle, + verbose/.new toggle, + render/.new value =\lb@render@fbox, + adjust-options/.new value = {\longbox@adjustoptions}, + eject/.new value = {\protect\vfill\protect\eject}, + use-vbox/.new toggle = true, + split-minimum/.new length = {1.5\baselineskip}, + split-badness/.new length = \baselineskip, + % + height-align/.new choice= {top,middle,bottom}, + baseline/.new choice = {bottom,middle,top}, + text-align/.new choice = {default,left,center,right,justify}, + vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub}, + raise/.new length = {0pt}, + baseline-skip/.new toggle =true, + % + height/.new length = -1sp, + width/.new length = -1sp, + outer-height/.new length= -1sp, + outer-width/.new length = -1sp, + insert-before/.new value= {}, + insert-after/.new value = {}, + breakat/.new value = {}, + breakable/.new toggle = false, + skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1}, + skip-top/.new length, + skip-right/.new length, + skip-bottom/.new length, + skip-left/.new length, + skip-break-bottom/.new length, + skip-break-top/.new length, +} + +\newcommand\longbox@adjustoptions{% + %\typeout{ standard longbox adjustoptions}% + \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}% + \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}% + % adjust height + \ifdim\option{/longbox/height}=-1sp\relax + \ifdim\option{/longbox/outer-height}=-1sp\else + \option@invoke{/longbox/height}% + {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}% + \fi + \fi + % set width + \ifdim\option{/longbox/width}=-1sp\relax + \ifdim\option{/longbox/outer-width}=-1sp\relax + \option@invoke{/longbox/outer-width}{\linewidth}% + \fi + \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax + \ifdim\dimen@<\z@\relax\dimen@=\z@\fi + \option@invoke{/longbox/width}{\dimen@}% + \fi + % use a breakbox whenever we are in external vertical mode and not width or height restricted. + \iftoggle{/longbox/use-vbox}{}{% + \ifinner\toggletrue{/longbox/use-vbox}\else + \ifhmode\toggletrue{/longbox/use-vbox}\else + \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else + \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}% + \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}% + \fi\fi\fi + }% +} + +\newenvironment{longbox}[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \begin{longbox@env}{/longbox}{#1}% +}{\end{longbox@env}} + +\newcommand\lbox[1][]{% + %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}% + \longbox@cmd{/longbox}{#1}% +} + +\newcommand*\lb@render@fbox{% + %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}% + \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax% + \@ovdy=\dimexpr\option{/longbox/@part-height}\relax% + \iftoggle{/longbox/@part-needbottom}% + {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax + \advance\bb@height by \@tempdima + \advance\@ovdy by \@tempdima}% + \iftoggle{/longbox/@part-needtop}% + {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}% + {\@tempdimb=\dimexpr\bb@stickout\relax + \advance\bb@height by \@tempdimb + \advance\@ovdy by \@tempdimb}% + % + \hbox{\lower \@tempdima\vbox{% + \vskip -\@tempdimb + \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}% + \hbox{% + \vrule width \fboxrule height \@ovdy% + \ifx\bb@bgcolor\@empty + \vrule width \@ovdx height \z@\relax + \else + {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}% + \fi + \vrule width \fboxrule height \@ovdy% + }% + \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}% + }}% +} \ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/longfbox/longfbox.sty b/Master/texmf-dist/tex/latex/longfbox/longfbox.sty new file mode 100644 index 00000000000..9627964199d --- /dev/null +++ b/Master/texmf-dist/tex/latex/longfbox/longfbox.sty @@ -0,0 +1,1344 @@ +%--------------------------------------------------------------------------- +% Copyright 2015 Daan Leijen, Microsoft Corporation. +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +%--------------------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages] + +\RequirePackage{options} +\RequirePackage{longbox} +\RequirePackage{pict2e} +\RequirePackage{ellipse} + +% -------------------------------------------------------- +% Dimension calulations +% -------------------------------------------------------- + +% dimmin/dimmax return minimum or maximum dimension +\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi} +\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi} + +\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}} +\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}} + + +% -------------------------------------------------------- +% Add a new 'sides' option type +% -------------------------------------------------------- + +\options{ + /handlers/new sides/.new handler = []{ + \ifblank{#2}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}% + {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}% + \optionsalso{ + #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{% + \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}% + {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}% + {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}% + {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}% + }% + }% + }, + #1/.type = sides, + }% + },% +} + +\newcommand*\optionlengthlimit[3]{% len, min, max + \letoption{#1}\opt@temp + \ifdim\opt@temp<\dimexpr#2\relax + \option@invoke{#1}{#2}% + \else\ifdim\opt@temp>\dimexpr#3\relax + \option@invoke{#1}{#3}% + \fi\fi +} + +\newcommand*\optionradiuslimit[4]{% r1, r2, min, max + \letoption{#1}\opt@tempa + \letoption{#2}\opt@tempb + \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi + \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi + \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else + \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax + \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/% + (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}% + %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}% + \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}% + \option@einvoke{#1}{\opt@temp}% + \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}% + %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}% + \fi + \fi +} + + +% \begin{macro}{\trig@atantan} +% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\ +% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$}, +% where $a$ and $b$ are dimensions. +% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$. +% \begin{macrocode} +\newcommand*\trig@atantan[4]{% + %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}% + \@tempdima\dimexpr#1\relax + \@tempdimb\dimexpr#2\relax +% \end{macrocode} +% If $a = b$, we have a circle and the result is $\alpha$. +% \begin{macrocode} + \ifdim\@tempdima=\@tempdimb + #4\dimexpr#3\relax + \else\ifdim\@tempdima=\z@ + #4\dimexpr#3\relax + \else\ifdim\@tempdimb=\z@ + #4\dimexpr#3\relax + \else + \edef\trig@temp{\strip@pt\dimexpr#3\relax}% + \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}% + \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax + \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax + \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@ + \ifdim\dimen@<\z@ + \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi + \fi + \@tempdima\dimexpr#3 - \dimen@\relax + \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi + \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi + %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }% + #4\dimen@ + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} + +% rough approximation of the perimeter; +% if |radius-x == radius-y| = 0 (a circle), the approximation is precise. +% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on. +\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result' + \@tempdima\dimexpr#3\relax + \@tempdimb\dimexpr#4\relax + \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax + \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi + \ifdim#1=#2\relax% circle? + \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor + \dimen@\@tempa\dimexpr#1\relax% r*delta + \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360) + \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90 + \@ovro\dimexpr#1\relax + \@ovri\dimexpr#2\relax + \edef\fbox@tempa{\strip@pt\@tempdima}% + \edef\fbox@tempb{\strip@pt\@tempdimb}% + \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}% + \@tempdima\@ellipcosone\@ovro + \@tempdimb\@ellipsinone\@ovri + \@tempdimc\@ellipcostwo\@ovro + \@tempdimd\@ellipsintwo\@ovri + \advance\@tempdimc by -\@tempdima% + \advance\@tempdimd by -\@tempdimb% + \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}% + %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}% + \fi + \edef#5{\the\dimen@}% +} + + +% ------------------------------------------------------------------------------ +% Borders using the picture environment +% ------------------------------------------------------------------------------ + +\newcommand*\fbox@border@pict{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \begingroup + \hbox{% + \unitlength\p@ + \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin + % markers + \ontoggle{/fbox/show-markers}{% + \linethickness{\option{/fbox/marker-width}}% + \optioncolor{/fbox/marker-color}% + \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}% + \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}% + {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}% + {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S + }% + %compute corner coordinates + \fbox@border@calccorners + %put down the background color + \fbox@border@colorbackground + \option{/fbox/picture-insert-before}% + %put down the sides + \fbox@border@side{3}{-2}{0}%top + \fbox@border@side{5}{-4}{3}%left + \fbox@border@side{-6}{7}{2}%bottom + \fbox@border@side{-8}{1}{1}%right + \end{picture}% + }% + \endgroup + \fi +} + +\newcommand*\fbox@border@pict@after{% + \ifnum\option{/fbox/render/@ord}=2\relax% + \letoption{/fbox/picture-insert-after}\fbox@insertafter + \eifblank{\fbox@insertafter}{}{% + \begingroup + \hbox{% + \begin{picture}(0,0)(0,0)% bottom-left is origin + \fbox@insertafter + \end{picture}% + }% + \endgroup + }% + \fi +} + +\newcommand*\fbox@border@side[3]{% + \fbox@setoct@angles{#1}% + \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}% + \optioncolor{/fbox/border-\fbox@side-color}% + \option{/fbox/picture-side-insert-before}% + \ifcsdef{fbox@border@pict@\fbox@style}% + {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}% + {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}% + \fbox@border@pict@solid{#1}{#2}{#3}}% + \option{/fbox/picture-side-insert-after}% +} + +% ------------------------------------------------------------------------------ +% Define standard border styles for the picture environment +% +% a style has the form \fbox@border@pict@