From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/ytableau/ytableau.dtx | 1616 ++++++++++++++++++++++++++++ 1 file changed, 1616 insertions(+) create mode 100644 macros/latex/contrib/ytableau/ytableau.dtx (limited to 'macros/latex/contrib/ytableau/ytableau.dtx') diff --git a/macros/latex/contrib/ytableau/ytableau.dtx b/macros/latex/contrib/ytableau/ytableau.dtx new file mode 100644 index 0000000000..25fb4ca5e6 --- /dev/null +++ b/macros/latex/contrib/ytableau/ytableau.dtx @@ -0,0 +1,1616 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010--2012 by Ryan Reich +% ------------------------------------------------------- +% +% This file may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.2 +% 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.2 or later is part of all distributions of LaTeX +% version 1999/12/01 or later. +% +% \fi +% +% \iffalse +%\NeedsTeXFormat{LaTeX2e} +%\ProvidesPackage{ytableau} +% [2012/08/14 v1.3 Many-featured Young tableaux and Young diagrams] +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{ytableau,amsmath,microtype,changepage} +\usepackage[numbered]{hypdoc} +\hypersetup{colorlinks,linkcolor=blue} + +\makeatletter +\def\DescribeOption{\leavevmode\@bsphack\begingroup\MakePrivateLetters + \Describe@Option} +\def\Describe@Option#1{\endgroup + \marginpar{\raggedleft\PrintDescribeOption{#1}}% + \SpecialOptionIndex{#1}\@esphack\ignorespaces} +\let\PrintDescribeOption=\PrintDescribeEnv +\def\option{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@YT} +\long\def\m@cro@YT#1{\endgroup \topsep\MacroTopsep \trivlist + \edef\saved@macroname{\string#1}% + \def\makelabel##1{\llap{##1}}% + \if@inlabel + \let\@tempa\@empty \count@\macro@cnt + \loop \ifnum\count@>\z@ + \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m@ne \repeat + \edef\makelabel##1{\llap{\vtop to\baselineskip + {\@tempa\hbox{##1}\vss}}}% + \advance \macro@cnt \@ne + \else \macro@cnt\@ne \fi + \edef\@tempa{\noexpand\item[% + \noexpand\PrintOptionName + {\string#1}]}% + \@tempa + \global\advance\c@CodelineNo\@ne + \SpecialMainOptionIndex{#1}\nobreak + \global\advance\c@CodelineNo\m@ne + \ignorespaces} +\let\endoption\endtrivlist +\let\PrintOptionName=\PrintEnvName +\newcommand*\SpecialOptionIndex[1]{% + \@bsphack + \begingroup + \HD@target + \let\HDorg@encapchar\encapchar + \edef\encapchar usage{% + \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage}% + }% + \index{#1\actualchar{\protect\ttfamily#1} (option)\encapchar usage}% + \index{options:\levelchar#1\actualchar{\protect\ttfamily#1}\encapchar usage}% + \endgroup + \@esphack +} +\def\SpecialMainOptionIndex#1{\@bsphack\special@index{% + #1\actualchar + {\string\ttfamily\space#1} + (option)% + \encapchar main}% + \special@index{options:\levelchar#1\actualchar{% + \string\ttfamily\space#1}\encapchar + main}\@esphack} +\makeatother + +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{ytableau.dtx} + \newlength{\newleftmargin} + \setlength{\newleftmargin}{\marginparwidth} + \addtolength{\newleftmargin}{-0.5in} + \newpage + \begin{adjustwidth}{-\newleftmargin}{-0.5in} + \PrintChanges + \newpage + \PrintIndex + \end{adjustwidth} +\end{document} +% +% \fi +% +% \CheckSum{580} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.0}{2010/11/04}{Initial version} +% +% \GetFileInfo{ytableau.sty} +% +% \DoNotIndex{\@firstoftwo,\@gobble,\eq@YTfalse,\eq@YTtrue} +% \DoNotIndex{\advance} +% \DoNotIndex{\bgroup,\box} +% \DoNotIndex{\cr,\crcr} +% \DoNotIndex{\def,\dimexpr,\dp} +% \DoNotIndex{\edef,\egroup,\else,\everycr,\expandafter} +% \DoNotIndex{\fbox,\fboxrule,\fboxsep,\fcolorbox,\fi} +% \DoNotIndex{\gdef,\global} +% \DoNotIndex{\halign,\hbox,\hss,\ht} +% \DoNotIndex{\iffalse,\ifnum,\ifx,\ignorespaces} +% \DoNotIndex{\kern} +% \DoNotIndex{\leavevmode,\let,\loop} +% \DoNotIndex{\newbox,\newcommand,\newcount,\newdimen,\newenvironment,\newif,\newtoks} +% \DoNotIndex{\offinterlineskip,\omit,\openup} +% \DoNotIndex{\pgfkeys,\pgfkeysalso,\ProcessPgfPackageOptions} +% \DoNotIndex{\raise,\relax,\repeat} +% \DoNotIndex{\scriptscriptstyle,\scriptsize,\scriptstyle,\setbox,\setlength} +% \DoNotIndex{\tabskip,\the} +% \DoNotIndex{\unexpanded,\unhbox,\unskip} +% \DoNotIndex{\vbox,\vcenter,\vrule,\vss,\vtop} +% \DoNotIndex{\wd} +% \DoNotIndex{\xdef} +% +% \title{The \textsf{ytableau} package\thanks{This document describes +% \textsf{ytableau}~\fileversion, dated~\filedate.}} +% \author{Ryan Reich\\\texttt{ryan.reich@gmail.com}} +% \date{August 14th, 2012} +% \maketitle +% +% \tableofcontents +%\pagebreak +% \noindent \textit{For Greta} +% +% \section{Y tableau?} +% +% At present there exist two packages with which one can draw Young tableaux: \textsf{young} and +% \textsf{youngtab}. As the latter is explicitly an alternative to the former, they do not overlap +% very much except in what they eventually produce. Between them, they define the following three +% basic constructions of Young tableaux: +% +% \begin{itemize} +% \item An environment with array-style syntax; +% +% \item A short-form macro; +% +% \item An even shorter-form macro for drawing Young diagrams (having nothing inside the boxes). +% \end{itemize} +% +% In this package we also implement these methods. However, we aim to take them as far as possible +% so that the conceivable needs of a mathematician making serious use of Young tableaux can be met +% with as little effort as possible on their part (and, thus, great effort on the part of this +% author). In writing this package we pursued the following major goals: +% +% \begin{itemize} +% \item The syntax should be as convenient as possible. The \textsf{young} package makes +% unfortunate use of the |\cr| delimiter for lines in an array, which is nowhere to be seen in +% modern \LaTeX\ and is likely unfamiliar to casual, young writers. The \textsf{youngtab} package +% requires the author to define individual, separate macros to draw items requiring more than one +% token to represent in \TeX. That is, if a cell of a tableau is to contain the expression $n + +% 1$, then one must place it into an auxiliary macro. Also, the same command, |\young|, delimits +% its contents with parentheses |(...)| rather than braces |{...}|. +% +% \item The package should make no assumptions about the intentions of the user. In particular, +% esoteric constructions such as skew tableaux and disconnected tableaux are not in principle any +% more difficult to draw, and should be no more difficult to write. +% +% \item Tableaux should support totally arbitrary decoration. We took this to mean that they +% should be easily colored; this possibility allows the depiction of tableaux within tableaux, an +% application which was specifically requested of the author (and was the original reason for +% writing this package). +% +% \item Configuration should be easy and plentiful. The \textsf{young} package has none, while +% \textsf{youngtab} package uses a strange syntax. Now that \textsf{keyval} is available there is +% no excuse for not providing a keyword-driven user interface to options controlling all aspects of +% the appearance of tableaux. +% +% \item Interoperability with all the common environments. In particular, since this is a +% mathematics package, it should work properly in the AMS environments, and since it is an +% array-based package it should work properly in array environments. +% \end{itemize} +% +% We believe the package achieves all these things. There should be nothing that one would want to +% do with Young tableaux that cannot be accomplished in the obvious way using the commands given +% below. +% +% \section*{Requirements} +% This package is quite self-contained and I have tried to avoid pulling in +% very large prerequisites. It includes \textsf{pgfkeys}, \textsf{pgfopts}, and +% \textsf{xcolor}, and specifically requires version 2 (2011/06/02) of +% \textsf{pgfopts}; this is enforced in the code. +% +% \section{User commands} +% \label{s:user commands} +% +% We provide three commands for drawing Young tableaux and diagrams. Each one is convenient for +% slightly different purposes and each supports various operations more or less easily than the +% others. +% +% \subsection{The \texttt{ytableau} environment} +% \label{ss:the ytableau environment} +% +% \DescribeEnv{ytableau} +% The |ytableau| environment is the core drawing engine for this package. It may be called as +% follows (similarly to \textsf{young}): +% +% \bigskip\noindent +% \quad |\begin{ytableau}|\oarg{general formatting} +% +% \smallskip\noindent +% \qquad \meta{entry} |&| |*|\parg{color name} \meta{entry} |& ... \\| +% +% \smallskip\noindent +% \qquad |...| +% +% \smallskip\noindent +% \quad |\end{ytableau}| +% +% \bigskip\noindent +% The result is an array of boxes separated by lines of width |0.4pt| (not tunable, and not affected +% by outside influences), each containing the entries specified in the environment. +% +% Each \meta{entry} is typeset in math mode (by default, but text mode is possible) and the entries +% are horizontally and (mostly) vertically +% centered in their box. In fact, the entries are treated as though they consist of a single line +% of text, and the baselines of all the entries in a row are aligned with each other for a +% consistent appearance (but see the options). + +% The environment may appear in or out of math mode without any ill effect +% (and without any effect on the contents). However, it \emph{is} affected by the ambient font +% size: in |\Huge| text the entire tableau is correspondingly Huge, at least as long as you are +% careful to specify the box size in |em| or |ex| units, rather than invariant ones like |pt|. +% +% \DescribeMacro{\none} +% An entry may be omitted by writing |\none|, which prevents the drawing of a frame but places an +% invisible box of the correct dimension inside the entry. Thus, one may create a tableau +% ``starting'' at an offset or even a ``tableau'' consisting of several disconnected regions. One +% can actually get things into these ``empty'' boxes by passing an optional argument to |\none|. +% +% The \meta{color name} can be any color name familiar to the package \textsf{xcolor}, or (of +% course) user-defined. The background of this box will be drawn in that color; by default, if no +% color is given the background is \emph{transparent}, which probably means white, unless the +% tableau is somehow overlaid on something else (see \ref{ss:chaining}). +% +% The \meta{general formatting} is simply \TeX\ material which is placed in front of each +% \meta{entry}. It can also contain a \meta{color name}, which is overridden by those specified +% individually. +% +% \subsection{The \texttt{ytableaushort} command} +% \label{ss:the ytableaushort command} +% +% \DescribeMacro{\ytableaushort} +% This command (however ironically named) allows inline specification of a tableau: +% +% \bigskip\noindent +% \quad |\ytableaushort| \oarg{general formatting} |{|\meta{line}|,|\meta{line}|,...}| +% +% \bigskip\noindent +% where \meta{general formatting} is as before, and each \meta{line} is a sequence of tokens +% representing entries in the tableau, similarly to \textsf{youngtab}. However, it is possible to +% include complex entries by surrounding them in |{...}|. This command internally reduces its +% functioning to |ytableau|, so the entries may contain colors and in general behave exactly as +% described above. +% +% \subsection{The \texttt{ydiagram} command} +% \label{ss:the ydiagram command} +% +% \DescribeMacro{\ydiagram} +% This command draws Young diagrams somewhat in the manner of \textsf{youngtab}: +% +% \bigskip\noindent +% \quad |\ydiagram| \oarg{general formatting} |{[|\meta{offset}| +]|\meta{number}|,...}| +% +% \bigskip\noindent +% producing an array of \emph{identical} boxes (empty by default), each row having \meta{number} in +% it with \meta{offset} blank boxes preceding (\meta{offset} is optional but, when provided, is not +% written with |[...]|. Thus, a typical invocation might be +% \begin{center} +% |\ydiagram{2 + 1, 3, 1}|. +% \end{center} +% Both \meta{offset} and \meta{number} may be any +% \TeX\ expressions evaluating to the textual representation of a number, including zero (e.g.\ 6 or +% |\thecountername|, but not just |\countername|). The boxes can be colored or filled with a single +% expression by means of \meta{general formatting}. +% +% \subsection{Chaining} +% \label{ss:chaining} +% +% The coloring facility for |\ydiagram| is not very interesting as-is. Thus, the package allows for +% the augmentation of several diagrams in the following manner: +% +% \bigskip\noindent +% \quad |\ydiagram| \meta{arguments} |*| \meta{arguments} |* ...| +% +% \bigskip\noindent +% produces a \emph{single} Young diagram obtained by layering the ones specified by the various +% \meta{arguments} from left (on top) to right (at the bottom). In fact, one can even write +% +% \bigskip\noindent +% \quad |\ytableaushort| \meta{tableau arguments} |*| \meta{diagram arguments} |* ...| +% +% \bigskip\noindent +% where first a Young tableau is constructed according to the initial set of arguments, then all +% subsequent arguments are passed to |\ydiagram|, with the result layered from left to right. This +% allows the construction of arbitrary color patterns with arbitrary contents. +% +% This operation is not possible with |\begin{ytableau}...\end{ytableau}| since the +% |\end| command obscures the following text from the internally-called |\endytableau| command. If +% you want to chain a |ytableau|, instead write it in the \TeX\ style |\ytableau...\endytableau|. +% Unfortunately it is not possible to work around this. +% +% \section{Package options} +% The package accepts the following options: +% \begin{itemize} +% \item \DescribeOption{boxsize} +% |boxsize|=\meta{dimension}. This manually sets the height (and width, which is the same) +% of boxes in all tableaux to \meta{dimension}. If you change the size and want to get back to +% the default (1.5em), just say |boxsize = normal|. +% +% \item \DescribeOption{smalltableaux} \DescribeOption{nosmalltableaux} +% |smalltableaux|/|nosmalltableaux|. The first option makes the box size quite small; +% indeed, just small enough to fit a |$($| precisely. It also passes |\scriptstyle| +% to each box, which as usual can be overridden if you wish (but you +% don't). The second option returns things to how they were, as do |smalltableaux=false| and |smalltableaux=off|. +% +% \item \DescribeOption{aligntableaux} \DescribeOption{centertableaux} +% \DescribeOption{nocentertableaux} +% |aligntableaux|=\meta{alignment}/|centertableaux|/|nocentertableaux|. The first argument +% allows any of |top|, |center|, or |bottom|. With |top|, the tableaux are all aligned on the +% baseline of their top row, with |bottom| they are aligned on the baseline of their bottom row, +% and |center| centers them (they correspond to |\vtop|, |\vbox|, and |\vcenter|). The other two +% arguments are semantically pleasing shorthand for |aligntableaux = center| and +% |aligntableaux = top|. +% +% \item \DescribeOption{textmode} \DescribeOption{mathmode} +% |textmode|/|mathmode|. The former sets all the boxes in text mode, and the latter returns +% to math mode (the default). +% +% \item \DescribeOption{baseline} \DescribeOption{nobaseline} \DescribeOption{centerboxes} +% |baseline|/|nobaseline|/|centerboxes|. The former, which is the default, aligns the +% entries of each box so that they share a common baseline, like normal text (but +% are otherwise centered). The latter (which are synonyms) center them vertically and +% independently of each other. Use |nobaseline| for tableaux with numbers, but |baseline| for +% anything else, particularly anything with some depth. + +% \item \DescribeOption{tabloids} \DescribeOption{notabloids} +% |tabloids|/|notabloids|. The former switches off drawing the vertical edges +% in a tableau, producing a ``tabloid''; the latter (the default) switches them +% back on. Syntax such as |tabloids = off| or |tabloids = true| is allowed. +% \end{itemize} +% It may not be useful to set these options globally, so we provide a macro for changing each of +% these parameters ``on the fly'': +% +% \DescribeMacro{\ytableausetup} +% Takes all of the above options and acts on them, setting parameters for all subsequent +% tableaux. The assignments are global with respect to \TeX\ nestings. +% +% \section{Samples} +% +% Note that the option settings are persistent. +% \subsection{Standard Young tableaux} +% \begin{center} +% \ytableausetup{centertableaux} +% \begin{ytableau} +% a & d & f \\ +% b & e & g \\ +% c +% \end{ytableau} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup{centertableaux} +% \begin{ytableau} +% a & d & f \\ +% b & e & g \\ +% c +% \end{ytableau} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ytableausetup{textmode} +% \begin{ytableau} +% a & d & f \\ +% b & e & g \\ +% c +% \end{ytableau} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup{textmode} +% \begin{ytableau} +% a & d & f \\ +% b & e & g \\ +% c +% \end{ytableau} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ytableausetup +% {mathmode, boxsize=2em} +% \begin{ytableau} +% 1 & 2 & 3 & \none[\dots] & \scriptstyle 2n-1 & 2n \\ +% 2 & 3 & 4 & \none[\dots] & 2n \\ +% \none[\vdots] & \none[\vdots] & \none[\vdots] \\ +% \scriptstyle 2n - 1 & 2n \\ +% 2n +% \end{ytableau} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup +% {mathmode, boxsize=2em} +% \begin{ytableau} +% 1 & 2 & 3 & \none[\dots] +% & \scriptstyle 2n - 1 & 2n \\ +% 2 & 3 & 4 & \none[\dots] +% & 2n \\ +% \none[\vdots] & \none[\vdots] +% & \none[\vdots] \\ +% \scriptstyle 2n - 1 & 2n \\ +% 2n +% \end{ytableau} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ytableausetup +% {boxsize=normal,tabloids} +% \ytableaushort{ +% 123, 45, 6 +% } +% \hfill +% \ytableaushort{ +% 1\none3, 45, 6 +% } +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup +% {boxsize=normal,tabloids} +% \ytableaushort{ +% 123, 45, 6 +% } +% \hfill +% \ytableaushort{ +% \none 23, 45, 6 +% } +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \subsection{Skew tableaux} +% +% \begin{center} +% \ytableausetup{notabloids} +% \begin{ytableau} +% \none & \none & 1 & 2 \\ +% \none & 1 & 2 \\ +% 1 & 2 \\ +% 2 +% \end{ytableau} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup{notabloids} +% \begin{ytableau} +% \none & \none & 1 & 2 \\ +% \none & 1 & 2 \\ +% 1 & 2 \\ +% 2 +% \end{ytableau} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ytableausetup{smalltableaux} +% \ytableaushort{ +% \none\none 12, +% \none 12, +% 12, +% 2} +% \hfill +% \ytableausetup{nobaseline} +% \ytableaushort{ +% \none\none 12, +% \none 12, +% 12, +% 2} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup{smalltableaux} +% \ytableaushort{ +% \none\none12,\none12,12,2} +% \ytableausetup{nobaseline} +% \ytableaushort{ +% \none\none12,\none12,12,2} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ydiagram{2+2,1+2,2,1} +% \hfill +% \ydiagram{2+2,0,0+2,1} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ydiagram{2+2,1+2,2,1} +% \ydiagram{2+2,0,0+2,1} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \subsection{Color and chaining} +% +% \begin{center} +% \ytableausetup{nosmalltableaux,nobaseline} +% \begin{ytableau} +% *(red) 1 & *(red) 3 & *(red) 5 \\ +% *(blue) 2 & *(blue) 4 \\ +% *(blue) 6 +% \end{ytableau} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup{nosmalltableaux} +% \begin{ytableau} +% *(red) 1& *(red) 3 &*(red) 5 \\ +% *(blue) 2 & *(blue) 4 \\ +% *(blue) 6 +% \end{ytableau} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ytableausetup{baseline} +% \ytableaushort[*(green) x_] +% {135,{*(white)2}4,6} +% \hfill +% {\Large +% \ytableaushort[*(green) x_] +% {135,{*(white)2}4,6} +% } +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup{baseline} +% \ytableaushort[*(green) x_] +% {135,{*(white)2}4,6} +% {\Large +% \ytableaushort[*(green) x_] +% {135,{*(white)2}4,6} +% } +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \begin{minipage}{0.4\textwidth} +% \begin{multline} +% \ytableausetup{boxsize=1.25em} +% \ytableausetup +% {aligntableaux=top} +% \ytableaushort[x_]{135,24,6} +% + \ydiagram[*(red) ]{3} \\ +% + \ydiagram[*(blue)]{3,2,1} +% = \ytableaushort[x_]{135,24,6} +% *[*(red)]{3} *[*(blue)]{3,2,1} +% \end{multline} +% \end{minipage} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \begin{multline} +% \ytableausetup +% {boxsize=1.25em} +% \ytableausetup +% {aligntableaux=top} +% \ytableaushort[x_]{135,24,6} +% + \ydiagram[*(red) ]{3} \\ +% + \ydiagram[*(blue)]{3,2,1} +% = \ytableaushort[x_]{135,24,6} +% *[*(red)]{3} *[*(blue)]{3,2,1} +% \end{multline} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ytableausetup{centertableaux} +% \ytableaushort +% {\none,\none ab, \none c} +% * {4,3,2,1} +% * [*(yellow)]{4,1,1,1} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ytableausetup{centertableaux} +% \ytableaushort +% {\none,\none ab, \none c} +% * {4,3,2,1} +% * [*(yellow)]{4,1,1,1} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \begin{center} +% \ydiagram[*(white) \bullet] +% {3+2,3+1,2,2} +% *[*(green)]{5,4,3,2,1} +% \hfill +% \begin{minipage}{0.5\textwidth} +% \begin{verbatim} +% \ydiagram[*(white) \bullet] +% {3+2,3+1,2,2} +% *[*(green)]{5,4,3,2,1} +% \end{verbatim} +% \end{minipage} +% \end{center} +% +% \StopEventually{} +% \newpage +% \section{The Code} +% \changes{v1.1}{2011/01/31}{Changed the namespace convention from \texttt{ytableau@...} to \texttt{...@YT} to make the index useful and the macros shorter.} +% \changes{v1.2}{2012/06/17}{Removed a lot of pointless endline-comments after control sequences and added spaces after numbers.} +% \changes{v1.2}{2012/06/17}{Fixed a bug where the prevailing font size was ignored or imperfectly obeyed.} +% \changes{v1.3}{2012/08/14}{Require sufficiently new \textsf{pgfopts} since v.1 breaks.} +% +% \subsection{Global defintions} +% +% Here are all the registers set and ``variables'' used. +% +% \subsubsection{Box registers} +% +% \begin{macro}{\tableaux@YT} +% When chaining, collects the successive tableaux. +% \begin{macro}{\thistableau@YT} +% When chaining, stores the current tableau in the chain. +% \\ +% Used in |\endytableau|. +% \begin{macrocode} +\newbox\tableaux@YT +\newbox\thistableau@YT +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\thisbox@YT} +% \changes{v1.1}{2011/01/31}{Made \texttt{\textbackslash thisbox@YT} an alias for \texttt{\textbackslash thistableau@YT}.} +% Stores the box currently being constructed. We define it as an alias because it is local to the construction of |\thistableau@YT| and, afterwards, irrelevant. Used in |\startbox@@YT| and |\endbox@YT|. +% \begin{macrocode} +\let\thisbox@YT=\thistableau@YT +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\refhtdp@YT} +% \changes{v1.1}{2011/01/31}{Put the reference letters into a single box and renamed it more semantically.} +% \changes{v1.2}{2012/06/17}{Moved definition to \texttt{\textbackslash ytableau}} +% Box that holds the reference-height and -depth character, which should be a math-mode parenthesis. This is set in |\ytableau| and used in option |smalltableaux| and in |\endbox@YT|. +% \begin{macrocode} +\newbox\refhtdp@YT +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Token registers} +% +% \begin{macro}{\toks@YT} +% Accumulates what will be put in the |ytableau| environment. +% Used in |\ydiagram|, |\getnumbers@YT|, +% |\getentries@@YT|, |\loop@YT|, and |\ytableaushort|. +% \begin{macrocode} +\newtoks\toks@YT +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\opttoksa@YT} +% \begin{macro}{\opttoksb@YT} +% Store the optional arguments (minus color specifications) when processing each entry of the +% tableau. Also used as temporary token registers. +% Used in |\startbox@YT|, |\getline@YT|. +% \begin{macrocode} +\newtoks\opttoksa@YT +\newtoks\opttoksb@YT +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Dimension registers} +% +% \begin{macro}{\boxdim@YT} +% The size of the boxes in a tableau. +% Used in |\ytableau|, |\startbox@@YT|, |\endbox@YT|. +% \begin{macrocode} +\newdimen\boxdim@YT +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tableauwd@YT} +% Save the total width of a tableau for supporting the ``chaining'' operation. Used in +% |\endytableau|. +% \begin{macrocode} +\newdimen\tableauwd@YT +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Count registers} +% +% \begin{macro}{\count@YT} +% Just a counter for looping. +% Used in |\loop@YT|, |\fullexpand@YT|. +% \begin{macrocode} +\newcount\count@YT +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Macros} +% +% \begin{macro}{\ifstar@YT} +% Fix a bug with |amsmath| where |\@ifnextchar| (used in |\@ifstar|) doesn't ignore spaces. +% \begin{macrocode} +\def\ifstar@YT#1{\kernel@ifnextchar *{\@firstoftwo{#1}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\expandonce@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% This is a substitute for using all of \textsf{etoolbox}. It operates on one token. +% \begin{macrocode} +\def\expandonce@YT#1{% + \expandafter\unexpanded\expandafter{#1}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\nil@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% A useful marker; it is equal to itself both as text and as a macro. +% \begin{macrocode} +\def\nil@YT{\nil@YT} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\boxframe@YT} +% \changes{v1.2}{2012/06/17}{Made a macro.} +% The font-independent width of the frame in a tableau. Used in |\ytableau| and |\none@YT|. +% \begin{macrocode} +\def\boxframe@YT{0.04em} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\boxdim@normal@YT} +% \changes{v1.2}{2012/06/17}{Made a macro.} +% \begin{macro}{\boxdim@save@YT} +% \changes{v1.2}{2012/06/17}{Made a macro.} +% Respectively, the font-independent "normal" box size and the previously used size when using the option pair |smalltableaux|, |nosmalltableaux|. +% Used in options |boxsize|, |smalltableaux|, |nosmalltableaux|. +% \begin{macrocode} +\def\boxdim@normal@YT{1.5em} +\let\boxdim@save@YT = \boxdim@normal@YT +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\macro@boxdim@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% The font-independent dimension of a tableau box. Sometimes is a |\dimexpr|. Used in options |boxsize|, |smalltableaux|, |nosmalltableaux|, and in |\ytableau|. +% \begin{macrocode} +\edef\macro@boxdim@YT{\boxdim@normal@YT} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\hrule@normal@YT} +% \begin{macro}{\vrule@normal@YT} +% |\hrule| and |\vrule| for drawing the frames around tableau cells. The +% vertical ones are a little shorter to produce a small overlap that eliminates +% gaps at the corners without producing anti-gaps in the hinting at the edges. +% I am basically copying the idea from \textsf{xcolor}'s |\boxframe|. +% \begin{macrocode} +\def\hrule@normal@YT{% + \hrule width \dimexpr \boxdim@YT + \fboxrule * 2\relax + height \fboxrule +} +\def\vrule@normal@YT{% + \vrule height \dimexpr \boxdim@YT + \fboxrule\relax + width \fboxrule +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\hrule@none@YT} +% \begin{macro}{\vrule@none@YT} +% Fake rules for |\none| to give the correct spacing. +% \begin{macrocode} +\def\hrule@none@YT{\kern\fboxrule} +\def\vrule@none@YT{% + \vrule width 0pt + height \dimexpr \boxdim@YT + \fboxrule\relax + \kern\fboxrule +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\font@YT} +% \changes{v1.2}{2012/06/17}{Changed name from \texttt{\textbackslash defarg@YT}.} +% This is the font style of everything in a tableau box. By default, it is normal. +% Used in option |smalltableaux|. +% \begin{macrocode} +\def\font@YT{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\skipin@YT} +% \begin{macro}{\skipout@YT} +% \changes{v1.1}{2011/01/31}{Split up the ``skip in'' and ``skip out'' macros.} +% Stores the delimiter for text mode or math mode which absorbs spaces around the contents of a box. +% \begin{macro}{\smallfont@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% The font style for the |smalltableaux| option. It depends on math or text mode. +% \begin{macro}{\set@mathmode@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% This sets up the tableau boxes to typeset in math mode. +% \begin{macrocode} +\def\set@mathmode@YT{% + \gdef\skipin@YT{$}% + \gdef\skipout@YT{$}% + \def\smallfont@YT{\scriptstyle}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\set@textmode@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% This sets up the tableau boxes to typset in text mode. +% In text mode, the |skipout| macro has to |\unskip| prior spaces, while the |skipin| macro has to ignore following ones. +% \begin{macrocode} +\def\set@textmode@YT{% + \gdef\skipin@YT{\ignorespaces}% + \gdef\skipout@YT{\unskip}% + \def\smallfont@YT{\scriptsize}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% The default is math mode. +% \begin{macrocode} +\set@mathmode@YT +% \end{macrocode} +% +% \begin{macro}{\thisboxcolor@YT} +% Stores the color of the current box in a tableau. The color |clear| is not recognized by +% |xcolor| but denotes for us a transparent box. +% Used in |\getcolor@@YT| and |\endbox@YT|. +% \begin{macrocode} +\def\thisboxcolor@YT{clear} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\centering@YT} +% What kind of vertical alignment our tableaux will have. +% Used in |\ytableau| and options |aligntableaux|, |centertableaux|, |nocentertableaux|. +% \begin{macrocode} +\def\centering@YT{top} +% \end{macrocode} +% \end{macro} +% +% \changes{v1.1}{2011/01/31}{Removed null initializations of temp macros \texttt{\textbackslash tmp(a,b,c)@YT}.} +% +% \begin{macro}{\compare@YT} +% Compares two strings. Neither of them should be hidden in macros; i.e.\ it compares exactly what +% is given. +% Used in options |boxsize| and |aligntableaux| as well as in |\getline@@YT|, +% |\getentries@@YT|, |\loop@YT|, and |\getnumbers@YT|. +% \begin{macro}{\compare@@YT} +% Compares two strings, where the first is hidden in one layer of macros. Used in |\endytableau|, +% |\fcolorbox@YT|. +% \begin{macro}{\ifeq@YT} +% Tests the result of |\compare@YT(@)|. +% \begin{macrocode} +\def\compare@YT#1#2{% + \def\tmpa@YT{#1}\def\tmpb@YT{#2}% + \ifx\tmpa@YT\tmpb@YT + \global\eq@YTtrue + \else + \global\eq@YTfalse + \fi +} +\def\compare@@YT#1#2{% + \def\tmpb@YT{#2}% + \ifx#1\tmpb@YT + \global\eq@YTtrue + \else + \global\eq@YTfalse + \fi +} +\newif\ifeq@YT +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Options} +% \changes{v1.2}{2012/06/17}{Added an option \texttt{baseline} to fix an irritating irregularity in some tableaux.} +% \changes{v1.2}{2012/06/17}{Switched from using \textsf{xkeyval} to \textsf{pgfkeys}.} +% +% We include \textsf{pgfkeys} to support various options. +% \begin{macrocode} +\RequirePackage{pgfkeys} +\pgfkeys{/ytableau/options/.is family} +% \end{macrocode} +% +% \begin{macro}{\ytableausetup} +% The user interface to options once the document is in progress. +% \end{macro} +% \begin{macrocode} +\newcommand{\ytableausetup}[1]{\pgfkeys{/ytableau/options,#1}} +\pgfkeys{/ytableau/options, +% \end{macrocode} +% \begin{option}{boxsize} +% Box size. Takes a dimension or |normal|. +% \end{option} +% \begin{macrocode} + boxsize/.value required, + boxsize/.code = {% +% \end{macrocode} +% Make tableaux un-small before changing the box size, even if the user wants to go smaller, +% because there is also the issue of |\font@YT| being set, and it is only ever changed in +% that option. +% \begin{macrocode} + \pgfkeysalso{nosmalltableaux}% + \compare@YT{#1}{normal}% + \ifeq@YT + \xdef\macro@boxdim@YT{\expandonce@YT\boxdim@normal@YT}% + \else + \xdef\macro@boxdim@YT{#1}% + \fi + } +} +\pgfkeys{/ytableau/options, +% \end{macrocode} +% \begin{option}{aligntableaux} +% Most general alignment option, can be any of |top|, |center|, or |bottom|. +% \end{option} +% \begin{macrocode} + aligntableaux/.value required, + aligntableaux/.is choice, + aligntableaux/top/.code = {\gdef\centering@YT{top}}, + aligntableaux/center/.code = {\gdef\centering@YT{center}}, + aligntableaux/bottom/.code = {\gdef\centering@YT{bottom}}, +% \end{macrocode} +% \begin{option}{centertableaux} +% |centertableaux| is |aligntableaux = center|. +% \end{option} +% \begin{macrocode} + centertableaux/.value forbidden, + centertableaux/.style = {aligntableaux/center}, +% \end{macrocode} +% \begin{option}{nocentertableaux} +% |nocentertableaux| is |aligntableaux = top|. +% \end{option} +% \begin{macrocode} + nocentertableaux/.value forbidden, + nocentertableaux/.style = {aligntableaux/top} +} +% \end{macrocode} +% +% \changes{v1.2}{2012/06/17}{Fixed a bug in \texttt{textmode} and \texttt{smalltableaux} where \texttt{\textbackslash scriptstyle} was used outside of math mode.} +% \begin{macro}{\ifsmalltableaux@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% This conditional tracks whether we are operating under the option |smalltableaux|. +% \end{macro} +% \begin{macrocode} +\newif\ifsmalltableaux@YT +\pgfkeys{/ytableau/options, +% \end{macrocode} +% \begin{option}{smalltableaux} +% Small tableaux: reduce the box size and the text size. +% \begin{macrocode} + smalltableaux/.default = true, + smalltableaux/.is choice, + smalltableaux/true/.code = {% +% \end{macrocode} +% We check whether we are ``in'' small tableaux; this prevents double-calling the option. Even if the user is not so malicious, this can (does) happen in the \textsf{amsmath} display environments. +% \begin{macrocode} + \ifsmalltableaux@YT\else + \global\smalltableaux@YTtrue + \gdef\font@YT{\smallfont@YT}% +% \end{macrocode} +% We expand once here and later so that |\macro@boxdim@YT| can be evaluated lazily. +% \begin{macrocode} + \xdef\boxdim@save@YT{\expandonce@YT\macro@boxdim@YT}% +% \end{macrocode} +% This one must be a |\def| rather than an |\edef| because |\refhtdp@YT| is not set until later. +% \begin{macrocode} + \gdef\macro@boxdim@YT{% + \dimexpr \ht\refhtdp@YT + \dp\refhtdp@YT + 0.1em\relax + } + \fi + }, + smalltableaux/false/.code = {% + \ifsmalltableaux@YT + \global\smalltableaux@YTfalse + \gdef\font@YT{}% + \xdef\macro@boxdim@YT{\expandonce@YT\boxdim@save@YT}% + \fi + }, + smalltableaux/on/.style = {smalltableaux/true}, + smalltableaux/off/.style = {smalltableaux/false}, +% \end{macrocode} +% \end{option} +% \begin{option}{nosmalltableaux} +% \changes{v1.1}{2011/01/31}{Correctly reassign a positive value to \texttt{\textbackslash boxdim@save@YT} when exiting small tableaux.} +% |nosmalltableaux| resets everything to the way it was before |smalltableaux| was passed. +% \begin{macrocode} + nosmalltableaux/.value forbidden, + nosmalltableaux/.style = {smalltableaux/false} +% \end{macrocode} +% \end{option} +% \begin{macrocode} +} +\pgfkeys{/ytableau/options, +% \end{macrocode} +% \begin{option}{textmode} +% Requests that the boxes in tableaux be typeset in text mode rather than the default math mode. +% \begin{macrocode} + textmode/.value forbidden, + textmode/.code = \set@textmode@YT, +% \end{macrocode} +% \end{option} +% \begin{option}{mathmode} +% The inverse of |textmode|. +% \end{option} +% \begin{macrocode} + mathmode/.value forbidden, + mathmode/.code = \set@mathmode@YT, +} +% \end{macrocode} +% +% \begin{macro}{\ifbaseline@YT} +% \changes{v1.2}{2012/06/17}{Added.} +% Whether or not to create a baseline in the tableau boxes. +% \begin{macrocode} +\newif\ifbaseline@YT +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\pgfkeys{/ytableau/options, +% \end{macrocode} +% \begin{option}{baseline} +% \changes{v1.2}{2012/06/17}{Added option.} +% Switches whether the cells of the tableau should have their sizes normalized (and thus establish a common baseline in each row). Enabling it (the default) improves the appearance of text and symbols. +% \begin{macrocode} + baseline/.is if = baseline@YT, + baseline/.default = true, +% \end{macrocode} +% \end{option} +% \begin{option}{nobaseline} +% \changes{v1.2}{2012/06/17}{Added option.} +% Synonymous with |baseline = false|. Improves the appearance of tableaux with numbers in their cells. +% \begin{macrocode} + nobaseline/.style = {baseline = false}, +% \end{macrocode} +% \end{option} +% \begin{option}{centerboxes} +% \changes{v1.2}{2012/06/17}{Added option.} +% Synonymous with |baseline = false|. +% \end{option} +% \begin{macrocode} + centerboxes/.style = {baseline = false}, +} +\pgfkeys{/ytableau/options, +% \end{macrocode} +% \begin{option}{tabloids} +% \changes{v1.3}{2012/08/14}{Added option.} +% Causes the vertical lines of a tableau to be omitted. +% \end{option} +% \begin{macrocode} + tabloids/.default = true, + tabloids/.is choice, + tabloids/true/.code = {% + \global\let\vrule@YT=\vrule@none@YT + \global\let\hrule@YT=\hrule@normal@YT + }, + tabloids/false/.code = {% + \global\let\vrule@YT=\vrule@normal@YT + \global\let\hrule@YT=\hrule@normal@YT + }, + tabloids/on/.style = {tabloids/true}, + tabloids/off/.style = {tabloids/false}, + notabloids/.style = {tabloids/false}, +} +% \end{macrocode} +% +% \changes{v1.2}{2012/06/17}{No longer pass options to \textsf{xcolor}.} +% Process the options now. Then we load \textsf{xcolor}. +% \begin{macrocode} +\ytableausetup{nosmalltableaux,mathmode,baseline,notabloids} +\RequirePackage{pgfopts}[2011/06/02] +\ProcessPgfPackageOptions{/ytableau/options} +\RequirePackage{xcolor} +% \end{macrocode} +% +% \subsection{\texttt{ytableau} environment} +% \changes{v1.2}{2012/06/17}{Fixed a bug where the widths of the outer rules of the tableau were ignored.} +% +% \begin{environment}{ytableau} +% The core tableau-drawing environment. The first argument, which is optional, is just +% ``formatting'' pasted on to each entry. The contents are an |\halign|-style array; if an entry +% begins with |*|\parg{color}, then the background of that box is colored. +% \begin{macrocode} +\newenvironment{ytableau}[1][] +{% +% \end{macrocode} +% \changes{v1.1}{2010/11/10}{Removed an unnecessary layer of boxes and moved the fake braces into +% the outer layer.} +% Despite the alignment requirements, we set the tableau top-aligned so that it can be easily +% chained. This will get fixed before we print it, though. +% +% The point of the mysterious |\iffalse| is to produce a syntactically balanced pair of braces |{}| +% which semantically is equivalent to just an open brace |{|. This is required to support tableaux +% nested inside other alignments because |\halign| does not recognize |\bgroup|...|\egroup| as +% designating a nesting! (We will use this fact later, actually.) But we can't just write |{| and +% (in |\endytableau|) |}| either. +% \begin{macrocode} + \global\setbox\thistableau@YT=\vtop{\iffalse}\fi +% \end{macrocode} +% \begin{macro}{\none} +% \changes{v1.2}{2012/06/17}{Moved definition inside \texttt{\textbackslash ytableau}.} +% This one is for omitting entries but leaving their space. We also allow something to be placed +% in the empty space (e.g.\ |\dots|), but don't allow color (that would defeat the purpose of +% omitting the box). To support the optional argument without screwing up the |\omit|, we have to +% go in two steps. +% \begin{macrocode} + \def\none{\omit\none@YT} +% \end{macrocode} +% \end{macro} +% Now we set all the dimensions that depend on the font. +% \changes{v1.2}{2012/06/17}{Use \texttt{(} for \texttt{\textbackslash refhtdp@YT} rather than \texttt{$bg$}.} +% \begin{macrocode} + \setbox\refhtdp@YT=\hbox{\skipin@YT\font@YT (\skipout@YT}% + \boxdim@YT=\macro@boxdim@YT\relax + \fboxrule=\boxframe@YT\relax + \fboxsep=0pt % +% \end{macrocode} +% I hate |\cr|, let's use the \LaTeX\ convention. +% \begin{macrocode} + \let\\=\cr@YT +% \end{macrocode} +% Lines and columns should abut, accounting for the fact that each entry is framed. The first entry should not have any skip, since the first rule is not doubled. +% \begin{macrocode} + \tabskip=0pt % + \offinterlineskip + \openup-\fboxrule +% \end{macrocode} + % \changes{v1.1}{2010/11/10}{Added the everycr fix.} +% We have to make sure |\everycr| is empty or else strange things could happen (like in the +% \textsf{amsmath} environment |gather|). Thanks to Harald Hanche-Olsen for telling me about this. +% \begin{macrocode} + \everycr={}% +% \end{macrocode} +% Now we begin the |\halign|. Each entry is passed as an argument to our box-building function, +% but we can't just write something like |\box@YT{##}| because of the following complication: +% +% When TeX sees |\box@YT{|, it absorbs tokens up until the next unmatched |}| without +% interpreting them and then feeds that to the macro as |#1|. Unfortunately, we would like it to +% be possible to omit |\\| on the last line (as people are used to this, and Knuth provided for it +% with |\crcr|). But since |ytableau| is an environment, the ending of |\halign| is hidden in the +% macro |\endytableau| (or |\end{ytableau}|) which is \emph{not expanded by} |\halign| while +% reading for |##| in the proposed code. +% +% The workaround is to pretend that |##| is not an argument to a macro until we get deep inside +% |\startbox@YT|, where (after some processing) it is fed to an |\hbox| inside math mode. +% |\hbox| is not really a macro (it's a builtin) and it does interpret its contents as it reads +% them, and since we have finally set up the desired typesetting environment we can let it read +% |##| properly. Since we are \emph{still} inside an |\halign|, eventually it will expand +% |\endytableau| and |##| will terminate properly. Whew. +% \begin{macrocode} + \halign\bgroup&\tabskip=-\fboxrule + \startbox@YT{\font@YT}{#1}##\endbox@YT\cr +} +{% +% \end{macrocode} +% The |\crcr| supports the omission of |\\| in the last row. That's a pretty modest goal for all +% the work that went into thinking up this crazy scheme. +% \begin{macrocode} + \crcr\egroup + \iffalse{\fi}% +% \end{macrocode} +% Support for chaining. We allow |\endytableau| to be followed by |*[...]{...}|, which is fed to +% |\ydiagram| as-is. This only works in the short forms |\ytableaushort| and |\ydiagram|, since in +% |\end{ytableau}| there is extra code intervening before the following characters and no way to +% insert things in it. +% \changes{v1.1}{2010/11/10}{Save the box width difference rather than the larger width.} +% \begin{macrocode} + \ifnum\wd\thistableau@YT>\wd\tableaux@YT + \tableauwd@YT=\wd\thistableau@YT +% \end{macrocode} +% This prevents the last rule from being ignored, as it is not doubled. +% \begin{macrocode} + \advance\tableauwd@YT by \fboxrule + \wd\thistableau@YT = \tableauwd@YT + \advance\tableauwd@YT by -\wd\tableaux@YT + \else + \tableauwd@YT = 0pt % + \fi +% \end{macrocode} +% We have saved the larger width, but now |\thistableau@YT| must have width zero so that it +% can be overlaid with the existing tableaux. +% \changes{v1.1}{2010/11/10}{Replaced explicit setting of the chained box width by a kern.} +% \begin{macrocode} + \wd\thistableau@YT=0pt % + \setbox\tableaux@YT + =\hbox{\box\thistableau@YT\unhbox\tableaux@YT + \kern\tableauwd@YT}% + \ifstar@YT + {\ydiagram}% + {% +% \end{macrocode} +% \changes{v1.1}{2010/11/10}{Moved the leavevmode down to the output routine and simplified the alignment computations now that the everycr fix is in.} +% We adjust the vertical alignment finally and print the boxes. |\leavevmode| ensures that the +% tableau is treated in horizontal mode. You are on your own if you put this inside of another box. +% \begin{macrocode} + \leavevmode + \compare@@YT{\centering@YT}{center}% + \ifeq@YT + \hbox{$\vcenter{\box\tableaux@YT}$}% + \else\compare@@YT{\centering@YT}{bottom}% + \ifeq@YT + \hbox{\raise\dp\tableaux@YT\box\tableaux@YT}% + \fi + \box\tableaux@YT + \fi + }% +} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\cr@YT} +% Annoying to have to do this, but nested halign chokes when |\cr| appears inside the definition. +% \begin{macrocode} +\def\cr@YT{\cr} +% \end{macrocode} +% \end{macro} +% +% \changes{v1.2}{2012/06/17}{Fixed a bug in \texttt{\textbackslash none} where text outside the optional argument would be typeset off-grid.} +% \begin{macro}{\none@YT} +% This finds the optional argument to |\none| and makes the box itself. We draw an invisible frame +% by replacing the actual frame with the frame separation. We use |\nullfont| after the box +% so as to forbid any "out of alignment" characters, which would appear between columns. +% Anything outside of the optional argument is simply ignored to the end of the cell. +% \begin{macrocode} +\newcommand{\none@YT}[1][]{% + \def\thisboxcolor@YT{clear}% + \let\hrule@YT=\hrule@none@YT + \let\vrule@YT=\vrule@none@YT + \startbox@@YT#1\endbox@YT + \nullfont +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\startbox@YT} +% |#1| = font style, |#2| = optional material. +% We want to extract the colors from each and then pass the whole thing on to |\startbox@@YT|. +% \begin{macrocode} +\def\startbox@YT#1#2{% +% \end{macrocode} +% We get the colors and then put the rest into temporary token registers. +% \begin{macrocode} + \getcolor@YT{\save@YT{\opttoksa@YT}}#1\nil@YT + \getcolor@YT{\save@YT{\opttoksb@YT}}#2\nil@YT +% \end{macrocode} +% Now we get the color from the entry and proceed. +% \begin{macrocode} + \getcolor@YT + {\startbox@@YT\the\opttoksa@YT\the\opttoksb@YT}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\save@YT} +% Stick the following text into the token register in |#1|. Note that we use |\nil@YT| as an +% end-marker; it is not actually defined, so hopefully we never expand it! +% \begin{macrocode} +\def\save@YT#1#2\nil@YT{#1={#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getcolor@YT} +% |#1| is pasted in front of what remains after removing the color. Basically, it's a ``do next''. +% \begin{macrocode} +\def\getcolor@YT#1{\ifstar@YT{\getcolor@@YT{#1}}{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getcolor@@YT} +% Save the (optional) color argument and pass the rest to |\startbox@@YT|. +% \begin{macrocode} +\def\getcolor@@YT#1(#2){% + \def\thisboxcolor@YT{#2}% + #1% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\startbox@@YT} +% Start collecting the current entry into a horizontally-centered hbox, but save the result. +% \begin{macrocode} +\def\startbox@@YT{% +% \end{macrocode} +% Use a |\bgroup|...|\egroup| so as not to introduce nesting that would block |&| or |\cr|. +% \begin{macrocode} + \setbox\thisbox@YT=\hbox to \boxdim@YT\bgroup + \hss + \skipin@YT +} +% \end{macrocode} +% Since we are now in the intended typesetting context (i.e.\ an hbox with math mode on) +% we can let |\halign| expand tokens in the rest of the entry until it finds a |&| or |\cr| (= |\\|) +% \end{macro} +% +% \begin{macro}{\endbox@YT} +% Now we can finish the box and set it. +% \begin{macrocode} +\def\endbox@YT{% + \skipout@YT + \hss + \egroup +% \end{macrocode} +% We want all the boxes to have a consistent baseline, so we normalize them to +% the same size. Multiple text lines will be aligned with the baseline of the +% last line at the center, so this really only works well for single lines of +% text. +% \begin{macrocode} + \ifbaseline@YT + \ht\thisbox@YT=\ht\refhtdp@YT + \dp\thisbox@YT=\dp\refhtdp@YT + \fi +% \end{macrocode} +% The extra |\fboxrule| is to account for the margin on the vertical edges of +% the frame. +% \begin{macrocode} + \fcolorbox@YT{\thisboxcolor@YT}{% + \vbox to \dimexpr\boxdim@YT + \fboxrule\relax{\vss\box\thisbox@YT\vss}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fcolorbox@YT} +% \changes{v1.3}{2012/08/14}{Rewrote to draw the vertical and horizontal lines +% separately, so the \texttt{tabloids} option is possible.} +% We need a wrapper around |\colorbox| since it produces an opaque box, and +% sometimes, we want |clear|. We also have to draw the frame carefully. Note +% the order of the |\vbox| and the |\hbox|: it has to be that way, else |\none| +% gives a strange gap at the right edge in tabloids since the inner set of +% rules is shorter, and |\colorbox| does odd things inside a |\vbox|. +% +% |#1| = color, |#2| = contents +% \begin{macrocode} +\def\fcolorbox@YT#1#2{% +% \end{macrocode} +% This idea is again from \textsf{xcolor}. +% \begin{macrocode} + \lower\fboxrule\vbox{% + \ifodd\fboxrule\kern1sp \fi + \kern0.5\fboxrule + \hbox{% + \kern\fboxrule + \compare@@YT{#1}{clear}% + \ifeq@YT +% \end{macrocode} +% Clear background; don't draw anything. +% \begin{macrocode} + #2% + \else +% \end{macrocode} +% Colored background; pass it to |\colorbox|. +% \begin{macrocode} + \colorbox{#1}{#2}% + \fi + \rules@YT{v}% + }% + \kern-0.5\fboxrule + \rules@YT{h}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\rules@YT} +% \changes{v1.3}{2012/08/14}{Added.} +% Draws |\boxdim@YT|-spaced rules either |h|orizontally or |v|ertically. This +% is so that the entire frame can be drawn after the contents of a box. +% It is drawn \emph{before} the current location. +% \begin{macrocode} +\def\rules@YT#1{% + \expandafter\let\expandafter\rule@YT\csname #1rule@YT\endcsname + \kern-\dimexpr\boxdim@YT + \fboxrule\relax + \rule@YT + \kern\boxdim@YT + \rule@YT +} +% \end{macrocode} +% \end{macro} +% \subsection{\texttt{ytableaushort} command} +% \changes{v1.2}{2012/06/17}{Fixed a bug in \texttt{\textbackslash ytableaushort} where \texttt{\{,\}} was treated as a comma at the beginning of a line.} +% +% \begin{macro}{\ytableaushort} +% The short form of |ytableau|. It takes a comma-separated list of lines, each one a string of +% entries given as individual tokens. |{...}| is allowed (and encouraged) for complex entries, and +% color is possible. All sorts of redundancies in the syntax are allowed. +% \begin{macrocode} +\newcommand{\ytableaushort}[2][]{% +% \end{macrocode} +% |\endytableau| has to be right at the end, so we can't use scope to reset |\toks@YT|. +% \begin{macrocode} + \toks@YT={}% + \getentries@YT{\getentries@@YT}{}#2,\nil@YT + \ytableau[#1]\the\toks@YT\endytableau +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getentries@YT} +% Split the CSV into rows. This is really a job for |etoolbox:\docsvlist| but whatever. +% We put a |.| in front of the string so that a line may be enclosed entirely in |{...}| +% Otherwise, |\def\cs#1,{etc}| would make |#1| = |...| and not |#1| = |{...}| as we want. +% \begin{macrocode} +\def\getentries@YT#1#2{\getline@YT{#1}{#2}.} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getline@YT} +% Grab the first \meta{line}|,| in the string and remove the initial |.| +% \begin{macrocode} +\def\getline@YT#1#2#3,{% + \opttoksa@YT=\expandafter{\@gobble#3}% + \opttoksb@YT={\getline@@YT{#1}{#2}}% +% \end{macrocode} +% We pass |#3| back as an \emph{argument} to |\getline@@YT|, thus avoiding the braces issue. +% \begin{macrocode} + \edef\next@YT{\the\opttoksb@YT{\the\opttoksa@YT}}% +% \end{macrocode} +% We use |\futurelet| to check whether the next token is |\nil@YT| without breaking brace groups. +% \begin{macrocode} + \futurelet\tmpa@YT\next@YT +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getline@@YT} +% |#1| = the macro to process each row, +% |#2| = the junk to put after each row (followed by |\nil@YT|), +% |#3| = everything before the first comma. +% If this is not the last row, we have to recurse down the list. Otherwise, just process the +% current row. Multiple commas are ignored. +% \begin{macrocode} +\def\getline@@YT#1#2#3{% + \ifx\tmpa@YT\nil@YT + \compare@YT{#3}{}% + \ifeq@YT + \def\next@YT{\@gobble}% + \else + \def\next@YT{#1#3#2}% + \fi + \else + \compare@YT{#3}{}% + \ifeq@YT + \def\next@YT{\getline@YT{#1}{#2}.}% + \else + \def\next@YT{#1#3#2\nil@YT\getentries@YT{#1}{#2}}% + \fi + \fi + \next@YT +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getentries@@YT} +% Separates the entries in a line of |\ytableaushort| and reformats them for |\ytableau|. +% Takes two tokens and checks if the second is |\nil@YT|, which means the first is the last entry. +% \begin{macrocode} +\def\getentries@@YT#1#2{% +% \end{macrocode} +% If this is not the last entry, we have to recurse down the line. Otherwise, we just print |\\|. +% \begin{macrocode} + \compare@YT{#2}{\nil@YT}% + \ifeq@YT + \toks@YT=\expandafter{\the\toks@YT#1\\}% + \def\next@YT{}% + \else + \toks@YT=\expandafter{\the\toks@YT#1&}% + \def\next@YT{\getentries@@YT{#2}}% + \fi + \next@YT +} +% \end{macrocode} +% \end{macro} +% +% \subsection{\texttt{ydiagram} commmand} +% \changes{v1.2}{2012/06/17}{Fixed a bug where giving a line length of 0 in \texttt{\textbackslash ydiagram} did not draw an empty row, but rather ignored the row.} +% \changes{v1.2}{2012/06/17}{Removed \texttt{\textbackslash fullexpand@YT}.} +% +% \begin{macro}{\ydiagram} +% Takes the same optional argument as the other macros. Its main argument |#2| is of the form +% \\ +% \indent[\meta{offset} + ]\meta{number}, ... +% \\ +% where both \meta{offset} and \meta{number} may be any expression evaluating to a textual number +% (e.g.\ |\the\count|\meta{n} rather than |\count|\meta{n}). +% \begin{macrocode} +\newcommand\ydiagram[2][]{% +% \end{macrocode} +% We need |\endytableau| to be right at the end, so we can't use scope to reset |\toks@YT|. +% \begin{macrocode} + \toks@YT={}% + \getentries@YT{\getnumbers@YT}{+}#2,\nil@YT + \ytableau[#1]\the\toks@YT\endytableau +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getnumbers@YT} +% Separates the entries in a line of |\ydiagram| and reformats them for |\ytableau|. +% \begin{macrocode} +\def\getnumbers@YT#1+#2\nil@YT{% +% \end{macrocode} +% If |#2| = |{}|, then there is no offset and |#1| is the row shape. +% \begin{macrocode} + \compare@YT{#2}{}% + \ifeq@YT + \def\next@YT{% + \loop@YT{#1}{}% + }% +% \end{macrocode} +% Else |#1| is the offset and |#2| is the shape. +% \begin{macrocode} + \else + \def\next@YT{% + \loop@YT{#1}{\none}% +% \end{macrocode} +% Now |#2| looks like \meta{number}|+|, so we feed it back in. +% \begin{macrocode} + \getnumbers@YT#2\nil@YT + }% + \fi + \next@YT +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\loop@YT} +% Loops on the first argument, building a |\ytableau| line whose entries are the second argument. +% The results go in |\toks@YT|. +% \begin{macrocode} +\def\loop@YT#1#2{% + \count@YT=#1\relax + \loop\ifnum\count@YT>1 % + \toks@YT=\expandafter{\the\toks@YT#2&}% + \advance\count@YT by -1 % + \repeat +% \end{macrocode} +% The last entry in the list may not be the last entry in the line. If it's empty, it is (according +% to our usage), otherwise not. +% \begin{macrocode} + \ifnum\count@YT=1 % + \compare@YT{#2}{}% + \ifeq@YT + \toks@YT=\expandafter{\the\toks@YT#2\\}% + \else + \toks@YT=\expandafter{\the\toks@YT#2&}% + \fi + \else +% \end{macrocode} +% This supports using 0 as a number: it inserts an empty line, but only if it is the |+0| case, not the |0+| case. +% \begin{macrocode} + \compare@YT{#2}{}% + \ifeq@YT + \toks@YT=\expandafter{\the\toks@YT\none\\}% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \Finale -- cgit v1.2.3