From 3ce8f395f1980ebc8f4e95d66e79ac7f29f99222 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 12 Sep 2013 23:16:05 +0000 Subject: stackengine (12sep13) git-svn-id: svn://tug.org/texlive/trunk@31637 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/latex/stackengine/stackengine.sty | 235 +++++++++++++++------ 1 file changed, 170 insertions(+), 65 deletions(-) (limited to 'Master/texmf-dist/tex/latex/stackengine') diff --git a/Master/texmf-dist/tex/latex/stackengine/stackengine.sty b/Master/texmf-dist/tex/latex/stackengine/stackengine.sty index 9d900389072..50103f0e9b8 100644 --- a/Master/texmf-dist/tex/latex/stackengine/stackengine.sty +++ b/Master/texmf-dist/tex/latex/stackengine/stackengine.sty @@ -1,6 +1,6 @@ -\def\stackengineversionnumber{v3.0} +\def\stackengineversionnumber{v3.1} \ProvidesPackage{stackengine} -[2013/08/06 \stackengineversionnumber +[2013/09/11 \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 @@ -25,15 +25,40 @@ % -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). \usepackage{calc} -\usepackage{readarray} -\newcounter{stackindex} -\newlength\boxshift +\usepackage{ifthen} +\newcounter{@stackindex} +\newlength\@boxshift \newlength\stack@tmplength -\global\newlength\stackedboxwidth -\newsavebox\addedbox -\newsavebox\anchorbox +\newlength\temp@stkl +\global\newlength\@stackedboxwidth +\newsavebox\@addedbox +\newsavebox\@anchorbox \newsavebox\stackedbox +\newcounter{ROWcellindex@} + %% Following 3 lines thanks to Prof. Enrico Gregorio, from: %% http://tex.stackexchange.com/questions/42318/ %% removing-a-backslash-from-a-character-sequence @@ -41,8 +66,44 @@ \lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}} \newcommand{\stack@macro@name}[1]{\expandafter\removebs\string#1} +\newcommand\setstackEOL[1]{% + \ifthenelse{\equal{#1}{}}{\def\SEP@char{ }}{\def\SEP@char{#1}}% + \expandafter\define@processROW\expandafter{\SEP@char}% +} + +\newcommand\define@processROW[1]{% + \def\@processROW##1#1##2||{% + \protected@edef\@preSEP{##1}% + \protected@edef\@postSEP{##2}% + }% +} + +% FOR PROCESSING A GROUP OF STACK ROWS SEPARATED BY \SEP@char +\newcommand\@readMANYrows[1]{% + \def\@doneROWreads{F}% + \def\@postSEP{#1\SEP@char}% + \setcounter{ROWcellindex@}{0}% + \whiledo{\equal{\@doneROWreads}{F}}{% + \stepcounter{ROWcellindex@}% + \expandafter\@processROW\@postSEP||% + \ifthenelse{\equal{\@postSEP}{}}{% + \def\@doneROWreads{T}% + }{}% + \ifthenelse{\equal{\SEP@char}{ }}% + {\def\@preSEPtemp{\@preSEP}}% + {\def\@preSEPtemp{\ignorespaces\@preSEP\unskip}}% + \expandafter\protected@edef\csname arg\roman{ROWcellindex@}\endcsname{% + \@preSEPtemp}% + }% +% \narg GIVES HOW MANY ROWS WERE PROCESSED + \xdef\narg{\arabic{ROWcellindex@}}% +} + +% PROCESS PACKAGE OPTIONS \newif\ifstackengine@oldsyntax +\newif\ifstackengine@usestackEOL \DeclareOption{oldsyntax}{\stackengine@oldsyntaxtrue} +\DeclareOption{usestackEOL}{\stackengine@usestackEOLtrue} \ProcessOptions\relax \ifstackengine@oldsyntax% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -65,17 +126,41 @@ \setstackgap{L}{\baselineskip}% LONGSTACKING GAP BETWEEN ITEMS (def. \baselineskip) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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 -\def\usestackstrut{T}% -\global\def\stack@delim{} +% DEPRECATED USAGE \def\usestackstrut{}; INSTEAD USE \strutshortanchors{} +%\def\usestackstrut{T} + +%MACROS + +%%%%% MODES \newcommand\stackMath{\global\def\stack@delim{$}} \newcommand\stackText{\global\def\stack@delim{}} +\stackText + +\newcommand\strutlongstacks[1]{\def\@strutlongstacks{#1}} +\strutlongstacks{F} + +\newcommand\strutshortanchors[1]{\def\usestackstrut{#1}} +\strutshortanchors{T} + +%%%%% %\stackengine{\Sstackgap or \Lstackgap or \stackgap or stacklength} % {anchor} @@ -86,50 +171,52 @@ % {\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}{\stack@delim#2\stack@delim}% - \sbox{\addedbox}{\stack@delim#3\stack@delim}% - \settowidth{\stackedboxwidth}{\stack@delim#2\stack@delim}% + \sbox{\@anchorbox}{\stack@delim\@STRT#2\stack@delim}% + \sbox{\@addedbox}{\stack@delim\@STRT#3\stack@delim}% + \settowidth{\@stackedboxwidth}{\stack@delim\@STRT#2\stack@delim}% \if F#7% - \ifdim\wd\addedbox>\stackedboxwidth% - \settowidth{\stackedboxwidth}{\stack@delim#3\stack@delim}% + \ifdim\wd\@addedbox>\@stackedboxwidth% + \settowidth{\@stackedboxwidth}{\stack@delim\@STRT#3\stack@delim}% \fi% \fi% - \setlength{\boxshift}{#1}% + \setlength{\@boxshift}{#1}% \if L#8% \if U#4% - \setlength{\boxshift}{-\boxshift}% + \setlength{\@boxshift}{-\@boxshift}% \fi% \else% \if U#4% - \setlength{\boxshift}{-\dp\anchorbox -\ht\addedbox -\boxshift}% + \setlength{\@boxshift}{-\dp\@anchorbox -\ht\@addedbox -\@boxshift}% \else% - \setlength{\boxshift}{\ht\anchorbox +\dp\addedbox +\boxshift}% + \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}% + \hspace{.5\@stackedboxwidth}% + \hspace{-.5\wd\@anchorbox}% + \usebox{\@anchorbox}% + \hspace{-.5\wd\@anchorbox}% + \hspace{-.5\wd\@addedbox}% + \raisebox{\@boxshift}{\stack@delim\@STRT#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}% + \usebox{\@anchorbox}% + \hspace{-\wd\@anchorbox}% + \raisebox{\@boxshift}{\stack@delim\@STRT#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}% + \hspace{\@stackedboxwidth}% + \hspace{-\wd\@anchorbox}% + \usebox{\@anchorbox}% + \hspace{-\wd\@addedbox}% + \raisebox{\@boxshift}{\stack@delim\@STRT#3\stack@delim}% \fi% \fi% \fi% @@ -152,22 +239,22 @@ \newcommand*\Longunderstack[2][\stackalignment]{\@stack{#1}{#2}{U}{L}} \newcommand*\@stack[4]{% - \getargsC{#2}% + \@readMANYrows{#2}% \if U#3% - \setcounter{stackindex}{\narg}% + \setcounter{@stackindex}{\narg}% \def\@stacksign{-}% - \def\@stackcondition{\thestackindex > 1}% + \def\@stackcondition{\the@stackindex > 1}% \else% - \setcounter{stackindex}{1}% + \setcounter{@stackindex}{1}% \def\@stacksign{}% - \def\@stackcondition{\thestackindex < \narg}% + \def\@stackcondition{\the@stackindex < \narg}% \fi% \sbox{\stackedbox}{% - \stack@delim\csname arg\roman{stackindex}\endcsname\stack@delim}% + \stack@delim\csname arg\roman{@stackindex}\endcsname\stack@delim}% \whiledo{\@stackcondition}{% - \addtocounter{stackindex}{\@stacksign 1}% + \addtocounter{@stackindex}{\@stacksign 1}% \stackengine{\csname#4stackgap\endcsname}% - {\csname arg\roman{stackindex}\endcsname}% + {\csname arg\roman{@stackindex}\endcsname}% {\usebox{\stackedbox}}{#3}{#1}{T}{\useanchorwidth}{#4}% }% \if F\quietstack\usebox{\stackedbox}\fi% @@ -182,7 +269,6 @@ \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]{% @@ -193,6 +279,8 @@ \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}% @@ -210,27 +298,10 @@ } \newcommand*\abovebaseline[2][\stackgap]{% - \stackengine{#1}{}{#2}{O}{\stackalignment}{\quietstack}{F}% - {\stacktype}} + \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}% -} + \stackengine{#1}{}{#2}{U}{\stackalignment}{\quietstack}{F}{\stacktype}} \newcommand*\savestack[2]{% \global\edef\sv@name{\stack@macro@name{#1}}% @@ -241,4 +312,38 @@ \protected@edef#1{\usebox{\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}} + +\newcommand*\bottominset[4]{\stackinset{\stackalignment}{#4}{b}{#3}{#1}{#2}} + +%\stackinset{l/c/r}{x}{b/c/t}{y}{inset}{anchor} +\newcommand*\stackinset[6]{% + \def\conditioned@inset{\stack@delim#5\stack@delim}% + \ifthenelse{\equal{#4}{}}% + {\setlength{\stack@tmplength}{0pt}}% + {\setlength{\stack@tmplength}{#4}}% + \if c#3% + \setlength{\temp@stkl}{% + \heightof{#6}+\depthof{#6}% + -\heightof{\conditioned@inset}-\depthof{\conditioned@inset}}% + \addtolength{\stack@tmplength}{.5\temp@stkl}% + \fi% + \ifthenelse{\equal{#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} + \endinput -- cgit v1.2.3