summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/stackengine/stackengine.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/stackengine/stackengine.sty
Initial commit
Diffstat (limited to 'macros/latex/contrib/stackengine/stackengine.sty')
-rw-r--r--macros/latex/contrib/stackengine/stackengine.sty402
1 files changed, 402 insertions, 0 deletions
diff --git a/macros/latex/contrib/stackengine/stackengine.sty b/macros/latex/contrib/stackengine/stackengine.sty
new file mode 100644
index 0000000000..e7b79fb04b
--- /dev/null
+++ b/macros/latex/contrib/stackengine/stackengine.sty
@@ -0,0 +1,402 @@
+\def\stackengineversionnumber{v4.01}
+\ProvidesPackage{stackengine}
+[2017/02/13 \stackengineversionnumber\
+ Stacking text and objects in convenient ways]
+% 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.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Steven B. Segletes.
+%
+% V1.0 -Initial release.
+% V2.0 -Revised syntax, making \Sstackgap=len, \Lstackgap=len syntax
+% obsolete. New syntax is \setstackgap{S}{len} and
+% \setstackgap{L}{len}
+% -Condensed several routines
+% -Revised documentation for clarity and to eliminate typos.
+% -Added \toplap and \bottomlap.
+% -Disallowed \quietstack for lapping.
+% -added \abovebaseline
+% V3.0 -Added \stackMath and \stackText macros to treat arguments,
+% by default, in math mode or not.
+% V3.1 -Added \hsmash, for zero-width, center-aligned argument (note:
+% other alignments can be achieved with \llap and \rlap)
+% -Eliminated need for \usepackage{readarray} through the
+% implementation of \@readMANYrows and \@processROW
+% -Added [usestackEOL] package option to use \\ separator, rather
+% than space separator in \Shortstack, \Longstack,
+% \Shortunderstack, and \Longunderstack
+% -Implemented \setstackEOL to define new separator in \Shortstack,
+% \Longstack, \Shortunderstack, and \Longunderstack
+% -Renamed some package internal variables with @...
+% -Added \addstackgap to place vertical gap above and below an
+% existing stack. Negative gaps have no effect.
+% -Added \stackinset, deprecates \topinset & \bottominset.
+% -allow c \stackalignment on \stackinset, \topinset, and
+% \bottominset to have meaning (rightward offset relative to
+% centerline, can be positive or negative).
+% -Forced \useanchorwidth{T} for insets, since otherwise the
+% stackwidth could vary for reasons not obvious to user.
+% -Added \strutlongstacks{} mode for auto-adding a strut to
+% each row of a long stack
+% -Recommend \strutshortanchors{} mode in preference to
+% \def\usestackstrut{} definition (now deprecated).
+% V3.11 -Corrected bug in \stackinset which did not condition the
+% anchor when using vertical centering in \stackMath mode
+% V3.2 -Incorporated changes suggested by E. Gregorio to make robust
+% the supporting macro \@readMANYrows
+% -Introduced routines: \Centerstack, \Vectorstack, \parenVectorstack
+% \bracketVectorstack, \braceVectorstack, \vertvectorstack,
+% and \ensurestackMath
+% V3.21 -Corrected a bug in \stackinset introduced in V3.11
+% V3.22 -Removed \usepackage{calc}
+% -Corrected \@STRT placement to not inadvertantly force a \mathop
+% on rows beginning with a minus sign.
+% V3.23 -Made EOL-separated stacks (i.e., \Longstack, \Shortstack,
+% \Centerstack, \Vectorstack, etc.) work properly when a single
+% (unstacked) row is input.
+% -Noted in documentation that while EOL-separated stacks
+% ignore leading/trailing spaces in their arguments (unless the
+% EOL itself is a space token), the \stackon / \stackunder
+% family of macros do not ignore spaces in their arguments.
+% -Reinstated \usepackage{calc} (Oops!)
+% V3.24 -Replaced references to \roman with \romannumeral, since \roman
+% is redefined by packages like spanish babel.
+% V3.25 -Default longstack gap is now \normalbaselineskip, so as to
+% automatically work in tabular environments.
+% V3.26 -V3.25 on partially fixed the problem of \normalbaselineskip.
+% V4.00 -Incorporate listofitems package methodology for parsing, requiring
+% some package rewrite, primarily macro \@readMANYrows.
+% -Eliminated all uses of \protected@edef.fxf
+% V4.01 -Removed unnecessary\global specifiers from \newlength and
+% \setlength, which could also cause potential problems with the
+% calc package.
+% -Changed \global\def to \gdef and \global\edef to \xdef.
+\RequirePackage{etoolbox}
+\RequirePackage{listofitems}% REQUIRES listofitems.sty AND listofitems.tex
+\usepackage{calc}
+
+\newtoggle{@doneROWreads}
+\newtoggle{stackloop@done}
+\newcounter{@stackindex}
+\newlength\@boxshift
+\newlength\stack@tmplength
+\newlength\temp@stkl
+\newlength\@stackedboxwidth
+\newsavebox\@addedbox
+\newsavebox\@anchorbox
+\newsavebox\stackedbox
+\newsavebox{\@centerbox}
+\newcounter{ROWcellindex@}
+
+%% Following 3 lines thanks to Prof. Enrico Gregorio, from:
+%% http://tex.stackexchange.com/questions/42318/
+\begingroup\lccode`\|=`\\
+\lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}}
+\newcommand{\stack@macro@name}[1]{\expandafter\removebs\string#1}
+
+%% Following macro was, in V3.2, made robust with the help of
+%% Prof. Enrico Gregorio. See:
+%% http://tex.stackexchange.com/questions/137298/
+\newcommand\setstackEOL[1]{%
+ \ifstrempty{#1}{\def\SEP@char{ }}{\def\SEP@char{#1}}%
+}
+
+% FOR PROCESSING A GROUP OF STACK ROWS SEPARATED BY \SEP@char
+% EMPLOYS listofitems PACKAGE, AS OF V4.0
+\newcommand\@readMANYrows[1]{%
+ \expandafter\setsepchar\expandafter{\SEP@char}%
+ \readlist*\stack@arg{#1}%
+ \xdef\stackengine@args{\stack@arglen}%
+}
+%%%%%
+
+% PROCESS PACKAGE OPTIONS
+\newif\ifstackengine@oldsyntax
+\newif\ifstackengine@usestackEOL
+\DeclareOption{oldsyntax}{\stackengine@oldsyntaxtrue}
+\DeclareOption{usestackEOL}{\stackengine@usestackEOLtrue}
+\ProcessOptions\relax
+\ifstackengine@oldsyntax%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%% THIS VERSION 1.0 SYNTAX WAS PHASED OUT %%%%%%%%%%%%%%%%%%%
+%%%%% (but can invoke with \usepackage[oldsyntax]{stackengine} )
+\newlength\Sstackgap\newlength\Lstackgap
+\newcommand\stackgap{\if S\stacktype\the\Sstackgap\else\the\Lstackgap\fi}
+\setlength{\Sstackgap}{3pt}
+\setlength{\Lstackgap}{\normalbaselineskip}
+\else%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%% AND REPLACED WITH THE FOLLOWING %%%%%%%%%%%%%%%%%%%%%%%%%%
+% Again, thanks to Prof. Gregorio for his lucid explanation that helped
+% improve this package. See:
+% http://tex.stackexchange.com/questions/123443/
+% defining-a-length-that-scales-with-fontsize-changes/123470#123470
+\newcommand{\setstackgap}[2]{\@namedef{#1stackgap}{#2}}
+\newcommand\stackgap{\@nameuse{\if S\stacktype S\else L\fi stackgap}\relax}
+\setstackgap{S}{3pt}% SHORTSTACKING GAP BETWEEN ITEMS (SAME AS \shortstack)
+\setstackgap{L}{\normalbaselineskip}% LONGSTACKING BASELINESKIP (\normalbaselineskip)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\fi
+\ifstackengine@usestackEOL%
+% USE \\ AS SEPERATOR IN \Shortstack, \Longstack,
+% \Shortunderstack, and \Longunderstack
+ \setstackEOL{\\}
+\else
+% USE SPACE TOKEN AS SEPERATOR IN \Shortstack, \Longstack,
+% \Shortunderstack, and \Longunderstack
+ \setstackEOL{ }
+\fi
+
+%%%%% PACKAGE DEFAULT DEFINITIONS
+\def\useanchorwidth{F}% T= FORCE BOX WIDTH TO ANCHOR-WIDTH
+\def\quietstack{F}% T = SUPPRESS OUTPUT OF ALL COMMANDS
+% (USE \usebox{\stackedbox} TO RETRIEVE)
+\def\stackalignment{c}% l, c, or r for left, center or right alignment
+\def\stacktype{S}% S for constant gap shortstack;
+ % L for constant baselineskip longstack
+
+% DEPRECATED USAGE \def\usestackstrut{}; INSTEAD USE \strutshortanchors{}
+%\def\usestackstrut{T}
+
+%%%%% MODES
+\newcommand\stackMath{\gdef\stack@delim{$}}
+\newcommand\stackText{\gdef\stack@delim{}}
+\stackText
+
+\newcommand\strutlongstacks[1]{\def\@strutlongstacks{#1}}
+\strutlongstacks{F}
+
+\newcommand\strutshortanchors[1]{\def\usestackstrut{#1}}
+\strutshortanchors{T}
+
+%%%%% MACROS
+
+%\stackengine{\Sstackgap or \Lstackgap or \stackgap or stacklength}
+% {anchor}
+% {item}
+% {O or U}
+% {\stackalignment or l or c or r}
+% {\quietstack or T or F}
+% {\useanchorwidth or T or F}
+% {\stacktype or S or L}
+\newcommand*\stackengine[8]{%
+ \def\@STRT{}%
+ \if T\@strutlongstacks\if L#8\def\@STRT{\strut}\fi\fi%
+ \sbox{\stackedbox}{%
+ \sbox{\@anchorbox}{\@STRT\stack@delim#2\stack@delim}%
+ \sbox{\@addedbox}{\@STRT\stack@delim#3\stack@delim}%
+ \settowidth{\@stackedboxwidth}{\@STRT\stack@delim#2\stack@delim}%
+ \if F#7%
+ \ifdim\wd\@addedbox>\@stackedboxwidth%
+ \settowidth{\@stackedboxwidth}{\stack@delim\@STRT#3\stack@delim}%
+ \fi%
+ \fi%
+ \setlength{\@boxshift}{#1}%
+ \if L#8%
+ \if U#4%
+ \setlength{\@boxshift}{-\@boxshift}%
+ \fi%
+ \else%
+ \if U#4%
+ \setlength{\@boxshift}{-\dp\@anchorbox -\ht\@addedbox -\@boxshift}%
+ \else%
+ \setlength{\@boxshift}{\ht\@anchorbox +\dp\@addedbox +\@boxshift}%
+ \fi%
+ \fi%
+ \if c#5%
+ \hspace{.5\@stackedboxwidth}%
+ \hspace{-.5\wd\@anchorbox}%
+ \usebox{\@anchorbox}%
+ \hspace{-.5\wd\@anchorbox}%
+ \hspace{-.5\wd\@addedbox}%
+ \raisebox{\@boxshift}{\@STRT\stack@delim#3\stack@delim}%
+ \hspace{-.5\wd\@addedbox}%
+ \hspace{.5\@stackedboxwidth}%
+ \else%
+ \if l#5%
+ \usebox{\@anchorbox}%
+ \hspace{-\wd\@anchorbox}%
+ \raisebox{\@boxshift}{\@STRT\stack@delim#3\stack@delim}%
+ \hspace{-\wd\@addedbox}%
+ \hspace{\@stackedboxwidth}%
+ \else%
+ \if r#5%
+ \hspace{\@stackedboxwidth}%
+ \hspace{-\wd\@anchorbox}%
+ \usebox{\@anchorbox}%
+ \hspace{-\wd\@addedbox}%
+ \raisebox{\@boxshift}{\@STRT\stack@delim#3\stack@delim}%
+ \fi%
+ \fi%
+ \fi%
+ }%
+ \if F#6\usebox{\stackedbox}\fi%
+}
+
+\newcommand*\stackunder[3][\stackgap]{\stackengine%
+ {#1}{#2}{#3}{U}{\stackalignment}{\quietstack}{\useanchorwidth}{\stacktype}}
+
+\newcommand*\stackon[3][\stackgap]{\stackengine%
+ {#1}{#2}{#3}{O}{\stackalignment}{\quietstack}{\useanchorwidth}{\stacktype}}
+
+\newcommand*\Shortstack[2][\stackalignment]{\@stack{#1}{#2}{O}{S}}
+
+\newcommand*\Longstack[2][\stackalignment]{\@stack{#1}{#2}{O}{L}}
+
+\newcommand*\Shortunderstack[2][\stackalignment]{\@stack{#1}{#2}{U}{S}}
+
+\newcommand*\Longunderstack[2][\stackalignment]{\@stack{#1}{#2}{U}{L}}
+
+\newcommand*\@stack[4]{%
+ \bgroup% SO AS NOT TO INTERFERE WITH loi's \setsepchar
+ \@readMANYrows{#2}%
+ \if U#3%
+ \setcounter{@stackindex}{\stackengine@args}%
+ \def\@stacksign{-}%
+ \def\@stackcondition{\the@stackindex > 1}%
+ \else%
+ \setcounter{@stackindex}{1}%
+ \def\@stacksign{}%
+ \def\@stackcondition{\the@stackindex < \stackengine@args}%
+ \fi%
+ \def\@STRT{}%
+ \if T\@strutlongstacks\if L#4\def\@STRT{\strut}\fi\fi%
+ \sbox{\stackedbox}{%
+ \@STRT\stack@delim\ignorespaces%
+ \stack@arg[\the@stackindex]%
+ \unskip\stack@delim}%
+ \ifnum\stackengine@args>1%
+ \togglefalse{stackloop@done}%
+ \else%
+ \toggletrue{stackloop@done}%
+ \fi%
+ \whileboolexpr{test {\nottoggle{stackloop@done}}}{%
+ \addtocounter{@stackindex}{\@stacksign 1}%
+ \stackengine{\csname#4stackgap\endcsname}%
+ {\stack@arg[\the@stackindex]}%
+ {\usebox{\stackedbox}}{#3}{#1}{T}{\useanchorwidth}{#4}%
+ \ifnum\@stackcondition\else\toggletrue{stackloop@done}\fi%
+ }%
+ \if F\quietstack\usebox{\stackedbox}\fi%
+ \egroup%
+}
+
+% PERHAPS THESE SIX MACROS CAN BE REPLACED BY \toplap AND \bottomlap
+\newcommand*\tllap[2][\Lstackgap]{\@stacklap{#1}{l}{#2}{O}}
+\newcommand*\tclap[2][\Lstackgap]{\@stacklap{#1}{c}{#2}{O}}
+\newcommand*\trlap[2][\Lstackgap]{\@stacklap{#1}{r}{#2}{O}}
+\newcommand*\bllap[2][\Lstackgap]{\@stacklap{#1}{l}{#2}{U}}
+\newcommand*\bclap[2][\Lstackgap]{\@stacklap{#1}{c}{#2}{U}}
+\newcommand*\brlap[2][\Lstackgap]{\@stacklap{#1}{r}{#2}{U}}
+
+\newcommand*\toplap[3][\Lstackgap]{\@stacklap{#1}{#2}{#3}{O}}
+\newcommand*\bottomlap[3][\Lstackgap]{\@stacklap{#1}{#2}{#3}{U}}
+
+\newcommand*\@stacklap[4]{%
+ \if l#2\stackengine{#1}{}{#3}{#4}{r}{F}{T}{L}\else%
+ \if r#2\stackengine{#1}{}{#3}{#4}{l}{F}{T}{L}\else%
+ \stackengine{#1}{}{#3}{#4}{c}{F}{T}{L}%
+ \fi%
+ \fi
+}
+
+\newcommand*\hsmash[1]{\stackengine{0pt}{}{#1}{O}{c}{F}{T}{L}}
+
+\newcommand*\stackanchor[3][\stackgap]{%
+ \setlength{\stack@tmplength}{#1}%
+ \setlength{\stack@tmplength}{.5\stack@tmplength}%
+ \if T\usestackstrut%
+ \if S\stacktype\addtolength{\stack@tmplength}%
+ {.5\ht\strutbox-.5\dp\strutbox}\fi%
+ \fi%
+ \stackengine{\stack@tmplength}{}{#2}{O}{\stackalignment}{T}{F}{\stacktype}%
+ \if T\usestackstrut%
+ \if S\stacktype\addtolength{\stack@tmplength}%
+ {-\ht\strutbox+\dp\strutbox}\fi%
+ \fi%
+ \stackengine{\stack@tmplength}{\usebox{\stackedbox}}{#3}{U}%
+ {\stackalignment}{\quietstack}{F}{\stacktype}%
+}
+
+\newcommand*\abovebaseline[2][\stackgap]{%
+ \stackengine{#1}{}{#2}{O}{\stackalignment}{\quietstack}{F}{\stacktype}}
+
+\newcommand*\belowbaseline[2][\stackgap]{%
+ \stackengine{#1}{}{#2}{U}{\stackalignment}{\quietstack}{F}{\stacktype}}
+
+\newcommand*\savestack[2]{%
+ \xdef\sv@name{\stack@macro@name{#1}}%
+ \@ifundefined{\sv@name content}{%
+ \expandafter\newsavebox\expandafter{\csname\sv@name content\endcsname}%
+ }{}%
+ \expandafter\sbox\csname\sv@name content\endcsname{#2}%
+ \expandafter\def\expandafter#1\expandafter{\expandafter\usebox\expandafter%
+ {\csname\sv@name content\endcsname}}%
+}
+
+\newcommand*\addstackgap[2][\Sstackgap]{\stackengine{#1}{%
+ \stackengine{#1}{#2}{}{O}{c}{\quietstack}{T}{S}}{}{U}{c}{\quietstack}{T}{S}}
+
+\newcommand*\topinset[4]{\stackinset{\stackalignment}{#4}{t}{#3}{#1}{#2}}% DEPRECATED
+
+\newcommand*\bottominset[4]{\stackinset{\stackalignment}{#4}{b}{#3}{#1}{#2}}% DEPRECATED
+
+%\stackinset{l/c/r}{x}{b/c/t}{y}{inset}{anchor}
+\newcommand*\stackinset[6]{%
+ \def\conditioned@inset{\stack@delim#5\stack@delim}%
+ \def\conditioned@anchor{\stack@delim#6\stack@delim}%
+ \ifstrequal{#4}{}%
+ {\setlength{\stack@tmplength}{0pt}}%
+ {\setlength{\stack@tmplength}{#4}}%
+ \if c#3%
+ \setlength{\temp@stkl}{%
+ \heightof{\conditioned@anchor}+\depthof{\conditioned@anchor}%
+ -\heightof{\conditioned@inset}-\depthof{\conditioned@inset}}%
+ \addtolength{\stack@tmplength}{.5\temp@stkl}%
+ \fi%
+ \ifstrequal{#2}{}{\def\stack@tmp{0pt}}{\def\stack@tmp{#2}}%
+ \def\stack@lroffset{\rule{\stack@tmp}{0pt}}%
+ \addtolength{\stack@tmplength}{%
+ \heightof{\conditioned@inset}+\depthof{\conditioned@inset}}%
+ \if c#1%
+ \def\conditioned@inset{\stack@lroffset\stack@lroffset#5}%
+ \else%
+ \def\conditioned@inset{\stack@lroffset#5\stack@lroffset}%
+ \fi%
+ \stackengine{-\stack@tmplength}{#6}{\conditioned@inset}%
+ {\inset@valign{#3}}{#1}{\quietstack}{T}{S}%
+}
+
+\def\inset@valign#1{\if t#1O\else U\fi}
+
+\newcommand\Centerstack[2][\stackalignment]{%
+ \sbox{\@centerbox}{\strutlongstacks{T}\Longstack[#1]{#2}}%
+ \raisebox{-.5\ht\@centerbox+.5\ht\strutbox}{\usebox{\@centerbox}}}
+
+\newcommand\Vectorstack[2][\stackalignment]{%
+ \ensurestackMath{\Centerstack[#1]{#2}}}
+
+\newcommand\parenVectorstack[2][\stackalignment]{%
+ \ensurestackMath{\left(\Centerstack[#1]{#2}\right)}}
+
+\newcommand\bracketVectorstack[2][\stackalignment]{%
+ \ensurestackMath{\left[\Centerstack[#1]{#2}\right]}}
+
+\newcommand\braceVectorstack[2][\stackalignment]{%
+ \ensurestackMath{\left\{\Centerstack[#1]{#2}\right\}}}
+
+\newcommand\vertVectorstack[2][\stackalignment]{%
+ \ensurestackMath{\left|\Centerstack[#1]{#2}\right|}}
+
+\newcommand\ensurestackMath[1]{%
+ \let\sv@stackmode\stack@delim\stackMath%
+ #1\global\let\stack@delim\sv@stackmode}
+
+\endinput