% Tableau macros -- tabmac.sty, by Glenn Tesler % Do not further distribute until further notice; it's incomplete now. % % \documentstyle[...,tabmac,...]{article} % or to use arrows through pb-diagram, things must go in this order: % \documentstyle[...,pb-diagram,tabmac,...]{article} % or \documentstyle[...,pb-diagram,lamsarrow,pb-lams,tabmac,...]{article} % % \tableau[options]{row1|row2|...|rowk} (can use \\ instead of |) % \tableau*[options]{row1\\row2\\...\\rowk} % rowk may be followed by optional | or \\, so to actually produce % a final row with only one entry, terminate with || or \\ \\ % % options: % alignment: % c: center, b: bottom, t: top % diagram type: % F: Ferrer's diagram Y: Young diagram % dflt cell frame none thin frame % null cells \bullet thin frame % ~ (for skew) \bullet no frame % a: use arrow font dimension as base instead of \strut % cell size in multiples of current font's \strut's dimensions % s: small (x1), m: medium (x2 -- default), l: large (x3) % p: small partition sized % can set variable \Tscale for scaling as well. % If you do this, don't use s,m,l as they will override this setting. % can use font size declarations -- \tiny, \Large, etc. -- to change % font size and cell size, too. % % rowi has the form % c1,c2,c3,c4,...,cn % where these are the entries to go on the row. Can use & instead of , % in * form, must use & % If no entry is given, the cell is a frame (Young) or a bullet (Ferrers) % special entries (only \ forms available with \tableau*) % \bullet, @ = bullet (unframed in Ferrers, framed in Young) % \bl = blank (no frame in either) % \sk, ~ = skew cell (use in upper left corner of tableau; % no frame in Young, bullet in Ferrer) % \tf, * = thick frame % \fl = filled square % \overlay ... = superimpose ... on this cell (terminate with another % \overlay, or with the end of the tab field) % \overlay[??] ... = superimpose ... on this cell with alignment given by % combination of the characters in ?? % t, c, b -- top, center, bottom % l, m, r -- left, middle, right % To get a blank row, use the one entry \bl on that row, i.e., |\bl| % because doing || will yield a one-square row (Young) or one bullet row % (Ferrers) % % The \arrow command from pb-diagram is implemented. % Use the exact same syntax for \arrow as in diagram. % Additional parameters which dgo@???? routines may set are two routines % \def\tb@getnodesizehead#1#2{...} % \def\tb@getnodesizetail#1#2{...} % which put the width & height of the text at the head or tail nodes % into number registers #1, #2, in units of scaled points. % % Arrow bugs: % The tableau dimensions don't correspond to the restricted % discrete arrow lengths, so when real small arrow wanted, % only a longer one might be available; option ``a'' may help. % % Dashed arrows may not be uniformly dashed. % % More to do % Add in LaTeX picture mode; put in alternate frames (dashed, oval, circle) % from LaTeX picture mode instead of just the thin and bold frames, % and use the picture mode \linethickness declaration instead of % \tb@fframe,... % % % % w/in tableau, \dimen0=cell size, \dimen1=frame size, \dimen2=strut size % with option "a", \dimen2 is replaced by value better suited to arrows. % % Be very careful that all lines end in % % so that no spurious spaces are introduced anywhere. \edef\savecatcodeat{\the\catcode`@} \catcode`\@=11 \def\tb@ifSpecChars#1#2{#1} \def\tb@ifNoSpecChars#1#2{#2} % Determine if * form used \def\tableau{% \bgroup% matched in \tb@tableauD \@ifstar{\let\Tif\tb@ifNoSpecChars\tb@tableauB}% *, don't use special chars {\let\Tif\tb@ifSpecChars\tb@tableauB}}% no *, use special chars \def\tb@tableauB{% add [] if no [options] \@ifnextchar[{\tb@tableauC}{\tb@tableauC[]}} \def\tb@tableauC[#1]{\hbox\bgroup% \let\\=\cr% end line \def\bl{\global\let\tbcellF\tb@cellNF}% \def\tf{\global\let\tbcellF\tb@cellH}% highlighted cell % % \dimen0=cell size, \dimen1=frame size, \dimen2=strut size \dimen2=\ht\strutbox \advance\dimen2 by\dp\strutbox% \ifx\baselinestretch\undefined\relax% \else% % want \dimen2 = \dimen2 / \baselinestretch, but can't do that if % \baselinestretch has a decimal, so fake it to 2 decimal places. \dimen0=100sp \dimen0=\baselinestretch\dimen0% \dimen2=100\dimen2 \divide\dimen2 by\dimen0% \fi% % \let\tpos\tb@vcenter% default position \tb@initYoung% default tableau type \tb@options#1\eoo% parse options % \let\arrow\tb@arrow% % \dimen0=\Tscale\dimen2% \dimen1=\dimen0 \advance\dimen1 by \tb@fframe% % \lineskip=0pt\baselineskip=0pt% line spacing will be from \vbox to \dimen0 % % \mkcell{#1} -- format individual cell: % set cellF to default frame. % supply argument for cell if none given % format argument in sized box, then superimpose cell frame. \def\tb@nothing{}% \def\endcellno{$\rss\egroup\bss\egroup}% end cell w/o overlap \def\endcell{\endcellno\kern-\dimen0}% end cell & prepare to overlap it \def\begincell{\vbox to\dimen0\bgroup\vss\hbox to\dimen0\bgroup\hss$}% % \def\overlay{\endcell\begincell}% \let\overlay\tb@overlay% \let\fl\tb@fl% \let\lss\hss\let\rss\hss\let\tss\vss\let\bss\vss% cell alignment \def\mkcell##1{% format individual cell \let\tbcellF\tb@cellD% default cell frame \def\tb@cellarg{##1}% store cell contents % provide default contents if cell empty \ifx\tb@cellarg\tb@nothing\let\tb@cellarg\tb@cellE\fi% \begincell\tb@cellarg\endcellno% the actual cell content \tbcellF}% draw cell frame % \let\savecellF\tbcellF% save global value of cellF in case of nested tableau \Tif{\catcode`,=4\catcode`|=\active}{}\tb@tableauD}% \let\tb@savetableauD\tableauD% save any current definition {% set up characters which will be interpreted as command characters % when the definition of \tableauD is read in \catcode`|=\active \catcode`*=\active \catcode`~=\active% \catcode`@=\active% command characters \gdef\tableauD#1{% \Tif{% make all the command characters active in math mode when #1 parsed \mathcode`|="8000 \mathcode`*="8000% \mathcode`~="8000 \mathcode`@="8000% \def@{\bullet}% \let|\cr% end line \let*\tf% highlighted cell \let~\sk% skew cell }{}% \tpos{\tabskip=0pt\halign{&\mkcell{##}\cr#1\crcr}}% \global\let\tbcellF\savecellF% restore global value \egroup% match \hbox\bgroup at start of \tableauC \egroup}% match \bgroup at start of \tableau } \let\tb@tableauD\tableauD% rename the command \let\tableauD\tb@savetableauD% restore old command with this name \let\tb@savetableauD\undefined %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Parse options in \tableau[options] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % pick out one option at a time until \eoo reached. \def\tb@options#1{\ifx#1\eoo\relax\else\tb@option#1\expandafter\tb@options\fi} % dispatch handler for each option \def\tb@option#1{% \if#1t\let\tpos\tb@vtop\fi% t = align at top \if#1c\let\tpos\tb@vcenter\fi% c = align at center \if#1b\let\tpos\vbox\fi% b = align at bottom \if#1F\tb@initFerrers\fi% F = Ferrers diagram \if#1Y\tb@initYoung\fi% Y = Young diagram \if#1s\tb@initSmall\fi% s = small boxes \if#1m\tb@initMedium\fi% m = medium boxes \if#1l\tb@initLarge\fi% l = large boxes \if#1p\tb@initPartition\fi% p = small partition sized boxes \if#1a\tb@initArrow\fi% a = use arrow font as base dimension } % alternate to \vcenter which starts math mode if necessary \def\tb@vcenter#1{\ifmmode\vcenter{#1}\else$\vcenter{#1}$\fi} % alternate to \vtop; the array produced by \halign has as its baseline % the lower border of the first row of the tableau, so move down by this % amount, and move up \ht\strutbox to align the top border with the % top of the text on this line. \def\tb@vtop#1{\hbox{\raise\ht\strutbox\hbox{\lower\dimen0\vtop{#1}}}} \def\tb@initPartition{\def\Tscale{.3}} \def\tb@initSmall{\def\Tscale{1}} \def\tb@initMedium{\def\Tscale{2}} \def\tb@initLarge{\def\Tscale{3}} % diagram has dimens hardcoded. Arrow is .625em \def\tb@initArrow{\dimen2=1.25em} \def\tb@initYoung{% \def\tb@cellE{}% empty cell stays empty \let\tb@cellD\tb@cellN% default frame is normal frame \def\sk{\global\let\tbcellF\tb@cellNF}}% skew cells are empty \def\tb@initFerrers{% \def\tb@cellE{\bullet}% empty cell gets bullet \let\tb@cellD\tb@cellNF% default frame is no frame \def\sk{\bullet}}% skew cell gets bullet \tb@initMedium% default scale %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % draw square frame with edges of given thickness %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % initial refrence pt = upper right corner of cell \def\tb@sframe#1{% \vbox to0pt{% Embed frame in a box of no vert or hor extent \vss% pull box above reference point \hbox to0pt{% \hss% pull box left of reference point \vbox to\dimen1{% Actual width of frame \hrule depth #1 height0pt% draw top edge of frame \vss% begin vcenter sides \hbox to\dimen1{% horiz box with side edges just inside \vrule width #1 height\dimen1% left edge \hss% stretch center \vrule width #1% right edge }% \vss% end vcenter sides \hrule height #1 depth 0in% bottom edge }% \kern-\tb@hframe% horiz alignment off by half line width }% \kern-\tb@hframe}}% vert alignment off by half line width % alignment off by \dimen1-\dimen0=2\tb@hframe % should this be combined with picture modes' linethickness? % \tb@fframe = width of ordinary divider line % \tb@hframe = \tb@fframe/2 % \tb@bframe = width of bold divider line; % ought to have \tb@bframe >= \tb@fframe \def\tb@hframe{.2pt}\def\tb@fframe{.4pt}\def\tb@bframe{2pt} \def\tb@cellH{\tb@sframe{\tb@bframe}} % bold frame \def\tb@cellNF{} % no frame \def\tb@cellN{\tb@sframe{\tb@fframe}} % normal frame \let\tbcellF\tb@cellN % default is normal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % overlay cell contents %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\tb@rpad{1pt} \def\tb@lpad{1pt} \def\tb@tpad{1.8pt} \def\tb@bpad{1.8pt} \def\tb@overlay{\endcell\@ifnextchar[{\tb@overlaya}{\begincell}} %\def\tb@overlay{\endcell\@ifnextchar[{\begincell}{\begincell}} \def\tb@overlaya[#1]{\vbox to\dimen0\bgroup% \tb@overlayoptions#1\eoo% \tss\hbox to\dimen0\bgroup\lss$} % pick out one option at a time until \eoo reached. \def\tb@overlayoptions#1{\ifx#1\eoo\relax\else\tb@overlayoption#1\expandafter\tb@overlayoptions\fi} % dispatch handler for each option \def\tb@overlayoption#1{ \if#1t\def\tss{\vskip\tb@tpad}\let\bss\vss\fi% t = align at top \if#1c\let\tss\vss\let\bss\vss\fi% c = align at center \if#1b\def\bss{\vskip\tb@bpad}\let\tss\vss\fi% b = align at bottom \if#1l\def\lss{\hskip\tb@lpad}\let\rss\hss\fi% l = align at left \if#1m\let\lss\hss\let\rss\hss\fi% m = align at middle \if#1r\def\rss{\hskip\tb@rpad}\let\lss\hss\fi% r = align at right } \def\tb@fl{\endcell\begincell\vrule depth 0pt width \dimen0 height \dimen0 \endcell\begincell} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % arrows, if diagram loaded %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \@ifundefined{diagram}{}{ % should \tb@arrowpad should be a multiple of .5? \def\tb@arrowpad{.5} % stripped down/altered from \dg@arrow % Usage: \tb@arrow[USERSIZE]{ARROW_SPECS}LABELS... \newoptcommand{\tb@arrow}{\@ne}[2]{% \endcell% end previous cell contents % Keep all arrow geometry parameters local. % The \endgroup is in \tb@draw \begingroup% \let\dg@getnodesize\tb@getnodesize% substitute routine to get nodesize % Get optional arrow USERSIZE. \dg@USERSIZE=#1\relax% \ifnum\dg@USERSIZE<\@ne \dg@USERSIZE=\@ne \fi% % Parse arrow specification. \dg@parse{#2}% \dg@label{\tb@draw{#1}{#2}}}% draw arrow % substitute alternate routine for getting node sizes % Usage: \tb@getnodesize{SLIST}{XCOORD}{YCOORD}{\WIDTH}{\HEIGHT} \def\tb@getnodesize#1#2#3#4#5{\dimen3=\tb@arrowpad\dimen2 #4=\dimen3 #5=\dimen3\relax} \def\tb@getnodesize#1#2#3#4#5{\ifnum#2=0\ifnum#3=0\tb@getnodesizetail{#4}{#5}\else\tb@getnodesizehead{#4}{#5}\fi\else\tb@getnodesizehead{#4}{#5}\fi} \def\tb@getnodesizetail#1#2{\dimen3=.5\dimen2 #1=\dimen3 #2=\dimen3} \def\tb@getnodesizehead#1#2{\dimen3=.5\dimen2 #1=\dimen3 #2=\dimen3} % like \dg@drawcalc & \dg@draw; do the actual drawing \def\tb@draw#1#2#3#4{% % grid geometry is determined by the tableau grid \dg@X=0\dg@Y=0\dg@XGRID=1\dg@YGRID=1\unitlength=.001\dimen0% \dg@LBLOFF=\dgLABELOFFSET \divide\dg@LBLOFF\unitlength% % \dg@drawcalc% compute arrow geometry \begincell% start tableau cell \let\lams@arrow\tb@lams@arrow% substitute routine % draw arrow VVVVV matches endgroup in \dg@draw \begin{picture}(0,0)\begingroup\dg@draw{#1}{#2}{#3}{#4}\end{picture}% \endcell% end tableau cell \endgroup% match \begingroup in \tb@arrow \begincell}% start new entry in this cell } % \lamssource{V} (= \arrow{...,V}), \lamstarget{V}, \lamstarget{^} % cause placement of arrow to be ``adjusted'', but then the % 45 deg. arrows don't go through grid points on the tableau. % % So this code from lamsarrow.sty has the adjustment section disabled. % % Perhaps \dgo@V should be modified to provide extra padding around cell % contents to compensate for the removed adjustment. % %\def\lams@arrow#1#2{% \def\tb@lams@arrow#1#2{% \lams@firstx\z@\lams@firsty\z@ \lams@lastx#1\relax\lams@lasty#2\relax \lams@center\z@ % % compute direction flags \N@false\E@false\H@false\V@false \ifdim\lams@lastx>\z@\E@true\fi \ifdim\lams@lastx=\z@\V@true\fi \ifdim\lams@lasty>\z@\N@true\fi \ifdim\lams@lasty=\z@\H@true\fi \NESW@false \ifN@\ifE@\NESW@true\fi\else\ifE@\else\NESW@true\fi\fi % % compute shaft char info with help of \lams@slope macro \ifH@\else\ifV@\else \lams@slope \ifnum\lams@tani>\lams@tanii \lams@ht\ten@\p@\lams@wd\ten@\p@ \multiply\lams@wd\lams@tanii\divide\lams@wd\lams@tani \else \lams@wd\ten@\p@\lams@ht\ten@\p@ \divide\lams@ht\lams@tanii\multiply\lams@ht\lams@tani \fi \fi\fi %%%%%%%%%%%%%%%%% BEGIN disable % % % % adjust arrow placement for source and target style % \ifH@\else\ifV@\else % \ifnum\lams@target=\thr@@ % \ifN@\advance\lams@lasty-.3\lams@ht % \else\advance\lams@lasty.3\lams@ht\fi % \fi % \ifnum\lams@source=\tw@ % \ifE@\advance\lams@firstx.3\lams@ht % \else\advance\lams@firstx-.3\lams@ht\fi % \fi % \ifnum\lams@target=12 % \ifN@\advance\lams@lasty-\lams@ht % \else\advance\lams@lasty\lams@ht\fi % \fi % \fi\fi %%%%%%%%%%%%%%%%% END disable % % draw arrow, special-casing horizontal and vertical ones \ifH@ \lams@harrow \else\ifV@ \lams@varrow \else \lams@darrow \fi\fi } \catcode`\@=\savecatcodeat \let\savecatcodeat\undefined