diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /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.sty | 402 |
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 |