\def\stackengineversionnumber{v3.0} \ProvidesPackage{stackengine} [2013/08/06 \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. \usepackage{calc} \usepackage{readarray} \newcounter{stackindex} \newlength\boxshift \newlength\stack@tmplength \global\newlength\stackedboxwidth \newsavebox\addedbox \newsavebox\anchorbox \newsavebox\stackedbox %% Following 3 lines thanks to Prof. Enrico Gregorio, from: %% http://tex.stackexchange.com/questions/42318/ %% removing-a-backslash-from-a-character-sequence \begingroup\lccode`\|=`\\ \lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} \newcommand{\stack@macro@name}[1]{\expandafter\removebs\string#1} \newif\ifstackengine@oldsyntax \DeclareOption{oldsyntax}{\stackengine@oldsyntaxtrue} \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} \global\setlength{\Sstackgap}{3pt} \global\setlength{\Lstackgap}{\baselineskip} \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}{\baselineskip}% LONGSTACKING GAP BETWEEN ITEMS (def. \baselineskip) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \fi \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 \def\usestackstrut{T}% \global\def\stack@delim{} \newcommand\stackMath{\global\def\stack@delim{$}} \newcommand\stackText{\global\def\stack@delim{}} %\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]{% \sbox{\stackedbox}{% \sbox{\anchorbox}{\stack@delim#2\stack@delim}% \sbox{\addedbox}{\stack@delim#3\stack@delim}% \settowidth{\stackedboxwidth}{\stack@delim#2\stack@delim}% \if F#7% \ifdim\wd\addedbox>\stackedboxwidth% \settowidth{\stackedboxwidth}{\stack@delim#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}{\stack@delim#3\stack@delim}% \hspace{-.5\wd\addedbox}% \hspace{.5\stackedboxwidth}% \else% \if l#5% \usebox{\anchorbox}% \hspace{-\wd\anchorbox}% \raisebox{\boxshift}{\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}{\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]{% \getargsC{#2}% \if U#3% \setcounter{stackindex}{\narg}% \def\@stacksign{-}% \def\@stackcondition{\thestackindex > 1}% \else% \setcounter{stackindex}{1}% \def\@stacksign{}% \def\@stackcondition{\thestackindex < \narg}% \fi% \sbox{\stackedbox}{% \stack@delim\csname arg\roman{stackindex}\endcsname\stack@delim}% \whiledo{\@stackcondition}{% \addtocounter{stackindex}{\@stacksign 1}% \stackengine{\csname#4stackgap\endcsname}% {\csname arg\roman{stackindex}\endcsname}% {\usebox{\stackedbox}}{#3}{#1}{T}{\useanchorwidth}{#4}% }% \if F\quietstack\usebox{\stackedbox}\fi% } % 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*\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*\topinset[4]{\stack@inset{#1}{#2}{#3}{#4}{O}} \newcommand*\bottominset[4]{\stack@inset{#1}{#2}{#3}{#4}{U}} \newcommand*\stack@inset[5]{% \ifthenelse{\equal{#3}{}} {\setlength{\stack@tmplength}{0pt}}% {\setlength{\stack@tmplength}{#3}}% \ifthenelse{\equal{#4}{}}{\def\stack@tmp{0pt}}{\def\stack@tmp{#4}}% \def\stack@lroffset{\rule{\stack@tmp}{0pt}}% \addtolength{\stack@tmplength}{\heightof{\stack@delim#1\stack@delim}}% \stackengine{-\stack@tmplength}{#2}{\stack@lroffset#1\stack@lroffset}% {#5}{\stackalignment}{\quietstack}{\useanchorwidth}{S}% } \newcommand*\savestack[2]{% \global\edef\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}% \protected@edef#1{\usebox{\csname\sv@name content\endcsname}}% } \endinput