summaryrefslogtreecommitdiff
path: root/macros/latex
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex')
-rw-r--r--macros/latex/contrib/atableau/LICENSE401
-rw-r--r--macros/latex/contrib/atableau/README.md45
-rw-r--r--macros/latex/contrib/atableau/atableau.ini13
-rw-r--r--macros/latex/contrib/atableau/atableau.pdfbin0 -> 840926 bytes
-rw-r--r--macros/latex/contrib/atableau/atableau.sty3335
-rw-r--r--macros/latex/contrib/atableau/atableau.tex4359
-rw-r--r--macros/latex/contrib/keytheorems/CHANGELOG.md5
-rw-r--r--macros/latex/contrib/keytheorems/README.md5
-rw-r--r--macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdfbin169165 -> 175459 bytes
-rw-r--r--macros/latex/contrib/keytheorems/doc/keytheorems-doc.tex73
-rw-r--r--macros/latex/contrib/keytheorems/tex/class-support/keythms-beamer-support.tex4
-rw-r--r--macros/latex/contrib/keytheorems/tex/keytheorems.sty43
12 files changed, 8221 insertions, 62 deletions
diff --git a/macros/latex/contrib/atableau/LICENSE b/macros/latex/contrib/atableau/LICENSE
new file mode 100644
index 0000000000..f79de3285a
--- /dev/null
+++ b/macros/latex/contrib/atableau/LICENSE
@@ -0,0 +1,401 @@
+The LaTeX Project Public License
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+LPPL Version 1.3 2003-12-01
+
+Copyright 1999 2002-03 LaTeX3 Project
+ Everyone is allowed to distribute verbatim copies of this
+ license document, but modification of it is not allowed.
+
+
+PREAMBLE
+========
+
+The LaTeX Project Public License (LPPL) is the primary license under
+which the LaTeX kernel and the base LaTeX packages are distributed.
+
+You may use this license for any work of which you hold the copyright
+and which you wish to distribute. This license may be particularly
+suitable if your work is TeX-related (such as a LaTeX package), but
+you may use it with small modifications even if your work is unrelated
+to TeX.
+
+The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
+below, gives instructions, examples, and recommendations for authors
+who are considering distributing their works under this license.
+
+This license gives conditions under which a work may be distributed
+and modified, as well as conditions under which modified versions of
+that work may be distributed.
+
+We, the LaTeX3 Project, believe that the conditions below give you
+the freedom to make and distribute modified versions of your work
+that conform with whatever technical specifications you wish while
+maintaining the availability, integrity, and reliability of
+that work. If you do not see how to achieve your goal while
+meeting these conditions, then read the document `cfgguide.tex'
+and `modguide.tex' in the base LaTeX distribution for suggestions.
+
+
+DEFINITIONS
+===========
+
+In this license document the following terms are used:
+
+ `Work'
+ Any work being distributed under this License.
+
+ `Derived Work'
+ Any work that under any applicable law is derived from the Work.
+
+ `Modification'
+ Any procedure that produces a Derived Work under any applicable
+ law -- for example, the production of a file containing an
+ original file associated with the Work or a significant portion of
+ such a file, either verbatim or with modifications and/or
+ translated into another language.
+
+ `Modify'
+ To apply any procedure that produces a Derived Work under any
+ applicable law.
+
+ `Distribution'
+ Making copies of the Work available from one person to another, in
+ whole or in part. Distribution includes (but is not limited to)
+ making any electronic components of the Work accessible by
+ file transfer protocols such as FTP or HTTP or by shared file
+ systems such as Sun's Network File System (NFS).
+
+ `Compiled Work'
+ A version of the Work that has been processed into a form where it
+ is directly usable on a computer system. This processing may
+ include using installation facilities provided by the Work,
+ transformations of the Work, copying of components of the Work, or
+ other activities. Note that modification of any installation
+ facilities provided by the Work constitutes modification of the Work.
+
+ `Current Maintainer'
+ A person or persons nominated as such within the Work. If there is
+ no such explicit nomination then it is the `Copyright Holder' under
+ any applicable law.
+
+ `Base Interpreter'
+ A program or process that is normally needed for running or
+ interpreting a part or the whole of the Work.
+ A Base Interpreter may depend on external components but these
+ are not considered part of the Base Interpreter provided that each
+ external component clearly identifies itself whenever it is used
+ interactively. Unless explicitly specified when applying the
+ license to the Work, the only applicable Base Interpreter is a
+ "LaTeX-Format".
+
+
+
+CONDITIONS ON DISTRIBUTION AND MODIFICATION
+===========================================
+
+1. Activities other than distribution and/or modification of the Work
+are not covered by this license; they are outside its scope. In
+particular, the act of running the Work is not restricted and no
+requirements are made concerning any offers of support for the Work.
+
+2. You may distribute a complete, unmodified copy of the Work as you
+received it. Distribution of only part of the Work is considered
+modification of the Work, and no right to distribute such a Derived
+Work may be assumed under the terms of this clause.
+
+3. You may distribute a Compiled Work that has been generated from a
+complete, unmodified copy of the Work as distributed under Clause 2
+above, as long as that Compiled Work is distributed in such a way that
+the recipients may install the Compiled Work on their system exactly
+as it would have been installed if they generated a Compiled Work
+directly from the Work.
+
+4. If you are the Current Maintainer of the Work, you may, without
+restriction, modify the Work, thus creating a Derived Work. You may
+also distribute the Derived Work without restriction, including
+Compiled Works generated from the Derived Work. Derived Works
+distributed in this manner by the Current Maintainer are considered to
+be updated versions of the Work.
+
+5. If you are not the Current Maintainer of the Work, you may modify
+your copy of the Work, thus creating a Derived Work based on the Work,
+and compile this Derived Work, thus creating a Compiled Work based on
+the Derived Work.
+
+6. If you are not the Current Maintainer of the Work, you may
+distribute a Derived Work provided the following conditions are met
+for every component of the Work unless that component clearly states
+in the copyright notice that it is exempt from that condition. Only
+the Current Maintainer is allowed to add such statements of exemption
+to a component of the Work.
+
+ a. If a component of this Derived Work can be a direct replacement
+ for a component of the Work when that component is used with the
+ Base Interpreter, then, wherever this component of the Work
+ identifies itself to the user when used interactively with that
+ Base Interpreter, the replacement component of this Derived Work
+ clearly and unambiguously identifies itself as a modified version
+ of this component to the user when used interactively with that
+ Base Interpreter.
+
+ b. Every component of the Derived Work contains prominent notices
+ detailing the nature of the changes to that component, or a
+ prominent reference to another file that is distributed as part
+ of the Derived Work and that contains a complete and accurate log
+ of the changes.
+
+ c. No information in the Derived Work implies that any persons,
+ including (but not limited to) the authors of the original version
+ of the Work, provide any support, including (but not limited to)
+ the reporting and handling of errors, to recipients of the
+ Derived Work unless those persons have stated explicitly that
+ they do provide such support for the Derived Work.
+
+ d. You distribute at least one of the following with the Derived Work:
+
+ 1. A complete, unmodified copy of the Work;
+ if your distribution of a modified component is made by
+ offering access to copy the modified component from a
+ designated place, then offering equivalent access to copy
+ the Work from the same or some similar place meets this
+ condition, even though third parties are not compelled to
+ copy the Work along with the modified component;
+
+ 2. Information that is sufficient to obtain a complete, unmodified
+ copy of the Work.
+
+7. If you are not the Current Maintainer of the Work, you may
+distribute a Compiled Work generated from a Derived Work, as long as
+the Derived Work is distributed to all recipients of the Compiled
+Work, and as long as the conditions of Clause 6, above, are met with
+regard to the Derived Work.
+
+8. The conditions above are not intended to prohibit, and hence do
+not apply to, the modification, by any method, of any component so that it
+becomes identical to an updated version of that component of the Work as
+it is distributed by the Current Maintainer under Clause 4, above.
+
+9. Distribution of the Work or any Derived Work in an alternative
+format, where the Work or that Derived Work (in whole or in part) is
+then produced by applying some process to that format, does not relax or
+nullify any sections of this license as they pertain to the results of
+applying that process.
+
+10. a. A Derived Work may be distributed under a different license
+ provided that license itself honors the conditions listed in
+ Clause 6 above, in regard to the Work, though it does not have
+ to honor the rest of the conditions in this license.
+
+ b. If a Derived Work is distributed under this license, that
+ Derived Work must provide sufficient documentation as part of
+ itself to allow each recipient of that Derived Work to honor the
+ restrictions in Clause 6 above, concerning changes from the Work.
+
+11. This license places no restrictions on works that are unrelated to
+the Work, nor does this license place any restrictions on aggregating
+such works with the Work by any means.
+
+12. Nothing in this license is intended to, or may be used to, prevent
+complete compliance by all parties with all applicable laws.
+
+
+NO WARRANTY
+===========
+
+There is no warranty for the Work. Except when otherwise stated in
+writing, the Copyright Holder provides the Work `as is', without
+warranty of any kind, either expressed or implied, including, but not
+limited to, the implied warranties of merchantability and fitness for
+a particular purpose. The entire risk as to the quality and performance
+of the Work is with you. Should the Work prove defective, you
+assume the cost of all necessary servicing, repair, or correction.
+
+In no event unless agreed to in writing will the Copyright Holder, or
+any author named in the components of the Work, or any other party who
+may distribute and/or modify the Work as permitted above, be liable to
+you for damages, including any general, special, incidental or
+consequential damages arising out of any use of the Work or out of
+inability to use the Work (including, but not limited to, loss of
+data, data being rendered inaccurate, or losses sustained by anyone as
+a result of any failure of the Work to operate with any other
+programs), even if the Copyright Holder or said author or said other
+party has been advised of the possibility of such damages.
+
+
+MAINTENANCE OF THE WORK
+=======================
+
+The Work has the status `author-maintained' if the Copyright Holder
+explicitly and prominently states near the primary copyright notice in
+the Work that the Work can only be maintained by the Copyright Holder
+or simply that is `author-maintained'.
+
+The Work has the status `maintained' if there is a Current Maintainer
+who has indicated in the Work that they are willing to receive error
+reports for the Work (for example, by supplying a valid e-mail
+address). It is not required for the Current Maintainer to acknowledge
+or act upon these error reports.
+
+The Work changes from status `maintained' to `unmaintained' if there
+is no Current Maintainer, or the person stated to be Current
+Maintainer of the work cannot be reached through the indicated means
+of communication for a period of six months, and there are no other
+significant signs of active maintenance.
+
+You can become the Current Maintainer of the Work by agreement with
+any existing Current Maintainer to take over this role.
+
+If the Work is unmaintained, you can become the Current Maintainer of
+the Work through the following steps:
+
+ 1. Make a reasonable attempt to trace the Current Maintainer (and
+ the Copyright Holder, if the two differ) through the means of
+ an Internet or similar search.
+
+ 2. If this search is successful, then enquire whether the Work
+ is still maintained.
+
+ a. If it is being maintained, then ask the Current Maintainer
+ to update their communication data within one month.
+
+ b. If the search is unsuccessful or no action to resume active
+ maintenance is taken by the Current Maintainer, then announce
+ within the pertinent community your intention to take over
+ maintenance. (If the Work is a LaTeX work, this could be
+ done, for example, by posting to comp.text.tex.)
+
+ 3a. If the Current Maintainer is reachable and agrees to pass
+ maintenance of the Work to you, then this takes effect
+ immediately upon announcement.
+
+ b. If the Current Maintainer is not reachable and the Copyright
+ Holder agrees that maintenance of the Work be passed to you,
+ then this takes effect immediately upon announcement.
+
+ 4. If you make an `intention announcement' as described in 2b. above
+ and after three months your intention is challenged neither by
+ the Current Maintainer nor by the Copyright Holder nor by other
+ people, then you may arrange for the Work to be changed so as
+ to name you as the (new) Current Maintainer.
+
+ 5. If the previously unreachable Current Maintainer becomes
+ reachable once more within three months of a change completed
+ under the terms of 3b) or 4), then that Current Maintainer must
+ become or remain the Current Maintainer upon request provided
+ they then update their communication data within one month.
+
+A change in the Current Maintainer does not, of itself, alter the fact
+that the Work is distributed under the LPPL license.
+
+If you become the Current Maintainer of the Work, you should
+immediately provide, within the Work, a prominent and unambiguous
+statement of your status as Current Maintainer. You should also
+announce your new status to the same pertinent community as
+in 2b) above.
+
+
+WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
+======================================================
+
+This section contains important instructions, examples, and
+recommendations for authors who are considering distributing their
+works under this license. These authors are addressed as `you' in
+this section.
+
+Choosing This License or Another License
+----------------------------------------
+
+If for any part of your work you want or need to use *distribution*
+conditions that differ significantly from those in this license, then
+do not refer to this license anywhere in your work but, instead,
+distribute your work under a different license. You may use the text
+of this license as a model for your own license, but your license
+should not refer to the LPPL or otherwise give the impression that
+your work is distributed under the LPPL.
+
+The document `modguide.tex' in the base LaTeX distribution explains
+the motivation behind the conditions of this license. It explains,
+for example, why distributing LaTeX under the GNU General Public
+License (GPL) was considered inappropriate. Even if your work is
+unrelated to LaTeX, the discussion in `modguide.tex' may still be
+relevant, and authors intending to distribute their works under any
+license are encouraged to read it.
+
+A Recommendation on Modification Without Distribution
+-----------------------------------------------------
+
+It is wise never to modify a component of the Work, even for your own
+personal use, without also meeting the above conditions for
+distributing the modified component. While you might intend that such
+modifications will never be distributed, often this will happen by
+accident -- you may forget that you have modified that component; or
+it may not occur to you when allowing others to access the modified
+version that you are thus distributing it and violating the conditions
+of this license in ways that could have legal implications and, worse,
+cause problems for the community. It is therefore usually in your
+best interest to keep your copy of the Work identical with the public
+one. Many works provide ways to control the behavior of that work
+without altering any of its licensed components.
+
+How to Use This License
+-----------------------
+
+To use this license, place in each of the components of your work both
+an explicit copyright notice including your name and the year the work
+was authored and/or last substantially modified. Include also a
+statement that the distribution and/or modification of that
+component is constrained by the conditions in this license.
+
+Here is an example of such a notice and statement:
+
+ %% pig.dtx
+ %% Copyright 2003 M. Y. Name
+ %
+ % 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.3 or later is part of all distributions of LaTeX
+ % version 2003/12/01 or later.
+ %
+ % This work has the LPPL maintenance status "maintained".
+ %
+ % This Current Maintainer of this work is M. Y. Name.
+ %
+ % This work consists of the files pig.dtx and pig.ins
+ % and the derived file pig.sty.
+
+Given such a notice and statement in a file, the conditions
+given in this license document would apply, with the `Work' referring
+to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
+generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
+referring to any "LaTeX-Format", and both `Copyright Holder' and
+`Current Maintainer' referring to the person `M. Y. Name'.
+
+To prevent the Maintenance section of LPPL from allowing someone else
+to become the Current Maintainer without your agreement, you could
+change "maintained" above into "author-maintained".
+
+
+Important Recommendations
+-------------------------
+
+ Defining What Constitutes the Work
+
+ The LPPL requires that distributions of the Work contain all the
+ files of the Work. It is therefore important that you provide a
+ way for the licensee to determine which files constitute the Work.
+ This could, for example, be achieved by explicitly listing all the
+ files of the Work near the copyright notice of each file or by
+ using a line such as:
+
+ % This work consists of all files listed in manifest.txt.
+
+ in that place. In the absence of an unequivocal list it might be
+ impossible for the licensee to determine what is considered by you
+ to comprise the Work and, in such a case, the licensee would be
+ entitled to make reasonable conjectures as to which files comprise
+ the Work.
+
diff --git a/macros/latex/contrib/atableau/README.md b/macros/latex/contrib/atableau/README.md
new file mode 100644
index 0000000000..67be172466
--- /dev/null
+++ b/macros/latex/contrib/atableau/README.md
@@ -0,0 +1,45 @@
+![version](https://img.shields.io/github/v/tag/AndrewMathas/aTableau?color=success&label=version)
+![LPPL](https://img.shields.io/github/license/note286/xduts?style=flat-square)
+![LaTeX](https://img.shields.io/badge/LaTeX-008080?logo=latex&logoColor=fff&style=flat)
+
+# aTableau
+1
+
+A LaTeX package for symmetric group combinatorics, with commands for:
+
+ - Young diagrams
+ - tableaux
+ - tabloids
+ - skew tableaux
+ - shifted tableaux
+ - ribbon tableaux
+ - multitableaux
+ - abacuses
+
+``` latex
+\Tableau{12345,678,9{10},{11}}
+\Diagram[french]{4^4,2,1^3}
+\Tabloid{1379{11},249{10},6,8}
+\SkewTableau[ukrainian]{3,2,1}{345,56,9{10}}
+\SkewDiagram[skew border style={dashed,fill=red!10},skew border]{1^2}{2^3}
+\ShiftedTableau[skew boxes]{1*23,4*5}
+\ShiftedDiagram[skew border]{3,2}
+\RibbonTableau[ukrainian, skew={4,1^2}]{16rcrrrccrcc, 26, 34rc}
+\Multidiagram[australian]{3,2^2|2,1,1|1}
+\Multitableau[box font=\tiny]{123,45,67|89,{10},{11}|{12}{13}{14}}
+\Abacus[rows=3, abacus ends=..]{3}{0,2,3,4,5}
+\Abacus{3}{0,2,3,4,5}
+```
+
+### Dependencies
+[LaTeX3](https://www.latex-project.org/latex3/) and [TikZ](https://tikz.net/)
+
+## Author
+Andrew Mathas
+
+## Licence
+LPPL Version 1.3 2003-12-01
+
+## Repository
+[github.com/AndrewMathas/aTableau/](github.com/AndrewMathas/aTableau/)
+
diff --git a/macros/latex/contrib/atableau/atableau.ini b/macros/latex/contrib/atableau/atableau.ini
new file mode 100644
index 0000000000..d8d8246479
--- /dev/null
+++ b/macros/latex/contrib/atableau/atableau.ini
@@ -0,0 +1,13 @@
+author_email = andrew.mathas@sydney.edu.au
+authors = Andrew Mathas
+copyright = 2023-2025
+description = A LaTeX package for tableaux, abacuses, ...
+email = andrew.mathas@gmail.com
+keywords = tableaux, Yougn diagrans, abacuses
+license = LPPL Version 1.3 2003-12-01
+name = Andrew Mathas
+package = atableau
+repository = github.com/AndrewMathas/aTableau/
+requirements = LaTeX2e
+release date = 22 January 2025 AEDT
+version = 2.0.2
diff --git a/macros/latex/contrib/atableau/atableau.pdf b/macros/latex/contrib/atableau/atableau.pdf
new file mode 100644
index 0000000000..d819e18d33
--- /dev/null
+++ b/macros/latex/contrib/atableau/atableau.pdf
Binary files differ
diff --git a/macros/latex/contrib/atableau/atableau.sty b/macros/latex/contrib/atableau/atableau.sty
new file mode 100644
index 0000000000..75904e3c64
--- /dev/null
+++ b/macros/latex/contrib/atableau/atableau.sty
@@ -0,0 +1,3335 @@
+% ---------------------------------------------------------------------------
+%
+% atableau - Andrew Mathas (C) 2022-2025
+%
+% A latex package for symmetric group combinatorics, including:
+% - abacuses
+% - multitableau
+% - ribbon tableau
+% - shifted tableau
+% - skew tableau
+% - tableaux
+% - tabloids
+% - Young diagrams
+%
+% E-mail: andrew.mathas@gmail.com
+% Released under the LaTeX Project Public License v1.3c or later
+% See http://www.latex-project.org/lppl.txt
+
+% ---------------------------------------------------------------------------
+% load TikZ early to avoid \ExplSyntaxOn...\ExplSyntaxOff wrappers
+\RequirePackage{tikz}
+\usetikzlibrary{shapes.geometric,matrix}
+
+
+% Correct for negative signs in contents being too long to fit in a tableau
+\RequirePackage{amsfonts} %% <- also included by amssymb
+\DeclareMathSymbol{\shortminus}{\mathbin}{AMSa}{"39}
+
+% ---------------------------------------------------------------------------
+% package date and version
+\def\atableau@version{2.0.2}
+\def\atableau@release{2025-01-22}
+
+\providecommand\DeclareRelease[3]{}
+\providecommand\DeclareCurrentRelease[2]{}
+\DeclareRelease{\atableau@version}{\atableau@release}{atableau.sty}
+\DeclareCurrentRelease{}{\atableau@release}
+
+\ProvidesExplPackage{atableau} {\atableau@release} {\atableau@version}
+ {A latex package for symmetric group combinatorics }
+
+% ---------------------------------------------------------------------------
+% package errors
+
+\msg_new:nnnn { aTableau } { empty-tableau-row }
+ { Row~#1~of~tableau~is~empty }
+ { Empty~tableau~rows~are~not~supported}
+
+\msg_new:nnnn { aTableau } { missing-runner-labels }
+{ Your~abacus~has~a~different~number~of~runners~and~runner~labels }
+{ The~number~of~labels~given~to~the~'runner~labels'~must~match~the~number~of~abacus~runners }
+
+\msg_new:nnnn { aTableau } { missing-style }
+{ The~'#1'~styles~key~is~missing~a~value }
+{ The~styles~key~accepts~a~comma~separated~list~of~key-value~pairs~for~defining~TikZ~styles }
+
+\msg_new:nnnn { aTableau } { invalid-dots}
+ { Invalid~specifications~for~dotted~rows~or~dotted~cols }
+ { You~can~only~use~these~options~for~interior~rows~and~columns~in~the~diagrams}
+
+\msg_new:nnnn { aTableau } { invalid-ribbon-head }
+ { Invalid~ribbon~head:~the~row~and~column~indices~of~the~ribbon~head~must~be~given:~'#1'}
+ { Ribbon~specifications~must~be~for~the~form:~(optional~ribbon~style)[style]<row><col>+sequences~of~r's~and~c's~with~style}
+
+\msg_new:nnnn { aTableau } { invalid-ribbon-specification }
+ { Invalid~ribbon~specification~'#1':~expecting~r~or~c. }
+ { Ribbon~specifications~must~be~for~the~form:~[optional~style]<row><col>~sequences~of~r's and~c's~with~style}
+
+\msg_new:nnnn { aTableau } { unrecognised-abacus-label }
+ { Unrecognised~abacus~label~'#1'. }
+ { The~possible~abacus~labels~are~betas,~residues,~rows~and~shape}
+
+\msg_new:nnnn { aTableau } { unrecognised-entries }
+ { Unrecognised~entries~value:~'#1' }
+ { The~possible~diagram~values~for~entries~are:~contents,~first,~hooks,~last,~and~residues}
+
+\msg_new:nnnn { aTableau } { unrecognised-style }
+ { Unrecognised~style:~'#1' }
+ { The~available~tableau~styles~are~australian,~english,~french~and~ukrainian~and~the~available~abacus~styles~are~north,~south,~east~and~west~}
+
+\msg_new:nnnn { aTableau } { unknown-abacus-ends }
+ { Unrecognised~abacus~ends~setting:~'#1' }
+ { The~supported~ends~for~the~top/bottom~of~the~abacus~are:~-,~_~,.~,|,~and~>}
+
+\msg_new:nnnn { aTableau } { unknown-cartan }
+ { Unrecognised~Cartan~type~'#1' }
+ { The~supported~Cartan~types~are~(affine)~types~A,~AA,~C~and~DD}
+
+\msg_new:nnnn { aTableau } { unknown-baseline }
+ { Unrecognised~baseline~option:~'#1' }
+ { The~supported~halign~options~are~bottom,~centre,~left,~and~top }
+
+\msg_new:nnnn { aTableau } { unknown-halign }
+ { Unrecognised~halign~option:~'#1' }
+ { The~supported~halign~options~are~centre,~left,~and~right }
+
+\msg_new:nnnn { aTableau } { unknown-top }
+ { Unrecognised~format~for~abacus~top;~'#1' }
+ { The~supported~formats~are:~blank,~dots,~and~frame}
+
+\msg_new:nnnn { aTableau } { unknown-valign }
+ { Unrecognised~valign~option:~#1 }
+ { The~supported~valign~options~are~bottom,~centre~and~top }
+
+% ---------------------------------------------------------------------------
+% package variables
+
+\bool_new:N \l__atableau_beta_numbers_bool% true if specifying beta numbers
+\bool_new:N \l__atableau_frame_bool % true if drawing framed abacus runners
+\bool_new:N \l__atableau_conjugate_bool % true if drawing conjugate tableau/diagram
+\bool_new:N \l__atableau_border_bool % true if drawing tableau border
+\bool_new:N \l__atableau_boxes_bool % true if drawing inner tableau walls
+\bool_new:N \l__atableau_shifted_bool % true if a shifted tableau
+\bool_new:N \l__atableau_skew_border_bool % true if drawing skew border
+\bool_new:N \l__atableau_skew_boxes_bool % true if drawing skew boxes
+\bool_new:N \l__atableau_tabloid_bool % true if a tabloid
+\bool_new:N \l__atableau_separators_bool % true if drawing separators for multishapes
+
+\fp_new:N \l__atableau_ab_col_dx_fp % change in x-coordinate between columns in an abacus
+\fp_new:N \l__atableau_ab_col_dy_fp % change in y-coordinate between columns in an abacus
+\fp_new:N \l__atableau_ab_row_dx_fp % change in x-coordinate between rows in an abacus
+\fp_new:N \l__atableau_ab_row_dy_fp % change in y-coordinate between rows in an abacus
+\fp_new:N \l__atableau_abacus_ht_fp % height of the tableaux nodes/separation between abacus beads
+\fp_new:N \l__atableau_abacus_wd_fp % width of the tableaux nodes/separation between abacus runners
+\fp_new:N \l__atableau_bead_size_fp % bead radius
+\fp_new:N \l__atableau_box_ht_fp % height of a tableau box
+\fp_new:N \l__atableau_box_wd_fp % width of a tableau box
+\fp_new:N \l__atableau_rows_fp % number of rows in abacus/tableau
+\fp_new:N \l__atableau_separation_fp % distance between multitableau
+\fp_new:N \l__atableau_tab_col_dx_fp % change in x-coordinate between columns in a tableau
+\fp_new:N \l__atableau_tab_col_dy_fp % change in y-coordinate between columns in a tableau
+\fp_new:N \l__atableau_tab_row_dx_fp % change in x-coordinate between rows in a tableau
+\fp_new:N \l__atableau_tab_row_dy_fp % change in y-coordinate between rows in a tableau
+\fp_new:N \l__atableau_tick_length_fp % half the length of the abacus ticks
+\fp_new:N \l__atableau_x_fp % x-coordinate of the origin of the diagram
+\fp_new:N \l__atableau_xa_fp % scratch x-coordinate of a node/bead
+\fp_new:N \l__atableau_xb_fp % scratch x-coordinate of a node/bead
+\fp_new:N \l__atableau_xl_fp % x-coordinate of a tableau node/bead
+\fp_new:N \l__atableau_xmax_fp % maximum x-coordinate for multidiagrams and multitableaux
+\fp_new:N \l__atableau_xoffsets_seq % x-offsets for the (1,1)-nodes in a multi-tableau
+\fp_new:N \l__atableau_xscale_fp % scaling in the x-direction
+\fp_new:N \l__atableau_xsep_fp % x-coordinate difference to next separator for multishapes
+\fp_new:N \l__atableau_y_fp % y-coordinate of the origin of the diagram
+\fp_new:N \l__atableau_ya_fp % scratch y-coordinate of a node/bead
+\fp_new:N \l__atableau_yb_fp % scratch y-coordinate of a node/bead
+\fp_new:N \l__atableau_yl_fp % y-coordinate of a tableau node/bead
+\fp_new:N \l__atableau_ymax_fp % maximum y-coordinate for multidiagrams and multitableaux
+\fp_new:N \l__atableau_ymin_fp % minimum y-coordinate for multidiagrams and multitableaux
+\fp_new:N \l__atableau_yoffsets_seq % t-offsets for the (1,1)-nodes in a multi-tableau
+\fp_new:N \l__atableau_yscale_fp % scaling in the x-direction
+
+\int_new:N \l__atableau_beads_int % number of beads in abacus
+\int_new:N \l__atableau_charge_int % charge for current component
+\int_new:N \l__atableau_col_int % current column index
+\int_new:N \l__atableau_c_int % scratch column counter
+\int_new:N \l__atableau_cols_int % number of columns in a multitableau/abacus
+\int_new:N \l__atableau_component_int % component in multidiagrams and tableaux
+\int_new:N \l__atableau_e_int % quantum characteristic
+\int_new:N \l__atableau_row_int % current row index
+\int_new:N \l__atableau_r_int % scratch row counter
+\int_new:N \l__atableau_rows_int % number of rows in abacus
+
+\seq_new:N \l__atableau_charge_seq % sequences of charges = residue/content offset
+\seq_new:N \l__atableau_component_seq % multipartition
+\seq_new:N \l__atableau_conjugate_seq % conjugate partition
+\seq_new:N \l__atableau_dotted_cols_seq % columns with dots
+\seq_new:N \l__atableau_dotted_rows_seq % rows with dots
+\seq_new:N \l__atableau_multidotted_cols_seq % sequence of dotted columns for multi shapes
+\seq_new:N \l__atableau_multidotted_rows_seq % sequence of dotted rows for multi shapes
+\seq_new:N \l__atableau_multilabel_seq % a sequence of labels for multi shapes
+\seq_new:N \l__atableau_multipaths_seq % a sequence of ribbon paths for multi shapes
+\seq_new:N \l__atableau_multiribbons_seq % a sequence of ribbon for multi shapes
+\seq_new:N \l__atableau_multiskew_seq % a sequence of skew partitions for multi shapes
+\seq_new:N \l__atableau_multisnobs_seq % a sequence of snobs for multi shapes
+\seq_new:N \l__atableau_paths_seq % ribbon paths to add to tableau/diagram
+\seq_new:N \l__atableau_rcs_seq % ribbon row, column indices
+\seq_new:N \l__atableau_ribbons_seq % ribbons to add to tableau/diagram
+\seq_new:N \l__atableau_runner_labels_seq % labels for the abacus runners
+\seq_new:N \l__atableau_shape_seq % a partition
+\seq_new:N \l__atableau_skew_seq % the inner partition for a skew shape
+\seq_new:N \l__atableau_snobs_seq % snob ribbons to add to tableau/diagram
+\seq_new:N \l__atableau_styles_seq % ribbon/bead styles
+\seq_new:N \l__atableau_texts_seq % ribbon/bead texts
+\seq_new:N \l__atableau_xsep_seq % x-coordinates separators for multishapes
+
+\tl_new:N \l__atableau_abacus_bottom_tl % specifies the bottom of the abacus
+\tl_new:N \l__atableau_abacus_top_tl % specifies the top of the abacus
+\tl_new:N \l__atableau_bead_font_tl % font for abacus beads
+\tl_new:N \l__atableau_bead_shape_tl % shape of abacus beads
+\tl_new:N \l__atableau_bead_text_tl % text colour of abacus beads
+\tl_new:N \l__atableau_bead_tl % abacus head colour
+\tl_new:N \l__atableau_border_tl % diagram border
+\tl_new:N \l__atableau_box_fill_tl % fill colour for tableau boxes
+\tl_new:N \l__atableau_box_font_tl % font for tableau boxes
+\tl_new:N \l__atableau_box_shape_tl % shape of tableau boxes
+\tl_new:N \l__atableau_box_text_tl % text colour for tableau boxes
+\tl_new:N \l__atableau_capture_exp_tl % contains captured exponent
+\tl_new:N \l__atableau_capture_part_tl % contains captured part
+\tl_new:N \l__atableau_capture_style_tl % contains captured style
+\tl_new:N \l__atableau_capture_txt_tl % contains captured text
+\tl_new:N \l__atableau_cartan_tl % the Cartan type
+\tl_new:N \l__atableau_empty_tl % symbol for empty tableau/diagram in a multi tableau/diagram
+\tl_new:N \l__atableau_entries_tl % custom entries in tableau
+\tl_new:N \l__atableau_inner_tl % colour of tableau inner walls
+\tl_new:N \l__atableau_label_tl % a label to print on an tableau/diagram
+\tl_new:N \l__atableau_left_delimiter_tl % the left delimiter for multitableau and multidiagrams
+\tl_new:N \l__atableau_multiprefix_tl % prefix used when constructing multinode names
+\tl_new:N \l__atableau_name_tl % name of a tableau node
+\tl_new:N \l__atableau_outer_tl % colour of tableau outer walls
+\tl_new:N \l__atableau_path_box_tl % node for ribbon paths
+\tl_new:N \l__atableau_prefix_tl % prefix for node names
+\tl_new:N \l__atableau_ribbon_box_tl % box entry for ribbons
+\tl_new:N \l__atableau_ribbon_style_tl % optional style used for current path< ribbon or snob
+\tl_new:N \l__atableau_ribbon_path_tl % a ribbon in the ribbon tableau
+\tl_new:N \l__atableau_ribbon_type_tl % the type of ribbon, which is either path, ribbon or snob
+\tl_new:N \l__atableau_right_delimiter_tl % the right delimiter for multitableau and multidiagrams
+\tl_new:N \l__atableau_runner_tl % abacus runner colour
+\tl_new:N \l__atableau_snob_box_tl % box entry for snobs
+\tl_new:N \l__atableau_separator_fg_tl % foreground colour of the separator
+\tl_new:N \l__atableau_separator_tl % the separator between multitableau: | or , or ...
+\tl_new:N \l__atableau_shading_tl % the type of shading to use for the abacus beads
+\tl_new:N \l__atableau_show_tl % automatic tableau/bead labelling
+\tl_new:N \l__atableau_skew_border_tl % skew border colour
+\tl_new:N \l__atableau_starstyle_tl % current star style in use
+\tl_new:N \l__atableau_styled_nodes_tl % token lists of nodes with non-default style
+\tl_new:N \l__atableau_tick_tl % abacus tick colour
+\tl_new:N \l__atableau_tikz_after_tl % TikZ commands for after the diagram
+\tl_new:N \l__atableau_tikz_before_tl % TikZ commands for before the diagram
+\tl_new:N \l__atableau_tikzpicture_tl % TikZ environment settings
+\tl_new:N \l__atableau_unstyled_nodes_tl % token lists of nodes with efault style
+
+% ---------------------------------------------------------------------------
+% Variable defaults -- most defaults are given in the settings: \keys_set:nn {aTableau} {...}
+\tl_set:Nn \l__atableau_ribbon_type_tl {ribbon} % by default, ribbons are ribbons
+
+% ---------------------------------------------------------------------------
+% default colours
+\definecolor{aTableauMain} {HTML} {00008B}
+\definecolor{aTableauInner} {HTML} {0073e6}
+\definecolor{aTableauSkew} {HTML} {818589}
+\definecolor{aTableauSkewFill} {HTML} {F8F8F8}
+\definecolor{aTableauStarStyle} {HTML} {E6F7FF}
+
+% ---------------------------------------------------------------------------
+% TikZ styling of aTableau components
+
+\tikzset{
+ % -----------------------------------------------------------------------
+ % Allow ball shading to be disabled via shade=none.
+ % The essential idea comes from https://tex.stackexchange.com/a/85750/234252
+ no~shade/.code={ \tikz@addmode{\tikz@mode@shadefalse } },
+ % -----------------------------------------------------------------------
+ % all tikz settings are in the aTableau family
+ aTableau/.is~family,
+ aTableau/.cd,
+ % -----------------------------------------------------------------------
+ % Styles for tableaux and diagrams
+ % -----------------------------------------------------------------------
+ % inner tableau wall
+ innerWall/.style = {
+ line~cap = rect,
+ thin,
+ },
+ % outer tableau wall
+ borderStyle/.style = {
+ % shifting allows us to use \__atableau_set_box_coordinates:nnn when drawing the border
+ shift = {(\fp_eval:n{-(\l__atableau_tab_row_dx_fp+\l__atableau_tab_col_dx_fp)*\l__atableau_box_wd_fp/2},
+ \fp_eval:n{-(\l__atableau_tab_row_dy_fp+\l__atableau_tab_col_dy_fp)*\l__atableau_box_ht_fp/2})},
+ line~cap = rect,
+ very~thick,
+ draw = \l__atableau_outer_tl,
+ },
+ % skew walls
+ skewBorder/.style = {
+ % shifting allows us to use \__atableau_set_box_coordinates:nnn when drawing the border
+ shift = {(\fp_eval:n{-(\l__atableau_tab_row_dx_fp+\l__atableau_tab_col_dx_fp)*\l__atableau_box_wd_fp/2},
+ \fp_eval:n{-(\l__atableau_tab_row_dy_fp+\l__atableau_tab_col_dy_fp)*\l__atableau_box_ht_fp/2})},
+ draw = \l__atableau_skew_border_tl,
+ thick
+ },
+ % styles for tableau boxes in Young diagrams
+ % -----------------------------------------------------------------------
+ node/.style = {
+ anchor = center,
+ inner~sep = 0pt,
+ minimum~height = \fp_use:N \l__atableau_box_ht_fp cm,
+ minimum~width = \fp_use:N \l__atableau_box_wd_fp cm,
+ shape = \l__atableau_box_shape_tl,
+ font = \l__atableau_box_font_tl,
+ text = \l__atableau_box_text_tl,
+ },
+ boxStyle/.style = {
+ aTableau/node,
+ aTableau/innerWall,
+ draw = \l__atableau_inner_tl,
+ fill = \l__atableau_box_fill_tl,
+ },
+ % default skew box style
+ skewBox/.style = {
+ aTableau/node,
+ aTableau/innerWall,
+ draw = \l__atableau_skew_border_tl,
+ fill = aTableauSkewFill,
+ },
+ % box styles for paths, ribbons and snobs
+ % -----------------------------------------------------------------------
+ pathBox/.style = {
+ aTableau/node,
+ draw = none, % border disabled by default
+ },
+ ribbonBox/.style = {
+ aTableau/node,
+ },
+ snobBox/.style = {
+ aTableau/node,
+ },
+ % styles for paths, ribbons and snobs
+ % -----------------------------------------------------------------------
+ % default path style
+ pathStyle/.style = {
+ draw = \l__atableau_inner_tl,
+ },
+ ribbonStyle/.style = {
+ aTableau/innerWall,
+ draw = \l__atableau_inner_tl,
+ },
+ % default ribbon style
+ snobStyle/.style = {
+ aTableau/innerWall,
+ draw = \l__atableau_inner_tl,
+ },
+ % label styles
+ % -----------------------------------------------------------------------
+ labelStyle/.style = {
+ shift = {(\fp_eval:n{-0.2*(\l__atableau_tab_row_dx_fp+\l__atableau_tab_col_dx_fp)*\l__atableau_box_wd_fp},
+ \fp_eval:n{-0.2*(\l__atableau_tab_row_dy_fp+\l__atableau_tab_col_dy_fp)*\l__atableau_box_ht_fp})},
+ font=\scriptsize,
+ text = \l__atableau_inner_tl,
+ },
+ % tableau star style
+ % -----------------------------------------------------------------------
+ tableauStarStyle/.style = {
+ fill = aTableauStarStyle,
+ text = \l__atableau_box_text_tl,
+ },
+ % cleared boxes for dotted rows and columns
+ % -----------------------------------------------------------------------
+ clearBoxes/.style = {
+ draw = white,
+ fill = white,
+ },
+ % dots used for dotted rows and columns
+ % -----------------------------------------------------------------------
+ dottedLine/.style = {
+ densely~dotted,
+ thick,
+ draw = \l__atableau_outer_tl,
+ },
+ % separators and delimiters
+ % -----------------------------------------------------------------------
+ separatorSymbol/.style = {
+ text = \l__atableau_separator_fg_tl,
+ },
+ % default separator line style
+ separatorLine/.style = {
+ thick,
+ draw = \l__atableau_separator_fg_tl,
+ },
+ % Delimiters around multitableaux and multidiagrams. To change the colour
+ % of the delimiters we need to use \path[aTableau/delimiterPath] (x,y) node...
+ delimiterStyle/.style = {
+ align = center,
+ inner~sep = 0pt,
+ minimum~height = \fp_use:N\l__atableau_ymax_fp cm,
+ },
+ % hack to set the colour
+ delimiterPath/.style = {
+ every~delimiter/.style = { \l__atableau_separator_fg_tl, },
+ },
+ leftDelimiter/.style = {
+ aTableau/delimiterStyle,
+ left~delimiter = \l__atableau_left_delimiter_tl,
+ xshift = 2pt,
+ },
+ rightDelimiter/.style = {
+ aTableau/delimiterStyle,
+ right~delimiter = \l__atableau_right_delimiter_tl,
+ xshift = -2pt,
+ },
+ % -----------------------------------------------------------------------
+ % abacus beads and runners
+ % -----------------------------------------------------------------------
+ % abacus beads
+ beadStyle/.style = {
+ ball~color = \l__atableau_bead_tl,
+ font = \l__atableau_bead_font_tl,
+ minimum~height = \fp_to_decimal:N \l__atableau_bead_size_fp cm,
+ minimum~width = \fp_to_decimal:N \l__atableau_bead_size_fp cm,
+ shading = \l__atableau_shading_tl,
+ shape = \l__atableau_bead_shape_tl,
+ text = \l__atableau_bead_text_tl,
+ anchor = center,
+ inner~sep = 0pt,
+ },
+ % abacus runners
+ runnerStyle/.style = {
+ line~cap = rect,
+ very~thick,
+ draw = \l__atableau_runner_tl,
+ },
+ runnerLabelStyle/.style = {
+ aTableau/node,
+ text = aTableauInner,
+ font = \scriptsize
+ },
+ % style for the top and bottom of the abacus
+ abacusEnds/.style = {
+ aTableau/runnerStyle,
+ },
+ % abacus star style
+ abacusStarStyle/.style = {
+ text = aTableauMain,
+ ball~color = aTableauStarStyle,
+ },
+ % abacus ticks
+ tickStyle/.style = {
+ draw = \l__atableau_tick_tl,
+ semithick,
+ },
+ % the named coordinate for an abacus tick
+ namedTick/.style = {
+ minimum~height = \fp_to_decimal:N \l__atableau_bead_size_fp cm,
+ minimum~width = \fp_to_decimal:N \l__atableau_bead_size_fp cm,
+ shape = \l__atableau_bead_shape_tl,
+ draw=none,
+ }
+}
+
+% ---------------------------------------------------------------------------
+
+% usage: \__atableau_set_style:nn {abacus|tableau} {style}
+% sets the basic styles for the tableaux and abacus commands
+\cs_new:Npn \__atableau_set_style:nn #1 #2
+{
+ \str_case:enF { #1/#2 }
+ {
+ {tableau/english}
+ {
+ \fp_set:Nn \l__atableau_tab_col_dx_fp {1}
+ \fp_set:Nn \l__atableau_tab_col_dy_fp {0}
+ \fp_set:Nn \l__atableau_tab_row_dx_fp {0}
+ \fp_set:Nn \l__atableau_tab_row_dy_fp {-1}
+ \fp_set:Nn \l__atableau_box_ht_fp {\l__atableau_yscale_fp*0.5}
+ \fp_set:Nn \l__atableau_box_wd_fp {\l__atableau_xscale_fp*0.5}
+ \tl_set:Nn \l__atableau_box_shape_tl {rectangle}
+ }
+ {tableau/french}
+ {
+ \fp_set:Nn \l__atableau_tab_col_dx_fp {1}
+ \fp_set:Nn \l__atableau_tab_col_dy_fp {0}
+ \fp_set:Nn \l__atableau_tab_row_dx_fp {0}
+ \fp_set:Nn \l__atableau_tab_row_dy_fp {1}
+ \fp_set:Nn \l__atableau_box_ht_fp {\l__atableau_yscale_fp*0.5}
+ \fp_set:Nn \l__atableau_box_wd_fp {\l__atableau_xscale_fp*0.5}
+ \tl_set:Nn \l__atableau_box_shape_tl {rectangle}
+ }
+ {tableau/australian}
+ {
+ \fp_set:Nn \l__atableau_tab_col_dx_fp {0.5}
+ \fp_set:Nn \l__atableau_tab_col_dy_fp {-0.5}
+ \fp_set:Nn \l__atableau_tab_row_dx_fp {-0.5}
+ \fp_set:Nn \l__atableau_tab_row_dy_fp {-0.5}
+ \fp_set:Nn \l__atableau_box_ht_fp {\l__atableau_yscale_fp*0.7012} % 1/sqrt(2)
+ \fp_set:Nn \l__atableau_box_wd_fp {\l__atableau_xscale_fp*0.7012}
+ \tl_set:Nn \l__atableau_box_shape_tl {diamond}
+ }
+ {tableau/ukrainian}
+ {
+ \fp_set:Nn \l__atableau_tab_col_dx_fp {0.5}
+ \fp_set:Nn \l__atableau_tab_col_dy_fp {0.5}
+ \fp_set:Nn \l__atableau_tab_row_dx_fp {-0.5}
+ \fp_set:Nn \l__atableau_tab_row_dy_fp {0.5}
+ \fp_set:Nn \l__atableau_box_ht_fp {\l__atableau_yscale_fp*0.7012}
+ \fp_set:Nn \l__atableau_box_wd_fp {\l__atableau_xscale_fp*0.7012}
+ \tl_set:Nn \l__atableau_box_shape_tl {diamond}
+ }
+ {tableau/russian}
+ {
+ \__atableau_set_style:nn {tableau} {ukrainian}
+ }
+ {abacus/south}
+ {
+ \fp_set:Nn \l__atableau_ab_col_dx_fp {1}
+ \fp_set:Nn \l__atableau_ab_col_dy_fp {0}
+ \fp_set:Nn \l__atableau_ab_row_dx_fp {0}
+ \fp_set:Nn \l__atableau_ab_row_dy_fp {-1}
+ \fp_set:Nn \l__atableau_abacus_ht_fp {\l__atableau_yscale_fp*0.5}
+ \fp_set:Nn \l__atableau_abacus_wd_fp {\l__atableau_xscale_fp*0.5}
+ \tl_set:Nn \l__atableau_bead_shape_tl {circle}
+ }
+ {abacus/north}
+ {
+ \fp_set:Nn \l__atableau_ab_col_dx_fp {1}
+ \fp_set:Nn \l__atableau_ab_col_dy_fp {0}
+ \fp_set:Nn \l__atableau_ab_row_dx_fp {0}
+ \fp_set:Nn \l__atableau_ab_row_dy_fp {1}
+ \tl_set:Nn \l__atableau_bead_shape_tl {circle}
+ \fp_set:Nn \l__atableau_abacus_wd_fp {\l__atableau_xscale_fp*0.5}
+ \fp_set:Nn \l__atableau_abacus_ht_fp {\l__atableau_yscale_fp*0.5}
+ }
+ {abacus/east}
+ {
+ \fp_set:Nn \l__atableau_ab_col_dx_fp {0}
+ \fp_set:Nn \l__atableau_ab_col_dy_fp {-1}
+ \fp_set:Nn \l__atableau_ab_row_dx_fp {1}
+ \fp_set:Nn \l__atableau_ab_row_dy_fp {0}
+ \tl_set:Nn \l__atableau_bead_shape_tl {circle}
+ \fp_set:Nn \l__atableau_abacus_wd_fp {\l__atableau_xscale_fp*0.5}
+ \fp_set:Nn \l__atableau_abacus_ht_fp {\l__atableau_yscale_fp*0.5}
+ }
+ {abacus/west}
+ {
+ \fp_set:Nn \l__atableau_ab_col_dx_fp {0}
+ \fp_set:Nn \l__atableau_ab_col_dy_fp {1}
+ \fp_set:Nn \l__atableau_ab_row_dx_fp {-1}
+ \fp_set:Nn \l__atableau_ab_row_dy_fp {0}
+ \tl_set:Nn \l__atableau_bead_shape_tl {circle}
+ \fp_set:Nn \l__atableau_abacus_wd_fp {\l__atableau_xscale_fp*0.5}
+ \fp_set:Nn \l__atableau_abacus_ht_fp {\l__atableau_yscale_fp*0.5}
+ }
+ }
+ {
+ \msg_error:nnx {aTableau} {unrecognised-style} {#1/#2}
+ }
+}
+
+% usage: \__atableau_set_xscale:n {x-scale} : rescale the x-dimension
+\cs_new_protected:Npn \__atableau_set_xscale:n #1
+{
+ \fp_set:Nn \l__atableau_xscale_fp {#1} % makes scale persistent
+ \fp_set:Nn \l__atableau_abacus_wd_fp {#1*\l__atableau_abacus_wd_fp}
+ \fp_set:Nn \l__atableau_box_wd_fp {#1*\l__atableau_box_wd_fp}
+ \fp_set:Nn \l__atableau_separation_fp {#1*\l__atableau_separation_fp }
+}
+% usage: \__atableau_set_yscale:n {y-scale} : rescale the y-dimension
+\cs_new_protected:Npn \__atableau_set_yscale:n #1
+{
+ \fp_set:Nn \l__atableau_yscale_fp {#1} % makes scale persistent
+ \fp_set:Nn \l__atableau_abacus_ht_fp {#1*\l__atableau_abacus_ht_fp}
+ \fp_set:Nn \l__atableau_box_ht_fp {#1*\l__atableau_box_ht_fp}
+}
+
+
+% usage: \__atableau_set_delimiters:nn {left delimiter} {right delimiter}
+\cs_new_protected:Npn \__atableau_set_delimiters:nn #1 #2
+{
+ \tl_set:Nn \l__atableau_left_delimiter_tl #1
+ \tl_set:Nn \l__atableau_right_delimiter_tl #2
+}
+
+% usage: \__atableau_set_multiseq_key:nn {name} {value}
+% Set up a sequence, for keys used with multishapes
+\cs_new_protected:Npn \__atableau_set_multiseq_key:nn #1 #2
+{
+ \tl_if_in:nnTF {#2} {|}
+ {
+ % unpack the ribbons into \l__atableau_multiribbons_seq
+ \seq_set_split:cnn {l__atableau_multi#1_seq} {|} {#2}
+ }
+ { \seq_set_from_clist:cn {l__atableau_#1_seq} {#2} }
+}
+
+% usage: \__atableau_set_abacus_ends:nn {top} {top}
+% Set the abacus ends abacus_top and abacus_bottom and give an error
+% message if the ends are not one of =,-,.,|,>
+\cs_new_protected:Npn \__atableau_set_abacus_ends:nn #1 #2
+{
+ \tl_set:Nn \l__atableau_abacus_top_tl {#1}
+ \str_if_in:nnF {-.>|\c_underscore_str*} {#1}
+ { \msg_error:nne {aTableau} {unknown-abacus-ends} {#1}}
+
+ \tl_set:Nn \l__atableau_abacus_bottom_tl {#2}
+ \str_if_in:nnF {-.>|\c_underscore_str*} {#2}
+ { \msg_error:nne {aTableau} {unknown-abacus-ends} {#2}}
+}
+
+% ---------------------------------------------------------------------------
+% command variants
+
+\cs_generate_variant:Nn \fp_add:Nn {NV}
+\cs_generate_variant:Nn \int_set:Nn {No}
+\cs_generate_variant:Nn \seq_put_right:Nn {Nx}
+\cs_generate_variant:Nn \seq_set_item:Nnn {NVx, Nnx, Nox}
+\cs_generate_variant:Nn \seq_set_from_clist:Nn {co}
+\cs_generate_variant:Nn \seq_set_split:Nnn {cnn}
+
+\cs_generate_variant:Nn \__atableau_add_ribbon:n {V}
+\cs_generate_variant:Nn \__atableau_count_row:n {x}
+\cs_generate_variant:Nn \__atableau_draw_tableau:n {V}
+\cs_generate_variant:Nn \__atableau_entry:n {x}
+\cs_generate_variant:Nn \__atableau_draw_abacus_end:nnn {noo}
+\cs_generate_variant:Nn \__atableau_set_bead_coordinates:nnn {nVV, nnV, noo, non, noV}
+\cs_generate_variant:Nn \__atableau_set_box_coordinates:nnn {nVV, nVn, noo }
+\cs_generate_variant:Nn \__atableau_set_partition:nn {no}
+\cs_generate_variant:Nn \__atableau_tl_put_right_braced:Nn { NV, Nx, No, Ne }
+
+% ---------------------------------------------------------------------------
+% utility functions
+
+% usage: \__atableau_tl_put_right_braced:Nn #1 #2
+% Add braces around #2 and append to #1
+\cs_new_protected:Nn \__atableau_tl_put_right_braced:Nn
+{
+ \tl_put_right:Nn #1 { {#2} }
+}
+
+% ---------------------------------------------------------------------------
+% expandable residue functions
+
+% usage: \__atableau_residue_A:nn
+% Computes the residue of #1 mod #2. This is positive integer remainder when
+% dividing by #2. As with \int_mod:n, the result is left in the input stream.
+\cs_new:Npn \__atableau_residue_A:nn #1 #2
+{
+ \int_compare:nNnTF {#1} > {0}
+ { \int_mod:nn {#1} {#2} }
+ { \int_eval:n {\int_mod:nn {#2 + \int_mod:nn {#1} {#2}} {#2}} }% \int_mod:nn is negative
+}
+
+% usage: \__atableau_residue_C:nn
+% Computes the residue of #1 in affine type C. When e=3 this residue pattern is
+% 0 1 2 3 2 1 0 1 2 3 2 1 0 1 ...
+% As with \int_mod:n, the result is left in the input stream.
+\cs_new:Npn \__atableau_residue_C:nn #1 #2
+{
+ \int_compare:nNnTF {#1} < {0}
+ { % #1 is negative
+ \int_compare:nNnTF {\int_mod:nn {#1} {2*#2}} < {-#2}
+ { \int_eval:n { 2*#2 + \int_mod:nn {#1} {2*#2} } }
+ { \int_eval:n { \int_mod:nn {-#1} {2*#2} } }
+ }
+ { % #1 is non-negative
+ \int_compare:nNnTF {\int_mod:nn {#1} {2*#2}} > {#2}
+ { \int_eval:n { 2*#2 - \int_mod:nn {#1} {2*#2} } }
+ { \int_eval:n { \int_mod:nn {#1} {2*#2} } }
+ }
+}
+
+% usage: \__atableau_residue_AA:nn
+% Computes the residue of #1 in twisted type A. When e=3 this residue pattern is
+% 0 1 2 3 3 2 1 0 1 2 3 3 2 1 0 1 ...
+% As with \int_mod:n, the result is left in the input stream.
+\cs_new:Npn \__atableau_residue_AA:nn #1 #2
+{
+ \int_compare:nNnTF {#1} < {0}
+ { % #1 is negative
+ \int_compare:nNnTF {\int_mod:nn {#1} {2*#2+1}} < {-#2}
+ { \int_eval:n { 2*#2+1 + \int_mod:nn {#1} {2*#2+1}} }
+ { \int_eval:n { \int_mod:nn {-#1} {2*#2+1} } }
+ }
+ { % #1 is non-negative
+ \int_compare:nNnTF {\int_mod:nn {#1} {2*#2+1}} > {#2}
+ { \int_eval:n { 2*#2+1 - \int_mod:nn {#1} {2*#2+1} } }
+ { \int_eval:n { \int_mod:nn {#1} {2*#2+1} } }
+ }
+}
+
+% usage: \__atableau_residue_D:nn
+% Computes the residue of #1 in affine type C. When e=3 this residue pattern is
+% 0 1 2 3 3 2 1 0 0 1 2 3 3 2 1 0 0 1 ...
+% As with \int_mod:n, the result is left in the input stream.
+\cs_new:Npn \__atableau_residue_DD:nn #1 #2
+{
+ \int_compare:nNnTF {#1} < {0}
+ { % #1 is negative
+ \int_compare:nNnTF {\int_mod:nn {#1} {2*#2+2}} < {-#2}
+ { \int_eval:n {2*#2+1 + \int_mod:nn {#1} {2*#2+2}} }
+ { \int_eval:n { -\int_mod:nn {#1} {2*#2+2} } }
+ }
+ { % #1 is non-negative
+ \int_compare:nNnTF {\int_mod:nn {#1} {2*#2+2}} > {#2}
+ { \int_eval:n {2*#2+1- \int_mod:nn {#1} {2*#2+2} } }
+ { \int_eval:n { \int_mod:nn {#1} {2*#2+2} } }
+ }
+}
+
+
+% use type A residues by default
+\cs_set_eq:NN \__atableau_residue:nn \__atableau_residue_A:nn
+
+% ---------------------------------------------------------------------------
+% Parsing input
+
+% \seq_set_split:Nnn does not respect braces around singleton entries
+% such as in { 1345, 8{10}, {11}, {12} }, with the result that {11}
+% and {12} are treated as {1}{1} and {1}{2}, respectively. As this is
+% not what we want, we use \peek_charcode:NTF to do this ourselves.
+\cs_new_protected:Npn \__atableau_peek_tableau:w
+{
+ \peek_remove_spaces:n { % ignore spaces
+ \peek_charcode_remove:NTF ,
+ {
+ % record the column index in the shape for drawing the border
+ \seq_put_right:NV \l__atableau_shape_seq \l__atableau_col_int
+
+ % increment the row index
+ \int_incr:N \l__atableau_row_int
+
+ % reset the column index, and update the skew shape for shifted tableau
+ \bool_if:NTF \l__atableau_shifted_bool
+ {
+ \seq_put_right:No \l__atableau_skew_seq {\int_use:N \l__atableau_row_int}
+ \int_set_eq:NN \l__atableau_col_int \l__atableau_row_int
+
+ }
+ {
+ \int_set:Nn \l__atableau_col_int { 0\seq_item:Nn \l__atableau_skew_seq {\l__atableau_row_int+1}}
+ }
+
+ % look for the next entry
+ \__atableau_peek_tableau:w
+ }
+ {
+ \__atableau_peek_style:nw {draw_entry:nn}
+ }
+ }
+}
+
+% ---------------------------------------------------------------------------
+
+% usage: \__atableau_peek_style:nw {command suffix}
+% Read the next entry in the input sequence, with any optional style given by
+% a * or [...], and then pass this data to the command \__atableau_#1.
+\cs_new_protected:Npn \__atableau_peek_style:nw #1
+{
+ \peek_remove_spaces:n { % ignore spaces
+ \peek_charcode:NTF [
+ { \use:c{__atableau_#1} }
+ {
+ \peek_charcode_remove:NTF *
+ { \use:c{__atableau_#1} [\l__atableau_starstyle_tl] }
+ { \use:c{__atableau_#1} [] }
+ }
+ }
+}
+
+% To parse the bead specifications used by \Abacus we need to accept the
+% a "bead specification" of the following form
+% [style]m^k_txt
+% where the [style] could simply be a *, the m is an integer, a part of the
+% partition being constructed, the k its exponent and txt is the text for the
+% node. Except for m, all of of these components are optional, with the
+% exponent being 1 if it is omitted. As is customary, the order of the
+% superscript and subscript is interchangeable. To parse these expressions we
+% first use \__atableau_peek_style:nw to strip off the style specification, via
+% \__atableau_record_style:nn, and then pass between \__atableau_peek_beads:nw
+% and \__atableau_record:nn to look ahead for the characters ^ and _ to decide
+% which of the following token lists the next character is added to:
+\cs_new_protected:Npn \__atableau_record_style:nn [#1] #2
+{
+ % clear the bead token lists
+ \tl_set:Nn \l__atableau_capture_style_tl {#1}
+ \tl_set:Nn \l__atableau_capture_part_tl {#2}
+ \tl_clear:N \l__atableau_capture_exp_tl
+ \tl_clear:N \l__atableau_capture_txt_tl
+ \__atableau_peek_beads:nw {part}
+}
+
+% look for a caret or an underscore and pass on to \__atableau_record_bead:nn
+\cs_new_protected:Npn \__atableau_peek_beads:nw #1
+{
+ \peek_remove_spaces:n { % ignore spaces
+ \peek_charcode_remove:NTF _
+ { \__atableau_record_bead:nn {txt} {}}
+ {
+ \peek_charcode_remove:NTF ^ { \__atableau_record_bead:nn {exp} {}}
+ { \__atableau_record_bead:nn {#1} }
+ }
+ }
+}
+
+% #1 is one of part, exp or txt
+\cs_new_protected:Npn \__atableau_record_bead:nn #1 #2
+{
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ {
+ % the data in the sequences \l__atableau_capture_exp_tl times
+ \tl_if_empty:NT \l__atableau_capture_exp_tl { \tl_set:Nn \l__atableau_capture_exp_tl {1}}
+ \int_step_inline:nn { \l__atableau_capture_exp_tl }
+ {
+ \int_incr:N \l__atableau_beads_int
+ \seq_put_right:NV \l__atableau_shape_seq \l__atableau_capture_part_tl
+ \seq_put_right:NV \l__atableau_texts_seq \l__atableau_capture_txt_tl
+ \seq_put_right:NV \l__atableau_styles_seq \l__atableau_capture_style_tl
+ }
+ }
+ \tl_put_right:cn {l__atableau_capture_#1_tl} {#2}
+ \__atableau_peek_beads:nw {#1}
+}
+
+
+% usage: \__atableau_count_entries:nn [style] {entry}
+% Count the number of entries in the row, storing the result in c_int
+\cs_new_protected:Npn \__atableau_count_entries:nn [#1] #2
+{
+ % exit when we reach the end of the row
+ \quark_if_recursion_tail_stop:n {#2}
+
+ \int_incr:N \l__atableau_c_int
+ \__atableau_peek_style:nw {count_entries:nn}
+}
+
+% usage: \__atableau_count_row:n {entries}
+\cs_new_protected:Npn \__atableau_count_row:n #1
+{
+ \__atableau_peek_style:nw {count_entries:nn} #1 \q_recursion_tail \q_recursion_stop
+}
+
+% ---------------------------------------------------------------------------
+% creating custom diagrams
+
+% usage: \__atableau_compute_conjugate_partition:N {seq}
+% compute the conjugate partition of <seq> and store in \l__atableau_conjugate_seq
+\cs_new_protected:Npn \__atableau_compute_conjugate_partition:N #1
+{
+ \seq_clear:N \l__atableau_conjugate_seq
+ \int_zero:N \l_tmpa_int % previous part
+ \int_set:No \l__atableau_r_int {\seq_count:N #1}
+ \int_while_do:nn {\l__atableau_r_int > 0}
+ {
+ \int_set:No \l_tmpb_int {\seq_item:NV #1 \l__atableau_r_int }
+ \int_step_inline:nn { \l_tmpb_int - \l_tmpa_int }
+ {
+ \seq_put_right:NV \l__atableau_conjugate_seq \l__atableau_r_int
+ }
+ \int_set_eq:NN \l_tmpa_int \l_tmpb_int
+ \int_decr:N \l__atableau_r_int
+ }
+}
+
+% usage: \__atableau_set_partition:nn {shape|skew} {csv for partition}
+% This function allows the partition to be given either as a comma separated
+% list of integers, or as a comma separated list of integers with exponents
+% giving the multiplicity of each part. For example, 4,3,3,3,2 and 4,3^3,2
+% are both supported.
+% TODO? Rewrite using quarks?
+\cs_new_protected:Npn \__atableau_set_partition:nn #1 #2
+{
+ \seq_clear:c {l__atableau_#1_seq}
+ \clist_map_inline:nn {#2} { \__atableau_add_to_partition:nn {#1} {##1} }
+}
+
+% add parts to the partition \l__atableau_#1_seq given input
+% of the form k or k^r
+\cs_new_protected:Npn \__atableau_add_to_partition:nn #1 #2
+{
+ % split #1 on ^: the trailing ^1 sets the exponent to 1 if it's omitted
+ \seq_set_split:Nnn \l_tmpa_seq {^} {#2 ^1}
+ % given k or k^r, set \l_tmpa_int=k and \l_tmpb_int=r, where r=1 with input k
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl % part
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpb_tl % exponent
+ % now add \l_tmpa_int to \l__atableau_#1_seq b times
+ \int_step_inline:nn {\l_tmpb_tl} { \seq_put_right:ce {l__atableau_#1_seq} {\l_tmpa_tl} }
+}
+
+% usage: \__atableau_diagram_for_shape:N {partition}
+% Young diagrams are drawn using the \Tableau command by generating
+% a sequence of ~ for the partition. For example,
+% it replaces the sequence 3,2,2,1 with
+% the dot-sequence ~~~,~~,~~,~,
+\cs_new_protected:Npn \__atableau_diagram_for_shape:N #1
+{
+ \tl_clear:N \l__atableau_entries_tl
+ \tl_set:Nn \l_tmpb_tl {}
+ \seq_map_inline:Nn #1
+ {
+ \tl_put_right:No \l__atableau_entries_tl \l_tmpb_tl
+ \tl_put_right:Nx \l__atableau_entries_tl { \prg_replicate:nn {##1} {{{~}}} }
+ \tl_set:Nn \l_tmpb_tl {,}
+ }
+}
+
+% usage: \__atableau_shape_to_content:Nn {partition sequence}
+% Return the content sequence to for a tableau of this shape
+\cs_new_protected:Npn \__atableau_shape_to_content:N #1
+{
+ \tl_clear:N \l__atableau_entries_tl
+ \int_zero:N \l__atableau_row_int
+ \tl_set:Nn \l_tmpb_tl {}
+ \seq_map_inline:Nn #1
+ {
+ \tl_put_right:No \l__atableau_entries_tl \l_tmpb_tl
+ \int_incr:N \l__atableau_row_int
+ \int_step_inline:nn {##1}
+ {
+ \int_set:Nn \l_tmpa_int { \l__atableau_charge_int + ####1 - \l__atableau_row_int + 0\seq_item:NV \l__atableau_skew_seq \l__atableau_row_int }
+ \int_compare:nNnTF {\l_tmpa_int} < {0}
+ { \__atableau_tl_put_right_braced:Ne \l__atableau_entries_tl {\exp_not:N\shortminus\int_eval:n{-\l_tmpa_int}} }
+ { \__atableau_tl_put_right_braced:No \l__atableau_entries_tl {\int_use:N \l_tmpa_int} }
+ }
+ \tl_set:Nn \l_tmpb_tl {,}
+ }
+}
+
+% Diagrams with show=last are drawn using the \Tableau command, with
+% usage: \__atableau_shape_to_last:N {partition sequence}
+\cs_new_protected:Npn \__atableau_shape_to_last:N #1
+{
+ % compute conjugate of #1 as \l__atableau_conjugate_seq
+ %\__atableau_compute_conjugate_partition:N #1
+
+ % initialise \l_tmpc_seq -- should not be necessary but otherwise \seq_item:NV fails
+ \seq_clear:N \l_tmpc_seq % construct the tableau in this sequence and then decant
+ \seq_map_inline:Nn #1 {\seq_put_right:Nn \l_tmpc_seq {}}
+
+ % value of last entry added to the tableau
+ \int_set:Nn \l__atableau_c_int {\l__atableau_charge_int}
+
+ % length of the first row of the partition/seq #1
+ \int_set:Nn \l__atableau_row_int {0\seq_item:Nn #1 {1}}
+
+ \int_step_inline:nn {\l__atableau_row_int} % ##1 is the column index
+ {
+ \int_zero:N \l__atableau_r_int % r_int is the row index
+ \seq_map_inline:Nn #1 % ####1 is the rth entry of the partition #1
+ {
+ \int_incr:N \l__atableau_r_int
+ \tl_set:Nn \l_tmpa_tl { 0\seq_item:NV \l__atableau_skew_seq \l__atableau_r_int}
+ \bool_if:nT { \int_compare_p:nNn {##1} > {\l_tmpa_tl} && \int_compare_p:nNn {\l_tmpa_tl+####1+1} > {##1}}
+ {
+ \int_incr:N \l__atableau_c_int
+ \tl_set:No \l_tmpa_tl { \seq_item:Nn \l_tmpc_seq {\l__atableau_r_int} }
+ \__atableau_tl_put_right_braced:No \l_tmpa_tl {\int_use:N \l__atableau_c_int}
+ \seq_set_item:NVx \l_tmpc_seq \l__atableau_r_int {\l_tmpa_tl}
+ }
+ }
+ }
+
+ % finally, unpack \l_tmpc_tl into l__atableau_entries_tl
+ \tl_clear:N \l__atableau_entries_tl
+ \tl_set:Nn \l_tmpb_tl {}
+ \seq_map_inline:Nn \l_tmpc_seq {
+ \tl_put_right:No \l__atableau_entries_tl \l_tmpb_tl
+ \tl_put_right:Nn \l__atableau_entries_tl {##1}
+ \tl_set:Nn \l_tmpb_tl {,}
+ }
+}
+
+% Diagrams with show=first are drawn using the \Tableau command, with
+% usage: \__atableau_shape_to_first:N {partition sequence}
+\cs_new_protected:Npn \__atableau_shape_to_first:N #1
+{
+ \tl_clear:N \l__atableau_entries_tl
+ \int_set:Nn \l__atableau_r_int {\l__atableau_charge_int}
+ \tl_set:Nn \l_tmpb_tl {}
+ \seq_map_inline:Nn #1
+ {
+ \tl_put_right:No \l__atableau_entries_tl \l_tmpb_tl
+ \int_step_inline:nn {##1}
+ {
+ \int_incr:N \l__atableau_r_int
+ \__atableau_tl_put_right_braced:NV \l__atableau_entries_tl \l__atableau_r_int
+ }
+ \tl_set:Nn \l_tmpb_tl {,}
+ }
+ \seq_put_right:No \l__atableau_charge_seq {\int_use:N\l__atableau_r_int}
+}
+
+% usage: \__atableau_shape_to_hook:N {partition_seq}
+% Return a string for the hooks length tableau
+% Diagrams with show=hooks are drawn using the \Tableau command
+\cs_new_protected:Npn \__atableau_shape_to_hook:N #1
+{
+ % now construct the hook tableau
+ \tl_clear:N \l__atableau_entries_tl
+ \bool_if:NTF \l__atableau_shifted_bool
+ { % shifted tableau
+ % initialise l_tmpc_seq because we will construct the entries in it and unpack at the end
+ \seq_clear:N \l_tmpc_seq
+ \seq_map_inline:Nn #1 {\seq_put_right:Nn \l_tmpc_seq {}}
+ \int_set:Nn \l__atableau_col_int { 0\seq_item:Nn #1 {1} } % length of first row
+ \int_step_inline:nn { \l__atableau_col_int }
+ { % add hooks column by column, starting by determining the rows in columns ##1
+ \int_zero:N \l__atableau_row_int
+ \seq_map_inline:Nn #1
+ {
+ \bool_if:nT { \int_compare_p:nNn {##1} > {\l__atableau_row_int} && \int_compare_p:nNn {####1+\l__atableau_row_int+1} > {##1} }
+ {
+ \int_incr:N \l__atableau_row_int
+ }
+ }
+ % record length of row col+1
+ \int_set:Nn \l_tmpa_int {0\seq_item:Nn #1 {##1+1}}
+ % loop through rows 1,...,row and add the hook lengths
+ \int_step_inline:nn {\l__atableau_row_int}
+ {
+ \tl_set:Nx \l_tmpa_tl { \seq_item:Nn \l_tmpc_seq {####1} }
+ \tl_set:Nx \l_tmpb_tl { \int_eval:n {\seq_item:Nn #1 {####1} + \l__atableau_row_int - ##1 + \l_tmpa_int } }
+ \__atableau_tl_put_right_braced:NV \l_tmpa_tl \l_tmpb_tl
+ \seq_set_item:Nnx \l_tmpc_seq {####1} {\l_tmpa_tl}
+
+ }
+ }
+ \tl_set:Nx \l__atableau_entries_tl { \seq_use:Nn \l_tmpc_seq {,} }
+ }
+ { % unshifted (although could be skew, when all bets are off...)
+ % compute conjugate of #1 as \l__atableau_conjugate_seq
+ \int_zero:N \l__atableau_row_int
+ \tl_set:Nn \l_tmpb_tl {}
+ \__atableau_compute_conjugate_partition:N #1
+ \seq_map_inline:Nn #1
+ {
+ \tl_put_right:No \l__atableau_entries_tl \l_tmpb_tl
+ \int_incr:N \l__atableau_row_int
+ \int_step_inline:nn {##1}
+ {
+ \tl_set:Ne \l_tmpc_tl { \int_eval:n {##1+\seq_item:Nn \l__atableau_conjugate_seq {####1} -\l__atableau_row_int-####1+1} }
+ \__atableau_tl_put_right_braced:NV \l__atableau_entries_tl \l_tmpc_tl
+ }
+ \tl_set:Nn \l_tmpb_tl {,}
+ }
+ }
+}
+
+% Residue diagrams are drawn using the \Tableau command, with
+% usage: \__atableau_shape_to_residue:N {partition sequence}
+\cs_new_protected:Npn \__atableau_shape_to_residue:N #1
+{
+ \tl_clear:N \l__atableau_entries_tl
+ \int_zero:N \l__atableau_row_int
+ \tl_set:Nn \l_tmpb_tl {}
+ \seq_map_inline:Nn #1
+ {
+ \tl_put_right:No \l__atableau_entries_tl \l_tmpb_tl
+ \int_incr:N \l__atableau_row_int
+ \int_step_inline:nn {##1}
+ {
+ \int_set:Nn \l_tmpa_int { \l__atableau_charge_int + ####1 - \l__atableau_row_int }
+ \int_add:Nn \l_tmpa_int { + 0\seq_item:NV \l__atableau_skew_seq \l__atableau_row_int }
+ \tl_set:Nx \l_tmpa_tl { \__atableau_residue:nn { \l_tmpa_int } {\l__atableau_e_int} }
+ \__atableau_tl_put_right_braced:Nx \l__atableau_entries_tl { \l_tmpa_tl }
+ }
+ \tl_set:Nn \l_tmpb_tl {,}
+ }
+}
+
+% ---------------------------------------------------------------------------
+% draw diagram border
+
+% usage: \__atableau_draw_border:nn #1 #2 {name of sequence} {name of style}
+% The name of the sequence is either skew or shape
+\cs_new_protected:Npn \__atableau_draw_border:nn #1 #2
+{
+ \int_zero:N \l__atableau_r_int % row index
+ \int_zero:N \l__atableau_c_int % column index
+ \tl_clear:N \l__atableau_border_tl % will hold the border
+
+ \seq_map_inline:cn {l__atableau_#1_seq}
+ {
+ % compute the endpoints of this row
+ \str_if_eq:nnF {skew} {#1}
+ {
+ \int_set:Nn \l__atableau_c_int { 0\seq_item:Nn \l__atableau_skew_seq {\l__atableau_r_int+1}}
+ \bool_if:nT { \l__atableau_tabloid_bool && \int_compare_p:nNn {\l__atableau_r_int} > {0} }
+ {
+ \int_set:Nn \l__atableau_c_int { \int_min:nn {\l__atableau_c_int} {0\seq_item:Nn \l__atableau_skew_seq {\l__atableau_r_int}} }
+ }
+ }
+ \__atableau_set_box_coordinates:nVV {a} \l__atableau_r_int \l__atableau_c_int
+ \__atableau_set_box_coordinates:nVn {b} \l__atableau_r_int {##1}
+ \bool_if:nTF { \int_compare_p:n {\l__atableau_r_int = 0} || \l__atableau_tabloid_bool }
+ {
+ % add line along "top" of the row
+ \tl_put_right:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp)}
+ \__atableau_add_row_ends:
+ }
+ {
+ % add lines for second and later rows
+ \tl_put_left:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--}
+ \tl_put_right:Nx \l__atableau_border_tl {--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp)}
+ \__atableau_add_row_ends:
+ }
+ \int_incr:N \l__atableau_r_int
+ }
+
+ % draw the border that we have constructed
+ \tl_if_empty:NF \l__atableau_border_tl
+ {
+ % fill in the last line
+ \bool_if:nT { \l__atableau_tabloid_bool && \int_compare_p:nNn {\l__atableau_r_int} > {0} }
+ {
+ \int_set:Nn \l__atableau_c_int { 0\seq_item:NV \l__atableau_skew_seq \l__atableau_r_int }
+ \__atableau_set_box_coordinates:nVV {a} \l__atableau_r_int \l__atableau_c_int
+ }
+ \tl_put_right:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp)}
+ % draw the border
+ \draw[aTableau/#2] \l__atableau_border_tl;
+ }
+}
+
+
+% usage: \__atableau_remove_dotted_tableau_rows:
+% Poke some holes in the border for the rows in dotted_rows_seq
+\cs_new_protected:Nn \__atableau_remove_dotted_tableau_rows:
+{
+ % To collect repeated rows in dotted_rows_seq
+ % we use \seq_map_inline:Nn and then compare ##1 with \l__atableau_r_int to
+ % determine if this is a new row.
+
+ % take a copy of \l__atableau_dotted_rows_seq so that the pop_left's below
+ % do not destroy it
+ \seq_set_eq:NN \l_tmpb_seq \l__atableau_dotted_rows_seq
+ \bool_do_until:nn { \seq_if_empty_p:N \l_tmpb_seq }
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_set:Nn \l__atableau_row_int {\l_tmpa_tl}
+ \int_set:Nn \l__atableau_r_int {\l__atableau_row_int+1}
+
+ % LaTeX3 does not provide \seq_if_in_p:NN, so ...
+ \bool_set_true:N \l_tmpa_bool
+ \bool_do_while:nn { \l_tmpa_bool }
+ {
+ \int_set:Nn \l_tmpa_int {0\seq_item:Nn \l_tmpb_seq 1}
+ \int_compare:nNnTF {\l__atableau_r_int} = {\l_tmpa_int}
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_incr:N \l__atableau_r_int
+ }
+ { \bool_set_false:N \l_tmpa_bool }
+ }
+
+ % We want to blank out the rows between the four coordinates
+ % a=(row,tmpa) .... b=(row,col)
+ % | |
+ % c=(r,tmpb) .... d=(r,c)
+
+ % set tmpa and tmpb to the column index for rows row and r, respectively
+ \int_set:No \l__atableau_col_int { 0\seq_item:NV \l__atableau_shape_seq \l__atableau_row_int } % mu_row
+ \int_set:No \l__atableau_c_int { 0\seq_item:NV \l__atableau_shape_seq \l__atableau_r_int } % mu_r
+
+ % shift in col-direction
+ \fp_set:Nn \l__atableau_xa_fp {\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_set:Nn \l__atableau_ya_fp {\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+
+ % shift in row-direction
+ \fp_set:Nn \l__atableau_xb_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_set:Nn \l__atableau_yb_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+
+ % a draw between the coordinates a, b, c, d
+ \__atableau_set_box_coordinates:noo {l} {\l__atableau_row_int-1} {\l__atableau_col_int-1} % point b
+
+ \draw[aTableau/clearBoxes]
+ (\fp_eval:n{\l__atableau_xl_fp+0.58*\l__atableau_xa_fp-0.42*\l__atableau_xb_fp},
+ \fp_eval:n{\l__atableau_yl_fp+0.58*\l__atableau_ya_fp-0.42*\l__atableau_yb_fp})
+ --++(\fp_eval:n{(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_xb_fp},
+ \fp_eval:n{(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_yb_fp})
+ --++(\fp_eval:n{(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_xa_fp},
+ \fp_eval:n{(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_ya_fp})
+ --++(\fp_eval:n{-0.12*\l__atableau_xb_fp}, \fp_eval:n{-0.12*\l__atableau_yb_fp})
+ --++(\fp_eval:n{-(0.15+\l__atableau_c_int)*\l__atableau_xa_fp}, \fp_eval:n{-(0.15+\l__atableau_c_int)*\l__atableau_ya_fp})
+ --++(\fp_eval:n{(\l__atableau_row_int-\l__atableau_r_int+0.12)*\l__atableau_xb_fp},
+ \fp_eval:n{(\l__atableau_row_int-\l__atableau_r_int+0.12)*\l__atableau_yb_fp})
+ --cycle
+ ;
+
+ % finally, we need to add dots between b and d
+ \draw[aTableau/dottedLine]
+ (\fp_eval:n{0.5*\l__atableau_xa_fp-0.5*\l__atableau_xb_fp+\l__atableau_xl_fp},
+ \fp_eval:n{0.5*\l__atableau_ya_fp-0.5*\l__atableau_yb_fp+\l__atableau_yl_fp})
+ --++(\fp_eval:n{(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_xa_fp+(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_xb_fp},
+ \fp_eval:n{(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_ya_fp+(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_yb_fp})
+ ;
+
+ % and between a and c, which is trickier as the skew shape plays a role
+ \int_set:No \l_tmpa_int { \int_eval:n {0\seq_item:Nn \l__atableau_skew_seq \l__atableau_row_int} }
+ \int_set:No \l_tmpb_int { \int_eval:n {\int_max:nn{\l_tmpa_int}{0\seq_item:Nn \l__atableau_skew_seq \l__atableau_r_int} }}
+ \int_decr:N \l__atableau_row_int
+ \int_decr:N \l__atableau_r_int
+ \draw[aTableau/dottedLine]
+ (\fp_eval:n{\l__atableau_x_fp+\l_tmpa_int*\l__atableau_xa_fp+\l__atableau_row_int*\l__atableau_xb_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l_tmpa_int*\l__atableau_ya_fp+\l__atableau_row_int*\l__atableau_yb_fp})
+ --(\fp_eval:n{\l__atableau_x_fp+\l_tmpb_int*\l__atableau_xa_fp+\l__atableau_r_int*\l__atableau_xb_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l_tmpb_int*\l__atableau_ya_fp+\l__atableau_r_int*\l__atableau_yb_fp})
+ ;
+
+ \bool_if:nT { \int_compare_p:nNn {\l_tmpa_int}>{0} && \l__atableau_skew_border_bool }
+ {
+ \draw[aTableau/dottedLine,draw=\l__atableau_skew_border_tl]
+ (\fp_eval:n{\l__atableau_x_fp+\l__atableau_row_int*\l__atableau_xb_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l__atableau_row_int*\l__atableau_yb_fp})
+ --(\fp_eval:n{\l__atableau_x_fp+\l__atableau_r_int*\l__atableau_xb_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l__atableau_r_int*\l__atableau_yb_fp})
+ ;
+ }
+ }
+}
+
+% usage: \__atableau_remove_dotted_tableau_cols:
+% Poke some holes in the border for the cols in dotted_rows_seq
+\cs_new_protected:Nn \__atableau_remove_dotted_tableau_cols:
+{
+ % To collect repeated columns in dotted_cols_seq
+ % we use \seq_map_inline:Nn and then compare ##1 with \l__atableau_c_int to
+ % determine if this is a new column.
+
+ % conjugate partition and skew shape
+ \__atableau_compute_conjugate_partition:N \l__atableau_skew_seq
+ \seq_set_eq:NN \l_tmpa_seq \l__atableau_conjugate_seq % \l_tmpa_seq is the conjugate skew
+ \__atableau_compute_conjugate_partition:N \l__atableau_shape_seq % conjugate shape
+
+ % take a copy of \l__atableau_dotted_cols_seq so that the pop_left's below
+ % do not destroy it
+ \seq_set_eq:NN \l_tmpb_seq \l__atableau_dotted_cols_seq
+ \bool_do_until:nn { \seq_if_empty_p:N \l_tmpb_seq }
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_set:Nn \l__atableau_col_int {\l_tmpa_tl}
+ \int_set:Nn \l__atableau_c_int {\l__atableau_col_int+1}
+
+ % LaTeX3 does not provide \seq_if_in_p:NN, so ...
+ \bool_set_true:N \l_tmpa_bool
+ \bool_do_while:nn { \l_tmpa_bool }
+ {
+ \int_set:Nn \l_tmpa_int {0\seq_item:Nn \l_tmpb_seq 1}
+ \int_compare:nNnTF {\l__atableau_c_int} = {\l_tmpa_int}
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_incr:N \l__atableau_c_int
+ }
+ { \bool_set_false:N \l_tmpa_bool }
+ }
+
+ % We want to blank out the rows between the four coordinates
+ % a=(row,tmpa) .... b=(r,tmpb)
+ % | |
+ % c=(row,col) .... d=(r,c)
+
+ % set row and r to the row indices for col and c, respectively
+ \int_set:No \l__atableau_row_int { 0\seq_item:NV \l__atableau_conjugate_seq \l__atableau_col_int } % mu_row
+ \int_set:No \l__atableau_r_int { 0\seq_item:NV \l__atableau_conjugate_seq \l__atableau_c_int } % mu_r
+
+
+ % shift in col-direction
+ \fp_set:Nn \l__atableau_xa_fp {\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_set:Nn \l__atableau_ya_fp {\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+
+ % shift in row-direction
+ \fp_set:Nn \l__atableau_xb_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_set:Nn \l__atableau_yb_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+
+ % a draw between the coordinates a, b, c, d
+ \__atableau_set_box_coordinates:noo {l} {\l__atableau_row_int-1} {\l__atableau_col_int-1} % point b
+
+ \draw[aTableau/clearBoxes]
+ (\fp_eval:n{\l__atableau_xl_fp-0.42*\l__atableau_xa_fp+0.58*\l__atableau_xb_fp},
+ \fp_eval:n{\l__atableau_yl_fp-0.42*\l__atableau_ya_fp+0.58*\l__atableau_yb_fp})
+ --++(\fp_eval:n{(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_xa_fp},
+ \fp_eval:n{(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_ya_fp})
+ --++(\fp_eval:n{(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_xb_fp},
+ \fp_eval:n{(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_yb_fp})
+ --++(\fp_eval:n{-0.12*\l__atableau_xa_fp}, \fp_eval:n{-0.12*\l__atableau_ya_fp})
+ --++(\fp_eval:n{-(0.15+\l__atableau_r_int)*\l__atableau_xb_fp}, \fp_eval:n{-(0.15+\l__atableau_r_int)*\l__atableau_yb_fp})
+ --++(\fp_eval:n{(\l__atableau_col_int-\l__atableau_c_int+0.12)*\l__atableau_xa_fp},
+ \fp_eval:n{(\l__atableau_col_int-\l__atableau_c_int+0.12)*\l__atableau_ya_fp})
+ --cycle
+ ;
+
+ % finally, we need to add dots between b and d
+ \draw[aTableau/dottedLine]
+ (\fp_eval:n{\l__atableau_xl_fp-0.5*\l__atableau_xa_fp+0.5*\l__atableau_xb_fp},
+ \fp_eval:n{\l__atableau_yl_fp-0.5*\l__atableau_ya_fp+0.5*\l__atableau_yb_fp})
+ --++(\fp_eval:n{(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_xb_fp+(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_xa_fp},
+ \fp_eval:n{(\l__atableau_r_int-\l__atableau_row_int)*\l__atableau_yb_fp+(\l__atableau_c_int-\l__atableau_col_int)*\l__atableau_ya_fp})
+ ;
+
+ % and between a and c, which is trickier as the skew shape plays a role
+ \int_set:No \l_tmpa_int { \int_eval:n {0\seq_item:Nn \l_tmpa_seq \l__atableau_col_int} }
+ \int_set:No \l_tmpb_int { \int_eval:n {\int_max:nn{\l_tmpa_int}{0\seq_item:Nn \l_tmpa_seq \l__atableau_c_int} }}
+ \int_decr:N \l__atableau_col_int
+ \int_decr:N \l__atableau_c_int
+ \draw[aTableau/dottedLine]
+ (\fp_eval:n{\l__atableau_x_fp+\l_tmpa_int*\l__atableau_xb_fp+\l__atableau_col_int*\l__atableau_xa_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l_tmpa_int*\l__atableau_yb_fp+\l__atableau_col_int*\l__atableau_ya_fp})
+ --(\fp_eval:n{\l__atableau_x_fp+\l_tmpb_int*\l__atableau_xb_fp+\l__atableau_c_int*\l__atableau_xa_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l_tmpb_int*\l__atableau_yb_fp+\l__atableau_c_int*\l__atableau_ya_fp})
+ ;
+
+ \bool_if:nT { \int_compare_p:nNn {\l_tmpa_int}>{0} && \l__atableau_skew_border_bool }
+ {
+ \draw[aTableau/dottedLine,draw=\l__atableau_skew_border_tl]
+ (\fp_eval:n{\l__atableau_x_fp+\l__atableau_col_int*\l__atableau_xa_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l__atableau_col_int*\l__atableau_ya_fp})
+ --(\fp_eval:n{\l__atableau_x_fp+\l__atableau_c_int*\l__atableau_xa_fp},
+ \fp_eval:n{\l__atableau_y_fp+\l__atableau_c_int*\l__atableau_ya_fp})
+ ;
+ }
+ }
+}
+
+% usage: \__atableau_draw_label:
+% Add the label to a diagram
+\cs_new_protected:Nn \__atableau_draw_label:
+{
+ % determine where the label should be attached, which is the (1,1)-box by default
+ \fp_set_eq:NN \l__atableau_xa_fp \l__atableau_x_fp
+ \fp_set_eq:NN \l__atableau_ya_fp \l__atableau_y_fp
+ \bool_if:nF { \seq_if_empty_p:N \l__atableau_skew_seq || \l__atableau_skew_border_bool }
+ { % attach label to the (1,skew_1)-box
+ \tl_set:Nn \l_tmpa_tl { 0\seq_item:Nn \l__atableau_skew_seq {1} }
+ \fp_add:Nn \l__atableau_xa_fp {\l_tmpa_tl*\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l_tmpa_tl*\l__atableau_tab_col_dy_fp*\l__atableau_box_wd_fp}
+ }
+ % add the label
+ \node[aTableau/labelStyle] at (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp) { \__atableau_entry:n{\l__atableau_label_tl} };
+}
+
+% usage: \__atableau_draw_skew_boxes:
+% Draw the skew boxes using ribbons
+\cs_new_protected:Nn \__atableau_draw_skew_boxes:
+{
+ \group_begin:
+ % override the style of the skew boxes inside this group
+ \tikzset{aTableau/ribbonBox/.style=aTableau/skewBox}
+ \tikzset{aTableau/ribbonStyle/.style={draw=none,fill=none}}
+ \tl_set:Nn \l__atableau_ribbon_type_tl {ribbon} % change ribbon type to ribbon
+ \int_zero:N \l__atableau_r_int
+ \seq_map_inline:Nn \l__atableau_skew_seq
+ {
+ \int_incr:N \l__atableau_r_int
+ \int_compare:nNnT {##1} > {0}
+ {
+ \tl_clear:N \l_tmpa_tl
+ \tl_put_right:Ne \l_tmpa_tl { {\int_use:N \l__atableau_r_int} }
+ \tl_put_right:Ne \l_tmpa_tl { {##1} }
+ \tl_put_right:Ne \l_tmpa_tl { \prg_replicate:nn {##1-1} {c} }
+ \__atableau_add_ribbon:V \l_tmpa_tl
+ }
+ }
+ \group_end:
+}
+
+% usage: \__atableau_add_row_ends: increment the (xa,ya) and (xb,yb) coordinates down
+% one row and add the lines at the left and right hand ends of the row to
+% \l__atableau_border_tl. If this is a tabloid then we only want to add the
+% coordinates but otherwise we join them up
+\cs_new_protected:Nn \__atableau_add_row_ends:
+{
+ \bool_if:NTF \l__atableau_conjugate_bool
+ {
+ % adding to the left-hand side
+ \fp_add:Nn \l__atableau_xa_fp {\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+
+ % adding to the right-hand side
+ \fp_add:Nn \l__atableau_xb_fp {\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_yb_fp {\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+
+ \bool_if:NTF \l__atableau_tabloid_bool
+ {
+ \tl_put_left:Nx \l__atableau_border_tl {--(\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)}
+ \tl_put_right:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp)--}
+ }
+ {
+ \tl_put_left:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--}
+ \tl_put_right:Nx \l__atableau_border_tl {--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp)}
+ }
+ }
+ {
+ % adding to the left-hand side
+ \fp_add:Nn \l__atableau_xa_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+
+ % adding to the right-hand side
+ \fp_add:Nn \l__atableau_xb_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_yb_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+
+ \bool_if:NTF \l__atableau_tabloid_bool
+ {
+ \tl_put_left:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)}
+ \tl_put_right:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp)--}
+ }
+ {
+ \tl_put_left:Nx \l__atableau_border_tl {(\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--}
+ \tl_put_right:Nx \l__atableau_border_tl {--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp)}
+ }
+ }
+}
+
+% ---------------------------------------------------------------------------
+% Tableaux
+
+% usage: \__atableau_draw_tableau:n {tableau specifications}
+% The entries are first primarily because the \Diagram commands need
+% to force the entries to expand
+\cs_new_protected:Npn \__atableau_draw_tableau:n #1
+{
+ % set the star style
+ \tl_set:Nn \l__atableau_starstyle_tl {aTableau/tableauStarStyle}
+
+ % disable interior boxes if boxes_bool is false
+ \bool_if:NF \l__atableau_boxes_bool { \__atableau_tikzset_append:nn {boxStyle} {draw=none} }
+
+ % initialise the skew shape for a shifted tableaux
+ \bool_if:NT \l__atableau_shifted_bool
+ {
+ \seq_clear:N \l__atableau_skew_seq
+ \seq_put_right:No \l__atableau_skew_seq {0}
+ }
+
+ % record the tableau shape as we go so that we can draw the border
+ % in finalise_tableau
+ \seq_clear:N \l__atableau_shape_seq
+
+ % the styled boxes are drawn at the end
+ \tl_clear:N \l__atableau_styled_nodes_tl
+
+ % set initial row and column
+ \int_zero:N \l__atableau_row_int
+ \int_set:Nn \l__atableau_col_int { 0\seq_item:Nn \l__atableau_skew_seq {1}}
+
+ % Parse #1 into the rows and columns with style. Initially we used
+ % \seq_set_split:Nnn here, but this required double bracing
+ % multi-character entries whenever they were he only entry in their
+ % column. Now we peek for the commas and the style simultaneously.
+ \__atableau_peek_tableau:w #1 \q_recursion_tail \q_recursion_stop
+
+ % add the nodes with style
+ \l__atableau_styled_nodes_tl
+
+ % add the labels, ribbons, snobs and border
+ \__atableau_finalise_tableau:
+}
+
+% usage: \__atableau_finalise_tableau:
+% As it is used in several places, collect the code that finishes
+% drawing the tableau by adding the ribbons, paths, snobs, skew boxes,
+% border and the dotted rows and columns.
+\cs_new_protected:Nn \__atableau_finalise_tableau:
+{
+ % prevent paths and ribbons from updating shape
+ \cs_set_eq:NN \__atableau_update_shape: \prg_do_nothing:
+
+ % add paths
+ \seq_if_empty:NF \l__atableau_paths_seq
+ {
+ \tl_set:Nn \l__atableau_ribbon_type_tl {path} % change ribbon type to path
+ \seq_map_inline:Nn \l__atableau_paths_seq {\__atableau_add_ribbon:n {##1}}
+ }
+
+ % add ribbons
+ \tl_set:Nn \l__atableau_ribbon_type_tl {ribbon} % change ribbon type to ribbon
+ \seq_map_inline:Nn \l__atableau_ribbons_seq {\__atableau_add_ribbon:n {##1}}
+
+ % paths and ribbons are inside the delimiters, but snobs are not
+ \cs_set_eq:NN \__atableau_update_extrema:n \use_none:n
+
+ % draw border
+ \tl_if_blank:VF \l__atableau_label_tl { \__atableau_draw_label: }
+ \bool_if:NT \l__atableau_skew_boxes_bool { \__atableau_draw_skew_boxes: }
+ \bool_if:NT \l__atableau_skew_border_bool { \__atableau_draw_border:nn {skew} {skewBorder} }
+ \bool_if:NT \l__atableau_border_bool { \__atableau_draw_border:nn {shape} {borderStyle} }
+
+ % remove dotted rows and columns
+ \seq_if_empty:NF \l__atableau_dotted_rows_seq \__atableau_remove_dotted_tableau_rows:
+ \seq_if_empty:NF \l__atableau_dotted_cols_seq \__atableau_remove_dotted_tableau_cols:
+
+ % add snobs
+ \tl_set:Nn \l__atableau_ribbon_type_tl {snob} % change ribbon type to snob
+ \seq_map_inline:Nn \l__atableau_snobs_seq {\__atableau_add_ribbon:n {##1}}
+}
+
+% ---------------------------------------------------------------------------
+% box and bead coordinates
+
+% usage: \__atableau_update_multi_extrema:n {letter}
+% Update xmax, ymax and ymin using the x#1_fp and y#1_fp
+\cs_new_protected:Npn \__atableau_update_multi_extrema:n #1
+{
+ % adjust xmax, ymin and ymax for multishapes
+ \fp_set:Nn \l__atableau_xmax_fp { max(\l__atableau_xmax_fp, \use:c{l__atableau_x#1_fp}) }
+ \fp_set:Nn \l__atableau_ymax_fp { max(\l__atableau_ymax_fp, \use:c{l__atableau_y#1_fp}) }
+ \fp_set:Nn \l__atableau_ymin_fp { min(\l__atableau_ymin_fp, \use:c{l__atableau_y#1_fp}) }
+}
+
+\cs_new_protected:Npn \__atableau_update_multi_xtrema:n #1
+{
+ % adjust xmax for multishapes
+ \fp_set:Nn \l__atableau_xmax_fp { max(\l__atableau_xmax_fp, \use:c{l__atableau_x#1_fp}) }
+}
+
+% By default, we do not update ymin, ymax and xmax. This only happens for multishapes
+\cs_set_eq:NN \__atableau_update_extrema:n \use_none:n
+
+% usage: \__atableau_set_box_coordinates_normal:nnn <letter> <row> <col>: given the row and columns
+% indices, row and col, define the corresponding coordinates in a tableau
+% - \l__atableau_xl_fp : x-coordinates
+% - \l__atableau_yl_fp : y-coordinate
+% - \l__atableau_name_tl : the node name
+% Used by the tableau and diagram commands. Note that row and col both start
+% from 0, so the (1,1)-box has row=col=0.
+\cs_new_protected:Npn \__atableau_set_box_coordinates_normal:nnn #1 #2 #3
+{
+ \tl_set:Nx \l__atableau_name_tl {\l__atableau_prefix_tl-\int_eval:n{1+#2}-\int_eval:n {1+#3}}
+ \fp_set:cn {l__atableau_x#1_fp} {\l__atableau_x_fp+((#2+0.5)*\l__atableau_tab_row_dx_fp+(#3+0.5)*\l__atableau_tab_col_dx_fp)*\l__atableau_box_wd_fp }
+ \fp_set:cn {l__atableau_y#1_fp} {\l__atableau_y_fp+((#2+0.5)*\l__atableau_tab_row_dy_fp+(#3+0.5)*\l__atableau_tab_col_dy_fp)*\l__atableau_box_ht_fp }
+ \__atableau_update_extrema:n #1
+}
+
+% usage: \__atableau_set_box_coordinates_conjugate:nnn <letter> <row> <col>: given the row and columns
+% indices, row and col, define the corresponding coordinates in the conjugate tableau
+% - \l__atableau_xl_fp : x-coordinates
+% - \l__atableau_yl_fp : y-coordinate
+% - \l__atableau_name_tl : the node name
+% Used by the tableau and diagram commands
+\cs_new_protected:Npn \__atableau_set_box_coordinates_conjugate:nnn #1 #2 #3
+{
+ \tl_set:Nx \l__atableau_name_tl {\l__atableau_prefix_tl-\int_eval:n{1+#3}-\int_eval:n {1+#2}}
+ \fp_set:cn {l__atableau_x#1_fp} {\l__atableau_x_fp+((#3+0.5)*\l__atableau_tab_row_dx_fp+(#2+0.5)*\l__atableau_tab_col_dx_fp)*\l__atableau_box_wd_fp }
+ \fp_set:cn {l__atableau_y#1_fp} {\l__atableau_y_fp+((#3+0.5)*\l__atableau_tab_row_dy_fp+(#2+0.5)*\l__atableau_tab_col_dy_fp)*\l__atableau_box_ht_fp }
+ \__atableau_update_extrema:n #1
+}
+
+% by default , normal coordinates are used
+\cs_set_eq:NN \__atableau_set_box_coordinates:nnn \__atableau_set_box_coordinates_normal:nnn
+
+
+% usage: \__atableau_set_bead_coordinates:nnn <letter> <row> <col>: given the row and columns
+% indices, row and col, define the corresponding coordinates in a tableau or abacus:
+% - \l__atableau_xl_fp : x-coordinates
+% - \l__atableau_yl_fp : y-coordinate
+% - \l__atableau_name_tl : the node name
+% Used by both the tableaux and abacus commands
+\cs_new_protected:Npn \__atableau_set_bead_coordinates:nnn #1 #2 #3
+{
+ \tl_set:Nx \l__atableau_name_tl {\l__atableau_prefix_tl-\fp_to_int:n{#2-1}-\fp_to_int:n{#3}}
+ \fp_set:cn {l__atableau_x#1_fp} {\l__atableau_x_fp+(#2*\l__atableau_ab_row_dx_fp+#3*\l__atableau_ab_col_dx_fp)*\l__atableau_abacus_wd_fp }
+ \fp_set:cn {l__atableau_y#1_fp} {\l__atableau_y_fp+(#2*\l__atableau_ab_row_dy_fp+#3*\l__atableau_ab_col_dy_fp)*\l__atableau_abacus_ht_fp }
+}
+
+% ---------------------------------------------------------------------------
+% tableaux boxes/nodes
+
+\cs_new_protected:Npn \__atableau_valign_bottom:n #1 { \vbox_to_zero:n { #1 \vss } }
+\cs_new_protected:Npn \__atableau_valign_centre:n #1 { \vbox_to_zero:n { \vss #1 \vss } }
+\cs_new_protected:Npn \__atableau_valign_top:n #1 { \vbox_to_zero:n { \vss #1 } }
+\cs_set_eq:NN \__atableau_valign_center:n \__atableau_valign_centre:n
+
+% We use \vbox_to_zero:n and \hbox_overlap_center:n to ensure that an entry
+% does not change the height or width of the node when it is too large.
+\cs_new_protected:Npn \__atableau_entry_math:n #1
+{
+ \__atableau_valign:n
+ {
+ \__atableau_halign:n
+ {
+ \tl_if_blank:VF \tikz@textcolor {\color{\tikz@textcolor}}
+ \tikz@textfont $~#1 $
+ }
+ }
+}
+
+% and a text version
+\cs_new_protected:Npn \__atableau_entry_text:n #1
+{
+ \__atableau_valign:n
+ {
+ \__atableau_halign:n
+ {
+ \tl_if_blank:VF \tikz@textcolor {\color{\tikz@textcolor}}
+ \tikz@textfont #1
+ }
+ }
+}
+
+% By default tableau nodes are typeset in math-mode.
+\cs_set_eq:NN \__atableau_entry:n \__atableau_entry_math:n
+
+% usage: \__atableau_draw_entry:nn [style] {entry}
+% Used by draw_tableau to draw the node entry #2 in the tableau using the style #1
+\cs_new_protected:Npn \__atableau_draw_entry:nn [#1] #2
+{
+ % exit when we reach the end of the row
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ {
+ % record the column index in the shape for drawing the border
+ \seq_put_right:NV \l__atableau_shape_seq \l__atableau_col_int
+ }
+
+ % compute the node name and its (x,y)-coordinates
+ \__atableau_set_box_coordinates:nVV {l} \l__atableau_row_int \l__atableau_col_int
+
+ \tl_if_empty:nTF {#1}
+ { % draw box if it has the default styling
+ \node[aTableau/boxStyle] (\l__atableau_name_tl)
+ at (\fp_use:N\l__atableau_xl_fp, \fp_use:N\l__atableau_yl_fp)
+ {\__atableau_entry:n{#2}};
+ }
+ { % save the node to \l__atableau_styled_nodes_tl if it is styled
+ \tl_put_right:Nx \l__atableau_styled_nodes_tl
+ {
+ \exp_not:N \node [aTableau/boxStyle,#1] (\l__atableau_name_tl)
+ at (\fp_use:N\l__atableau_xl_fp, \fp_use:N\l__atableau_yl_fp)
+ {\exp_not:N\__atableau_entry:n{#2}};
+ }
+ }
+
+ % look for the next entry, or finish
+ \int_incr:N \l__atableau_col_int
+ \__atableau_peek_tableau:w
+}
+
+% ---------------------------------------------------------------------------
+% diagrams
+
+% usage: \__atableau_draw_diagram:n {partition}
+\cs_new_protected:Npn \__atableau_draw_diagram:n #1
+{
+ % convert #1 to the partition \l__atableau_shape_seq
+ \__atableau_set_partition:nn {shape} {#1}
+
+ % set the skew shape for shifted tableaux
+ \bool_if:NT \l__atableau_shifted_bool
+ {
+ \seq_clear:N \l__atableau_skew_seq
+ \seq_map_inline:Nn \l__atableau_shape_seq
+ {
+ \seq_put_right:No \l__atableau_skew_seq {\int_use:N \l__atableau_row_int}
+ \int_incr:N \l__atableau_row_int
+ }
+ \int_zero:N \l__atableau_row_int
+ }
+
+ % depending on \l__atableau_show_tl, generate the tableau entries
+ \str_case:VnF \l__atableau_show_tl
+ {
+ {contents} { \__atableau_shape_to_content:N \l__atableau_shape_seq }
+ {last} { \__atableau_shape_to_last:N \l__atableau_shape_seq }
+ {hooks} { \__atableau_shape_to_hook:N \l__atableau_shape_seq }
+ {first} { \__atableau_shape_to_first:N \l__atableau_shape_seq }
+ {residues} { \__atableau_shape_to_residue:N \l__atableau_shape_seq }
+ {} { \__atableau_diagram_for_shape:N \l__atableau_shape_seq }
+ }
+ {
+ \msg_error:nnx {aTableau} {unrecognised-entries} {\l__atableau_show_tl}
+ }
+ \__atableau_draw_tableau:V \l__atableau_entries_tl
+}
+
+
+% ---------------------------------------------------------------------------
+% multitableau and their diagrams
+
+% usage: \__atableau_draw_multishape:n diagram|tableau
+% Draw a multitableau or multidiagram. Most of the work is in calculating the
+% x-coordinates of the origins and each diagram, their separators and the
+% maximal y-coordinates, for drawing the delimiters. We also need to set
+% various keys for the components, so that they work correctly.
+\cs_new_protected:Npn \__atableau_draw_multishape:n #1
+{
+ % save the prefix name so that we can modify it
+ \tl_set_eq:NN \l__atableau_multiprefix_tl \l__atableau_prefix_tl
+
+ % check for conjugation
+ \bool_if:NT \l__atableau_conjugate_bool { \seq_reverse:N \l__atableau_component_seq }
+
+ % reset the variables that we need
+ \int_zero:N \l__atableau_component_int % component index
+
+ % We will increment x_fp to give the origins of the component diagrams.
+ % For now we record the position of the x-coordinates of the left brace,
+ % which will be placed after the diagrams have been drawn we first have to
+ % determine their height.
+ \seq_clear:N \l__atableau_xsep_seq
+ \seq_put_right:Nx \l__atableau_xsep_seq {\fp_to_decimal:N\l__atableau_x_fp}
+
+ % keep track of min/max y-coordinates used and max x-coordinate
+ \fp_set_eq:NN \l__atableau_xmax_fp \l__atableau_x_fp
+ \fp_set:Nn \l__atableau_ymax_fp {\l__atableau_y_fp + \l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp/2} % middle of box
+ \fp_set_eq:NN \l__atableau_ymin_fp \l__atableau_ymax_fp
+
+ \seq_map_inline:Nn \l__atableau_component_seq
+ {
+ % increment component and set prefix, charge, skew, ribbons and snobs
+ \int_incr:N \l__atableau_component_int
+
+ % update ymin, ymax and xmax (re-enable each time as this is disabled when placing ribbons)
+ \fp_compare:nNnTF {\l__atableau_rows_fp} = {0}
+ { \cs_set_eq:NN \__atableau_update_extrema:n \__atableau_update_multi_extrema:n } % update xmax, ymin, ymax
+ { \cs_set_eq:NN \__atableau_update_extrema:n \__atableau_update_multi_xtrema:n } % update only xmax
+
+ % change the node prefix to include the component index
+ \tl_set:No \l__atableau_prefix_tl {\l__atableau_multiprefix_tl-\int_use:N\l__atableau_component_int}
+
+ % charge defaults to zero if not set
+ \int_set:Nn \l__atableau_charge_int {0\seq_item:NV \l__atableau_charge_seq \l__atableau_component_int}
+
+ % set the multi-component keys from the corresponding multi sequence
+ \clist_map_inline:nn {dotted_rows, dotted_cols, paths, ribbons, snobs}
+ {
+ % if multi####1 is empty then clear the ####1 sequence, otherwise set it equal to component value
+ \seq_if_empty:cTF {l__atableau_multi####1_seq}
+ { \seq_clear:c {l__atableau_####1_seq} }
+ {
+ \tl_set:Nx \l_tmpb_tl {\seq_item:cV {l__atableau_multi####1_seq} \l__atableau_component_int}
+ \seq_set_from_clist:co {l__atableau_####1_seq} {\l_tmpb_tl}
+ }
+ }
+
+ % labels are handled separately because they are not sequences
+ \seq_if_empty:NTF \l__atableau_multilabel_seq
+ { \seq_clear:N \l__atableau_label_seq }
+ {
+ \tl_set:Nx \l_tmpb_tl {\seq_item:NV \l__atableau_multilabel_seq \l__atableau_component_int}
+ \tl_set:No \l__atableau_label_tl {\l_tmpb_tl}
+ }
+
+ % skew is handled separately because it uses set_partition
+ \seq_if_empty:NTF \l__atableau_multiskew_seq
+ { \seq_clear:N \l__atableau_skew_seq }
+ {
+ \tl_set:Nx \l_tmpb_tl {\seq_item:NV \l__atableau_multiskew_seq \l__atableau_component_int}
+ \__atableau_set_partition:no {skew} {\l_tmpb_tl}
+ }
+
+ % determine the coordinates for the diagram/tableau
+ % - \l__atableau_c_int: number of columns in first row
+ % - \l__atableau_r_int: number of rows in components
+ \bool_if:nTF { \str_if_empty_p:n {##1} || \str_if_eq_p:nn {##1} {...} }
+ {
+ \int_set:Nn \l__atableau_c_int {1}
+ \int_set:Nn \l__atableau_r_int {1}
+ }
+ {
+ % the component is nonempty
+ \tl_if_eq:nnTF {#1} {diagram}
+ {
+ \__atableau_set_partition:nn {shape} {##1}
+ \int_set:No \l__atableau_c_int {\seq_item:Nn \l__atableau_shape_seq {1}+0\seq_item:Nn \l__atableau_skew_seq {1}}
+
+ % set r_int equal to the number of nonzero rows in shape_seq
+ \int_set:No \l__atableau_r_int { \seq_count:N \l__atableau_shape_seq }
+ }
+ { % coordinates for tableaux
+ \seq_set_from_clist:Nn \l_tmpa_seq {##1}
+ \int_set:No \l__atableau_c_int {0\seq_item:Nn \l__atableau_skew_seq {1}} % initialise to skew length
+ \tl_set:Nx \l_tmpc_tl {\seq_item:Nn \l_tmpa_seq {1}} % first row of tableau
+ \__atableau_count_row:x \l_tmpc_tl % length of first row + skew
+
+ % set r_int equal to the number of nonzero rows in shape_seq
+ \int_set:No \l__atableau_r_int { \seq_count:N \l_tmpa_seq }
+ }
+ }
+
+ % now that we have the coordinates we need, we compute the
+ % x-coordinates of the diagram origin and the separators
+
+ % need to switch for conjugate partitions
+ \bool_if:NTF \l__atableau_conjugate_bool
+ { % conjugating
+ % the origin is c * col_dx units from the separator + xoffset
+ \fp_add:Nn \l__atableau_x_fp
+ {
+ abs(\l__atableau_c_int*\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp) % number of columns
+ + 0\seq_item:NV \l__atableau_xoffsets_seq \l__atableau_component_int % x-offset
+ }
+ % the next separator is is r * row_dx units from the origin
+ \fp_set:Nn \l__atableau_xsep_fp {
+ abs(\l__atableau_r_int*\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp)
+ + \l__atableau_separation_fp
+ }
+
+ % compute maximum height of the diagram
+ \fp_set:Nn \l__atableau_yb_fp
+ {
+ \l__atableau_c_int*\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp
+ + \l__atableau_r_int*abs(\l__atableau_tab_col_dy_fp)*\l__atableau_box_ht_fp
+ + 0\seq_item:NV \l__atableau_yoffsets_seq \l__atableau_component_int
+ }
+ }
+ { % not conjugating
+ % the origin is r * row_dx units from the separator + xoffset
+ \fp_add:Nn \l__atableau_x_fp
+ {
+ abs(\l__atableau_r_int*\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp) % number of columns
+ + 0\seq_item:NV \l__atableau_xoffsets_seq \l__atableau_component_int % x-offset
+ }
+ % the next separator is is c * col_dx units from the origin
+ \fp_set:Nn \l__atableau_xsep_fp
+ {
+ abs(\l__atableau_c_int*\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp) % number of columns
+ + \l__atableau_separation_fp
+ }
+ % compute maximum height of the diagram
+ \fp_set:Nn \l__atableau_yb_fp
+ {
+ \l__atableau_r_int*\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp
+ + \l__atableau_c_int*\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp
+ + 0\seq_item:NV \l__atableau_yoffsets_seq \l__atableau_component_int
+ }
+ }
+
+ % Having determined the positions of the diagram origins and separators, we are ready to draw the diagram
+ % First set the y-coordinate for the origin of the current component
+ \fp_add:Nn \l__atableau_y_fp {0\seq_item:NV \l__atableau_yoffsets_seq \l__atableau_component_int}
+
+ % special processing for empty diagrams and ...
+ \str_case:nnF {##1}
+ {
+ {}
+ {
+ % an empty diagram -> \l__atableau_empty_tl
+ \__atableau_set_box_coordinates:nnn {a} {0} {0}
+ \node[aTableau/separatorSymbol] at (\fp_use:N \l__atableau_xa_fp, \fp_use:N \l__atableau_ya_fp){\l__atableau_empty_tl};
+ }
+ {...}
+ {
+ % insert dots. ?? Replace \cdots with \l__atableau_dots_tl ??
+ \__atableau_set_box_coordinates:nnn {a} {0} {0}
+ \node[aTableau/separatorSymbol] at (\fp_use:N \l__atableau_xa_fp, \fp_use:N \l__atableau_ya_fp){$\cdots$};
+ }
+ }
+ {
+ % draw the diagram/tableau
+ \use:c {__atableau_draw_#1:n} {##1}
+ }
+
+ % increment the origin by the separation distance and record the
+ % x-coordinate of the separator
+ \fp_set:Nn \l__atableau_x_fp { \l__atableau_xmax_fp+\l__atableau_box_wd_fp/2+\l__atableau_separation_fp }
+ \seq_put_right:Nx \l__atableau_xsep_seq {\fp_to_decimal:N\l__atableau_x_fp}
+
+ % add the separation distance to x_fp for the next component
+ \fp_add:NV \l__atableau_x_fp \l__atableau_separation_fp % separation
+
+ } % end of seq_map_inline to draw component diagrams/tableau
+
+ % All of the component diagrams/tableaux have been drawn
+ % It remains to add the separators. First we adjust ymin and ymax
+ \bool_if:NT \l__atableau_separators_bool
+ {
+
+ % when rows_fp is nonzero it sets the maximum y-coordinate, otherwise we
+ % need to adjust ymin and ymax by half the box height
+ \fp_compare:nNnTF {\l__atableau_rows_fp} > {0}
+ {
+ \fp_compare:nNnTF {\l__atableau_tab_row_dy_fp} > {0}
+ {
+ \fp_add:Nn \l__atableau_ymax_fp { (\l__atableau_rows_fp-0.5)*\l__atableau_box_ht_fp }
+ \fp_add:Nn \l__atableau_ymin_fp { -0.5*\l__atableau_box_ht_fp }
+ }
+ {
+ \fp_add:Nn \l__atableau_ymin_fp { (0.5-\l__atableau_rows_fp)*\l__atableau_box_ht_fp }
+ \fp_add:Nn \l__atableau_ymax_fp { 0.5*\l__atableau_box_ht_fp }
+ }
+ }
+ {
+ % adjust ymin and ymax count as they count from the centre of the box
+ \fp_add:Nn \l__atableau_ymax_fp { \l__atableau_box_ht_fp/2}
+ \fp_add:Nn \l__atableau_ymin_fp {-\l__atableau_box_ht_fp/2}
+ }
+
+ \fp_set:Nn \l__atableau_y_fp {(\l__atableau_ymin_fp+\l__atableau_ymax_fp)/2} % midway between ymin and ymax
+ \fp_set:Nn \l__atableau_ymax_fp { \l__atableau_ymax_fp-\l__atableau_ymin_fp } % maximum height
+
+ % add left delimiter: need to use \path to set the colour
+ \seq_pop_left:NN \l__atableau_xsep_seq \l_tmpa_tl
+ \tl_if_blank:VF \l__atableau_left_delimiter_tl
+ {
+ \path[aTableau/delimiterPath] (\fp_eval:n{\l_tmpa_tl-\l__atableau_separation_fp/2}, \fp_use:N \l__atableau_y_fp)
+ node[aTableau/leftDelimiter] {};
+ }
+
+ % add right delimiter
+ \seq_pop_right:NN \l__atableau_xsep_seq \l_tmpa_tl
+ \tl_if_blank:VF \l__atableau_right_delimiter_tl
+ {
+ \path[aTableau/delimiterPath] (\fp_eval:n{\l_tmpa_tl-\l__atableau_separation_fp/2}, \fp_use:N \l__atableau_y_fp)
+ node[aTableau/rightDelimiter] {};
+ }
+
+ % the internal separators
+ \tl_set:Ne \l_tmpa_tl {\fp_to_decimal:N \l__atableau_ymin_fp } % ymin
+ \tl_set:Ne \l_tmpb_tl {\fp_to_decimal:n {\l__atableau_y_fp + \l__atableau_ymax_fp/2}} % ymax
+ \seq_map_inline:Nn \l__atableau_xsep_seq
+ {
+ % add the separator
+ \str_case:VnF \l__atableau_separator_tl
+ {
+ {|} { \draw[aTableau/separatorLine](##1,\l_tmpa_tl)--(##1,\l_tmpb_tl); }
+ }
+ { % any other separator is assumed to be text
+ \node[aTableau/separatorSymbol] at (##1,\fp_use:N \l__atableau_y_fp){\l__atableau_separator_tl};
+ }
+ }
+ }
+}
+
+
+% usage: \__atableau_multidiagram:n {entries}
+% The entries are first primarily because the \Diagram commands needs
+% to force the entries to expand
+\cs_new_protected:Npn \__atableau_multidiagram:n #1
+{
+ % separate the component partitions
+ \seq_set_split:Nnn \l__atableau_component_seq {|} {#1}
+
+ % when entries=last, we need to set the charge
+ \tl_if_eq:NnT \l__atableau_show_tl {last}
+ {
+ \seq_clear:N \l__atableau_charge_seq
+ \int_zero:N \l__atableau_c_int % cumulative total of component sizes
+ \seq_set_eq:NN \l_tmpc_seq \l__atableau_component_seq
+ \seq_reverse:N \l_tmpc_seq
+ \seq_map_inline:Nn \l_tmpc_seq
+ {
+ \seq_put_left:No \l__atableau_charge_seq {\int_use:N \l__atableau_c_int}
+ \__atableau_set_partition:nn {shape} {##1}
+ \seq_map_inline:Nn \l__atableau_shape_seq { \int_add:Nn \l__atableau_c_int {####1} }
+ }
+ }
+
+ % determine the coordinates of the components of the diagram
+ \__atableau_draw_multishape:n {diagram}
+}
+
+% usage: \__atableau_multitableau:n {entries}
+% The entries are first primarily because the \Diagram commands need
+% to force the entries to expand
+\cs_new_protected:Npn \__atableau_multitableau:n #1
+{
+ % separate the entries of the component tableaux
+ \seq_set_split:Nnn \l__atableau_component_seq {|} {#1}
+
+ % determine the coordinates of the components of the tableau
+ \__atableau_draw_multishape:n {tableau}
+}
+
+% ---------------------------------------------------------------------------
+% Ribbon tableaux
+
+% usage: \__atableau_ribbon_tableau:n {ribbons}
+% Draw a ribbon tableau. The ribbons are specified by
+% (ribbon style) ij sequences of r's and c's with optional style and
+% with text as a subscript. Here i and j are the row and column
+% indices of the head of the ribbon
+\cs_new_protected:Npn \__atableau_ribbon_tableau:n #1
+{
+ % set the star style
+ \tl_set:Nn \l__atableau_starstyle_tl {aTableau/tableauStarStyle}
+
+ % record the shape as we draw the border
+ \seq_clear:N \l__atableau_shape_seq
+ \cs_set_eq:NN \__atableau_update_shape: \__atableau_update_ribbon_tableau_shape:
+
+ % draw the ribbon tableau by drawing each of the ribbons
+ \tl_set:Nn \l__atableau_ribbon_type_tl {ribbon} % change ribbon type to ribbon
+ \clist_map_inline:nn {#1} { \__atableau_add_ribbon:n {##1} }
+
+ % draw the tableau border, adding associated bells and whistles
+ \__atableau_finalise_tableau:
+}
+
+% usage: \__atableau_add_ribbon:n {ribbon} add a ribbon to the tableau
+% The code for adding ribbons is slightly different dependning onf on whether
+% \l__atableau_ribbbon_ty[e is equal to 'ribbon' or 'path'
+\cs_new_protected:Npn \__atableau_add_ribbon:n #1
+{
+ % reset the sequences that store the ribbon specifications data
+ \seq_clear:N \l__atableau_texts_seq % will contain node text
+ \seq_clear:N \l__atableau_styles_seq % will contain node styles
+ \seq_clear:N \l__atableau_rcs_seq % will contain node (row,col)-indices
+ \__atableau_peek_ribbon_style:w #1 \q_recursion_tail \q_recursion_stop
+}
+
+% usage: \__atableau_peek_ribbon_style:w {ribbon specifications}
+% look for (ribbon) style inside parentheses: (style)
+\cs_new_protected:Npn \__atableau_peek_ribbon_style:w
+{
+ \peek_remove_spaces:n { % ignore spaces
+ \peek_charcode:NTF (
+ { \__atableau_save_ribbon_style:n }
+ { \__atableau_save_ribbon_style:n ()}
+ }
+}
+
+% usage: \__atableau_save_ribbon_style:n {style}
+% read the style (style) and save in \l__atableau_ribbon_style_tl
+% and then peek for [style]rc...
+\cs_new_protected:Npn \__atableau_save_ribbon_style:n (#1)
+{
+ \tl_set:Nn \l__atableau_ribbon_style_tl {#1}
+ \__atableau_peek_style:nw {save_ribbon_head:nnn}
+}
+
+
+% usage: \__atableau_initialise_path_head:
+% Start \l__atableau_ribbon_path_tl for a path
+\cs_new_protected:Nn \__atableau_initialise_path_head:
+{ % adding a ribbon path
+ \tl_set:Nx \l__atableau_ribbon_path_tl
+ {
+ (\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp)
+ node[aTableau/pathBox,\l__atableau_ribbon_style_tl]{\__atableau_entry:n{\l__atableau_path_box_tl}}
+ }
+}
+
+% usage: \__atableau_initialise_ribbon_head:
+% Start \l__atableau_ribbon_path_tl for a ribbon
+\cs_new_protected:Nn \__atableau_initialise_ribbon_head:
+{
+ % 1. Make (xl,yl) the top corner of the ribbon and add it
+ \fp_add:Nn \l__atableau_xl_fp { 0.5*(\l__atableau_tab_col_dx_fp-\l__atableau_tab_row_dx_fp)*\l__atableau_box_wd_fp }
+ \fp_add:Nn \l__atableau_yl_fp { 0.5*(\l__atableau_tab_col_dy_fp-\l__atableau_tab_row_dy_fp)*\l__atableau_box_ht_fp }
+ \tl_set:Nx \l__atableau_ribbon_path_tl { (\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp) }
+
+ % 2. Make (xa,ya) the top left of the ribbon and add it on the left (decreasing column)
+ \fp_set:Nn \l__atableau_xa_fp {\l__atableau_xl_fp-\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_set:Nn \l__atableau_ya_fp {\l__atableau_yl_fp-\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_left:Nx \l__atableau_ribbon_path_tl { (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)-- }
+
+ % 3. Make (xb,yb) the bottom right corner and add it on the right (increasing row)
+ \fp_set:Nn \l__atableau_xb_fp {\l__atableau_xl_fp+\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_set:Nn \l__atableau_yb_fp {\l__atableau_yl_fp+\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_right:Nx \l__atableau_ribbon_path_tl { --(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp) }
+}
+
+% usage: \__atableau_save_ribbon_head:nnnn {path/ribbon} [style] {row index} {col index}
+% save the style, row and column indices for the head of the ribbon
+% and then compute the coordinates of the three "external nodes" in the
+% head.
+\cs_new_protected:Npn \__atableau_save_ribbon_head:nnn [#1] #2 #3
+{
+ % check for syntax errors to prevent an endless loop
+ \quark_if_recursion_tail_stop_do:nn {#2} { \msg_error:nnn {aTableau} {invalid-ribbon-head} {no~x-coordinate~given} }
+ \quark_if_recursion_tail_stop_do:nn {#3} { \msg_error:nnn {aTableau} {invalid-ribbon-head} {no~y-coordinate~given} }
+
+ % save any style
+ \seq_put_right:Nx \l__atableau_styles_seq {#1}
+
+ % record the row and column indices of the head
+ \int_set:No \l__atableau_row_int { \int_eval:n {#2-1} }
+ \int_set:No \l__atableau_col_int { \int_eval:n {#3-1} }
+ \seq_put_right:NV \l__atableau_rcs_seq \l__atableau_row_int
+ \seq_put_right:NV \l__atableau_rcs_seq \l__atableau_col_int
+
+ % update the shape to include the head node (#3,#4)
+ \__atableau_update_shape:
+
+ % add initial coordinates to \l__atableau_ribbon_path_tl
+ \__atableau_set_box_coordinates:nVV {l} \l__atableau_row_int \l__atableau_col_int
+
+ % initialise the start of the path/ribbon
+ \use:c {__atableau_initialise_ \l__atableau_ribbon_type_tl _head:}
+
+ %\message{row=\int_use:N\l__atableau_row_int,~col=\int_use:N\l__atableau_col_int}
+ \__atableau_peek_ribbon_text:w
+}
+
+% usage: \__atableau_peek_ribbon_text:nw {path/ribbon}
+% peek for subscripted text _{text} in the ribbon
+\cs_new_protected:Npn \__atableau_peek_ribbon_text:w
+{
+ \peek_remove_spaces:n { % ignore spaces
+ \peek_charcode_remove:NTF _
+ { \__atableau_save_ribbon_text:n }
+ {
+ \seq_put_right:Nn \l__atableau_texts_seq {} % empty text
+ \__atableau_peek_style:nw {save_ribbon:nn}
+ }
+ }
+}
+
+% usage: \__atableau_save_ribbon_text:n {text}
+% save any text for a rode in the ribbon in \l__atableau_texts_seq
+\cs_new_protected:Npn \__atableau_save_ribbon_text:n #1
+{
+ \seq_put_right:No \l__atableau_texts_seq {#1}
+ \__atableau_peek_style:nw {save_ribbon:nn}
+}
+
+% usage: \__atableau_add_to_ribbon:n
+% Extend a ribbon path. Here #1 is either r or c
+\cs_new_protected:Npn \__atableau_extend_ribbon:n #1
+{
+ \str_case:enF {#1}
+ {
+ {c} { % move back one column
+ \int_decr:N \l__atableau_col_int
+
+ % Move (xa,ya) back one column add it to the ribbon on the left
+ \fp_sub:Nn \l__atableau_xa_fp {\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_sub:Nn \l__atableau_ya_fp {\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_left:Nx \l__atableau_ribbon_path_tl { (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)-- }
+
+ % Move (xb,xb) back one column add it to the ribbon on the right
+ \fp_sub:Nn \l__atableau_xb_fp {\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_sub:Nn \l__atableau_yb_fp {\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_right:Nx \l__atableau_ribbon_path_tl { --(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp) }
+ }
+ {r} { % move forward one row
+ \int_incr:N \l__atableau_row_int
+
+ % Move (xa,ya) forward one row add it to the ribbon on the left
+ \fp_add:Nn \l__atableau_xa_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_left:Nx \l__atableau_ribbon_path_tl { (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)-- }
+
+ % Move (xb,xb) forward one row add it to the ribbon on the right
+ \fp_add:Nn \l__atableau_xb_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_yb_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_right:Nx \l__atableau_ribbon_path_tl { --(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp) }
+ }
+ }
+ {
+ \msg_error:nnx {aTableau} {invalid-ribbon-specification} {#1}
+ }
+
+}
+
+% usage: \__atableau_add_to_path:n
+% Extend a ribbon path. Here #1 is either r or c
+\cs_new_protected:Npn \__atableau_extend_path:n #1
+{
+
+ % the ribbon hasn't finished, so move row and col according to the ribbon
+ % specification and update the nodes (xa,ya) and (xb,yb) in the ribbon
+ \str_case:enF {#1}
+ {
+ {c} { % move back one column
+ \int_decr:N \l__atableau_col_int
+
+ \fp_sub:Nn \l__atableau_xl_fp {\l__atableau_tab_col_dx_fp*\l__atableau_box_wd_fp}
+ \fp_sub:Nn \l__atableau_yl_fp {\l__atableau_tab_col_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_right:Nx \l__atableau_ribbon_path_tl
+ {
+ --(\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp)
+ node[aTableau/pathBox,\l__atableau_ribbon_style_tl]{\__atableau_entry:n{\l__atableau_path_box_tl}}
+ }
+ }
+ {r} { % move forward one row
+ \int_incr:N \l__atableau_row_int
+
+ \fp_add:Nn \l__atableau_xl_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_yl_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_right:Nx \l__atableau_ribbon_path_tl
+ {
+ --(\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp)
+ node[aTableau/pathBox,\l__atableau_ribbon_style_tl]{\__atableau_entry:n{\l__atableau_path_box_tl}}
+ }
+ }
+ }
+ {
+ \msg_error:nnx {aTableau} {invalid-ribbon-specification} {#1}
+ }
+}
+
+% For each successive r and c in the ribbon specification, determine the
+% surrpouding coordinates in the ribbon and save any custom styles in
+% \l__atableau_styles_seq and then repeat
+\cs_new_protected:Npn \__atableau_save_ribbon:nn [#1] #2
+{
+ % draw the ribbon when we run out of nodes
+ \quark_if_recursion_tail_stop_do:nn {#2} { \__atableau_draw_ribbon: }
+
+ % Add the new coordinate(s) to \l__atableau_ribbon_path_tl. This is
+ % different for ribbons and paths
+ \use:c {__atableau_extend_ \l__atableau_ribbon_type_tl :n} {#2}
+
+ % update the shape to include the new node
+ \__atableau_update_shape:
+
+ % save the style and row and column indices
+ \seq_put_right:No \l__atableau_styles_seq {#1} % record the style of the head
+ \seq_put_right:NV \l__atableau_rcs_seq \l__atableau_row_int % record the row of the node
+ \seq_put_right:NV \l__atableau_rcs_seq \l__atableau_col_int % record the column of the node
+
+ % check to see if this node has any text
+ \__atableau_peek_ribbon_text:w
+}
+
+
+% update the shape of the ribbon tableau using the current values of
+% \l__atableau_row_int and \l__atableau_col_int
+\cs_new_protected:Nn \__atableau_update_ribbon_tableau_shape:
+{
+ % ensure that \l__atableau_shape_seq has at least a 0 in each row
+ \int_step_inline:nn { \l__atableau_row_int+1 - \seq_count:N \l__atableau_shape_seq }
+ {
+ \seq_put_right:Nn \l__atableau_shape_seq {0}
+ }
+ % for shifted tableaux we also need to ensure that skew is big enough
+ \bool_if:NT \l__atableau_shifted_bool
+ {
+ \int_set:Nn \l_tmpa_int {\seq_count:N \l__atableau_skew_seq}
+ \int_step_inline:nn { \l__atableau_row_int+1 - \l_tmpa_int }
+ {
+ \seq_put_right:Nx \l__atableau_skew_seq {\int_eval:n{\l_tmpa_int+##1-1 }}
+ }
+ }
+ \int_compare:nNnT {0\seq_item:Nn \l__atableau_shape_seq {\l__atableau_row_int+1}} < {\l__atableau_col_int+1}
+ {
+ \seq_set_item:Nox \l__atableau_shape_seq {\l__atableau_row_int+1} { \int_eval:n{\l__atableau_col_int+1} }
+ }
+}
+
+% usage: \__atableau_finalise_ribbon:n
+% Add the final node to the ribbon
+\cs_new_protected:Nn \__atableau_finalise_ribbon:
+{
+ % Add the last node to the ribbon
+ \fp_add:Nn \l__atableau_xa_fp {\l__atableau_tab_row_dx_fp*\l__atableau_box_wd_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l__atableau_tab_row_dy_fp*\l__atableau_box_ht_fp}
+ \tl_put_left:Nx \l__atableau_ribbon_path_tl { (\fp_use:N\l__atableau_xa_fp, \fp_use:N\l__atableau_ya_fp)-- }
+
+ % add a closing cycle
+ \tl_put_right:Nn \l__atableau_ribbon_path_tl {--cycle}
+}
+
+
+% usage: \__atableau_finalise_path:n
+% We do not need to do anything to finalise a path
+\cs_set_eq:NN \__atableau_finalise_path:n \prg_do_nothing:
+
+% by default, snobs have the same styles and coordinates as ribbons
+\cs_set_eq:NN \__atableau_extend_snob:n \__atableau_extend_ribbon:n
+\cs_set_eq:NN \__atableau_finalise_snob: \__atableau_finalise_ribbon:
+\cs_set_eq:NN \__atableau_initialise_snob_head: \__atableau_initialise_ribbon_head:
+
+% \__atableau_draw_ribbon: use the various sequences we have constructed
+% to draw the ribbon. We first place the nodes with default styling and
+% no text, then draw the ribbon with its supplied style and then,
+% finally, add the nodes with custom styling or text.
+\cs_new_protected:Nn \__atableau_draw_ribbon:
+{
+
+ \use:c { __atableau_finalise_ \l__atableau_ribbon_type_tl :}
+
+ % We want to first draw the ribbon, with its outline and any filling, and
+ % then place the node with the default styling (or unstyled), and styled
+ % nodes in the ribbon. To do this we build the two token lists
+ % \l__atableau_unstyled_nodes_tl and \l__atableau_styled_nodes_tl for these
+ % two types of nodes
+ \tl_clear:N \l__atableau_styled_nodes_tl
+ \tl_clear:N \l__atableau_unstyled_nodes_tl
+
+ % We need to add ribbon_node to every box in a ribbon, so we do the
+ % check here rather than in \seq_map_inline:Nn
+ \tl_if_eq:VnTF \l__atableau_ribbon_type_tl {path}
+ { \tl_clear:N \l_tmpc_tl }
+ { \tl_set_eq:Nc \l_tmpc_tl { l__atableau_ \l__atableau_ribbon_type_tl _box_tl } }
+
+ \seq_map_inline:Nn \l__atableau_styles_seq
+ {
+ % pop the text and row and column indices
+ \seq_pop_left:NN \l__atableau_texts_seq \l_tmpa_tl % text
+ \seq_pop_left:NN \l__atableau_rcs_seq \l_tmpb_tl % row index
+ \int_set:Nn \l__atableau_row_int {\l_tmpb_tl}
+ \seq_pop_left:NN \l__atableau_rcs_seq \l_tmpb_tl % column index
+ \int_set:Nn \l__atableau_col_int {\l_tmpb_tl}
+
+ % compute the box coordinates
+ \__atableau_set_box_coordinates:nVV {l} \l__atableau_row_int \l__atableau_col_int
+ \tl_if_empty:eTF {##1\l_tmpa_tl}
+ { % nodes with default style and no text are added to \l__atableau_unstyled_nodes_tl
+ \tl_put_right:Nx \l__atableau_unstyled_nodes_tl
+ {
+ \exp_not:N \node [aTableau/\l__atableau_ribbon_type_tl Box](\l__atableau_name_tl)
+ at (\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp)
+ { \exp_not:N \__atableau_entry:n{\l_tmpc_tl }};
+ }
+ }
+ { % nodes with styling are added to \l__atableau_styled_nodes_tl
+ \tl_put_right:Nx \l__atableau_styled_nodes_tl
+ {
+ \exp_not:N \node [aTableau/\l__atableau_ribbon_type_tl Box,##1](\l__atableau_name_tl)
+ at (\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp)
+ {\exp_not:N \__atableau_entry:n{\l_tmpa_tl}};
+ }
+ }
+ }
+ % draw the ribbon, applying any style
+ \exp_last_unbraced:Ne\draw { [aTableau/\l__atableau_ribbon_type_tl Style,\l__atableau_ribbon_style_tl] } \l__atableau_ribbon_path_tl;
+
+ % finally, add the unstyled and the styled nodes on top of the ribbon
+ \l__atableau_unstyled_nodes_tl
+ \l__atableau_styled_nodes_tl
+}
+
+
+% ---------------------------------------------------------------------------
+
+% abacuses
+% usage: \__atableau_draw_abacus_end:nnn {abacus_top/abacus_bottom} % {0/row index} {±1}
+% Draw the top/bottom on gthe abacus. Here #1 is either
+% \l__atableau_abacus_top_tl or \l__atableau_abacus_bottom_tl and #2 is
+% either 0, for top, or the row index of the last row, for bottom
+\cs_new_protected:Npn \__atableau_draw_abacus_end:nnn #1 #2 #3
+{
+ \str_case:Vn #1
+ {
+ {-}
+ { % draw a line
+ \__atableau_set_bead_coordinates:non {a} {#2} {0}
+ \__atableau_set_bead_coordinates:noo {b} {#2} { \int_eval:n {\l__atableau_cols_int-1} }
+ \draw[aTableau/abacusEnds]
+ (\fp_eval:n{\l__atableau_xa_fp-\l__atableau_ab_col_dx_fp*\l__atableau_abacus_wd_fp/2},
+ \fp_eval:n{\l__atableau_ya_fp-\l__atableau_ab_col_dy_fp*\l__atableau_abacus_ht_fp/2})
+ -- (\fp_eval:n{\l__atableau_xb_fp+\l__atableau_ab_col_dx_fp*\l__atableau_abacus_wd_fp/2},
+ \fp_eval:n{\l__atableau_yb_fp+\l__atableau_ab_col_dy_fp*\l__atableau_abacus_ht_fp/2});
+
+ % set default "row height" of the runner labels for use below
+ \fp_set:Nn \l_tmpa_fp {-0.4}
+ }
+ {_}
+ { % draw a line
+ \__atableau_set_bead_coordinates:non {a} {#2} {0}
+ \__atableau_set_bead_coordinates:noo {b} {#2} { \int_eval:n {\l__atableau_cols_int-1} }
+ \draw[aTableau/abacusEnds] (\fp_use:N\l__atableau_xa_fp, \fp_use:N\l__atableau_ya_fp)
+ -- (\fp_use:N\l__atableau_xb_fp, \fp_use:N\l__atableau_yb_fp);
+
+ % set default "row height" of the runner labels for use below
+ \fp_set:Nn \l_tmpa_fp {-0.4}
+ }
+ {.}
+ { % draw dots
+ \int_step_inline:nn {\l__atableau_cols_int}
+ {
+ \seq_if_in:NeF \l__atableau_dotted_cols_seq { \int_eval:n{##1-1} }
+ {
+ % draw the abacus runners from (xa,ya) to (xb,yb)
+ \__atableau_set_bead_coordinates:noo {a} { #2 } { \int_eval:n{##1-1} }
+ \__atableau_set_bead_coordinates:noo {b} { #3 } { \int_eval:n{##1-1} }
+ \draw[aTableau/abacusEnds, dotted] (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+ }
+
+ % set default "row height" of the runner labels for use below
+ \fp_set:Nn \l_tmpa_fp {-1.4}
+ }
+ {>}
+ { % draw dots
+ \int_step_inline:nn {\l__atableau_cols_int}
+ {
+ \seq_if_in:NeF \l__atableau_dotted_cols_seq { \int_eval:n{##1-1} }
+ {
+ % draw the abacus runners from (xa,ya) to (xb,yb)
+ \int_compare:nNnTF {#2} = {0}
+ {
+ \__atableau_set_bead_coordinates:noo {a} { \fp_eval:n{#2+0.5} } { \fp_eval:n{##1-1} }
+ \__atableau_set_bead_coordinates:noo {b} { \fp_eval:n{#3+0.5} } { \fp_eval:n{##1-1} }
+ }
+ {
+ \__atableau_set_bead_coordinates:noo {a} { \fp_eval:n{#2-0.5} } { \fp_eval:n{##1-1} }
+ \__atableau_set_bead_coordinates:noo {b} { \fp_eval:n{#3-0.5} } { \fp_eval:n{##1-1} }
+ }
+ \draw[aTableau/abacusEnds,->] (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+ }
+
+ % set default "row height" of the runner labels for use below
+ \fp_set:Nn \l_tmpa_fp {-0.8}
+ }
+
+ {*}
+ { % draw dots
+ \int_step_inline:nn {\l__atableau_cols_int}
+ {
+ \seq_if_in:NeF \l__atableau_dotted_cols_seq { \int_eval:n{##1-1} }
+ {
+ % draw the abacus runners from (xa,ya) to (xb,yb)
+ \int_compare:nNnTF {#2} = {0}
+ {
+ \__atableau_set_bead_coordinates:noo {a} { \fp_eval:n{#2} } { \fp_eval:n{##1-1} }
+ \__atableau_set_bead_coordinates:noo {b} { \fp_eval:n{#3-0.5} } { \fp_eval:n{##1-1} }
+ }
+ {
+ \__atableau_set_bead_coordinates:noo {a} { \fp_eval:n{#2} } { \fp_eval:n{##1-1} }
+ \__atableau_set_bead_coordinates:noo {b} { \fp_eval:n{#3+0.5} } { \fp_eval:n{##1-1} }
+ }
+ \draw[aTableau/abacusEnds,dotted,->] (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+ }
+
+ % set default "row height" of the runner labels for use below
+ \fp_set:Nn \l_tmpa_fp {-1.8}
+ }
+
+ {|} {
+ % set default "row height" of the runner labels for use below
+ \fp_set:Nn \l_tmpa_fp {-0.4}
+ }
+ }
+}
+
+
+% usage: \__atableau_abacus:nn { #runners } { bead specifications }
+\cs_new_protected:Npn \__atableau_abacus:nn #1 #2
+{
+ % set the star style
+ \tl_set:Nn \l__atableau_starstyle_tl {aTableau/abacusStarStyle}
+
+ \int_set:Nn \l__atableau_cols_int {#1}
+
+
+ \seq_if_empty:NF \l__atableau_runner_labels_seq
+ {
+ \int_set:No \l_tmpa_int { \seq_count:N \l__atableau_runner_labels_seq }
+ \int_compare:nNnF {\l__atableau_cols_int-\l_tmpa_int } = {0}
+ {
+ \msg_error:nn {aTableau} {missing-runner-labels }
+ }
+ }
+
+ % Extract the bead positions and their styles into
+ % \l__atableau_shape_seq, \l__atableau_styles_seq and \l__atableau_text_tl
+ % We allow all of the following expressions
+ % m, m^r, [style]m, [style]m^2, *m, *m^2,
+ % m_text, m_text^r, [style]m_text, [style]m_text^2, *m_text, *m_text^2,
+ % m_text^r, [style]m_text^2, *m_text^2
+ % where m is a part of the partition \l__atableau_shape_seq and r is
+ % its' exponent. First, clear all of the sequences and zero the bead
+ % counter
+ \seq_clear:N \l__atableau_shape_seq % will record the partition
+ \seq_clear:N \l__atableau_styles_seq % will record the bead style
+ \seq_clear:N \l__atableau_texts_seq % will record the bead text
+ \int_zero:N \l__atableau_beads_int % will record the number of beads
+
+ % determine the partition/beta numbers
+ \clist_map_inline:nn {#2}
+ {
+ \__atableau_peek_style:nw {record_style:nn} ##1 \q_recursion_tail \q_recursion_stop
+ }
+
+ % unless they have been set, determine the number of abacus rows
+ \int_compare:nNnT {\l__atableau_rows_int} = {0}
+ {
+ \bool_if:NTF \l__atableau_beta_numbers_bool
+ { \int_set:Nn \l__atableau_rows_int { 1+\int_div_truncate:nn { 0\seq_item:Nn \l__atableau_shape_seq 1} {#1} } }
+ { \int_set:Nn \l__atableau_rows_int { 1+\int_div_truncate:nn {\l__atableau_beads_int-1 + 0\seq_item:Nn \l__atableau_shape_seq 1} {#1} } }
+ }
+
+ % draw the abacus runners
+ \int_zero:N \l__atableau_col_int
+ \int_step_inline:nn {\l__atableau_cols_int}
+ {
+ \int_set:Nn \l_tmpa_int {##1-1} % save recalculating this many times
+ % skip the runners in dotted_cols_seq
+ \seq_if_in:NVF \l__atableau_dotted_cols_seq \l_tmpa_int
+ {
+ % draw the abacus runners from (xa,ya) to (xb,yb)
+ \__atableau_set_bead_coordinates:nnV {a} { 0 } \l_tmpa_int
+ \__atableau_set_bead_coordinates:noV {b} { \int_eval:n{\l__atableau_rows_int+1} } \l_tmpa_int
+ \draw[aTableau/runnerStyle] (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+
+ % draw ticks
+ \int_step_inline:nn {\l__atableau_rows_int}
+ {
+ \__atableau_set_bead_coordinates:noV {l} { ####1 } \l_tmpa_int
+ % add a named node
+ \node[aTableau/namedTick] (\l__atableau_name_tl) at (\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp){};
+ % add and subtract (half) tick width
+ \fp_set:Nn \l__atableau_xa_fp {\l__atableau_xl_fp+\l__atableau_tick_length_fp*\l__atableau_ab_col_dx_fp}
+ \fp_set:Nn \l__atableau_ya_fp {\l__atableau_yl_fp+\l__atableau_tick_length_fp*\l__atableau_ab_col_dy_fp}
+ \fp_set:Nn \l__atableau_xb_fp {\l__atableau_xl_fp-\l__atableau_tick_length_fp*\l__atableau_ab_col_dx_fp}
+ \fp_set:Nn \l__atableau_yb_fp {\l__atableau_yl_fp-\l__atableau_tick_length_fp*\l__atableau_ab_col_dy_fp}
+
+ \draw[aTableau/tickStyle,name=\l__atableau_name_tl] (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+ }
+ }
+
+ % set e when entries=residues
+ \tl_if_eq:VnT \l__atableau_show_tl {residues}
+ {
+ % if it is not set already, then set e based on the number of runners and the Cartan type
+ \int_compare:nNnT {\l__atableau_e_int} = {0}
+ {
+ \str_case:Vn \l__atableau_cartan_tl
+ {
+ {A } { \int_set_eq:NN \l__atableau_e_int \l__atableau_cols_int }
+ {C } { \int_set:Nn \l__atableau_e_int {\l__atableau_cols_int/2} }
+ {AA} { \int_set:Nn \l__atableau_e_int {(\l__atableau_cols_int-1)/2} }
+ {DD} { \int_set:Nn \l__atableau_e_int {\l__atableau_cols_int/2-1} }
+ }
+ }
+ }
+
+ % draw the beads on the abacus
+ \int_step_inline:nn { \l__atableau_beads_int } % finally, add the beads, with labels and styles
+ {
+
+ % determine the row and column indices for the bead
+ \bool_if:NTF \l__atableau_beta_numbers_bool
+ {
+ \int_set:No \l_tmpa_int { \seq_item:Nn \l__atableau_shape_seq {##1} } % beta number
+ }
+ {
+ \int_set:No \l_tmpa_int { \l__atableau_beads_int - ##1 + \seq_item:Nn \l__atableau_shape_seq {##1} } % part -> beta number
+ }
+ \int_set:Nn \l__atableau_row_int { \int_div_truncate:nn {\l_tmpa_int} {\l__atableau_cols_int} }
+ \int_set:Nn \l__atableau_col_int { \int_mod:nn {\l_tmpa_int} {\l__atableau_cols_int} }
+
+ % determine the bead coordinates: push everything 0.5 of a
+ % unit down to allow space of the top of the abacus
+ \__atableau_set_bead_coordinates:noV {l} {\int_eval:n{\l__atableau_row_int+1} } \l__atableau_col_int
+
+ \seq_if_in:NVF \l__atableau_dotted_rows_seq \l__atableau_row_int
+ {
+ \seq_if_in:NVF \l__atableau_dotted_cols_seq \l__atableau_col_int
+ {
+ \str_case:VnF \l__atableau_show_tl
+ {
+ {betas} { \tl_set:No \l_tmpa_tl { \int_use:N\l_tmpa_int } }
+ {residues} {
+ \int_set:Nn \l_tmpb_int { \l__atableau_charge_int+\l_tmpa_int-\l__atableau_beads_int }
+ \tl_set:No \l_tmpa_tl { \__atableau_residue:nn {\l_tmpb_int} {\l__atableau_e_int} }
+ }
+ {rows } {
+ \int_set:Nn \l_tmpb_int { \l_tmpa_int-\l__atableau_beads_int+##1 }
+ \int_compare:nNnTF {\l_tmpb_int} > {0}
+ { \tl_set:No \l_tmpa_tl { ##1 } }
+ { \tl_set:No \l_tmpa_tl { {-} } }
+ }
+ {shape} { \tl_set:No \l_tmpa_tl { \seq_item:Nn \l__atableau_shape_seq {##1} } }
+ {} { \tl_set:No \l_tmpa_tl { \seq_item:Nn \l__atableau_texts_seq {##1} } }
+ }
+ {
+ \msg_error:nnx {aTableau} {unrecognised-abacus-label} { \l__atableau_show_tl }
+ }
+ % draw the bead with style
+ \tl_set:No \l_tmpb_tl { \seq_item:Nn \l__atableau_styles_seq {##1} }
+ \exp_last_unbraced:Nx \node{[aTableau/beadStyle, \l_tmpb_tl]}
+ at (\fp_use:N\l__atableau_xl_fp,\fp_use:N\l__atableau_yl_fp){\__atableau_entry:x {\l_tmpa_tl}};
+ }
+ }
+ }
+
+ % draw the top ends of the abacus -- and set \l_tmpa_fp for the runner labels
+ \__atableau_draw_abacus_end:nnn \l__atableau_abacus_top_tl {0} {-1}
+ \int_zero:N \l__atableau_c_int
+
+ % add the runner labels using the "row height" \l_tmpa_fp
+ \int_zero:N \l__atableau_c_int
+ \seq_map_inline:Nn \l__atableau_runner_labels_seq
+ {
+ \__atableau_set_bead_coordinates:nVV {a} \l_tmpa_fp \l__atableau_c_int
+ \seq_if_in:NVF \l__atableau_dotted_cols_seq \l__atableau_c_int
+ {
+ \node[aTableau/runnerLabelStyle] at (\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp){ \__atableau_entry:n{##1} };
+ }
+ \int_incr:N \l__atableau_c_int
+ }
+
+ % draw the bottom ends of the abacus
+ \__atableau_draw_abacus_end:noo \l__atableau_abacus_bottom_tl {\int_eval:n {\l__atableau_rows_int+1}} {\int_eval:n {\l__atableau_rows_int+2}}
+
+ % remove dotted rows and columns
+ \seq_if_empty:NF \l__atableau_dotted_rows_seq \__atableau_remove_dotted_abacus_rows:
+ \seq_if_empty:NF \l__atableau_dotted_cols_seq \__atableau_remove_dotted_abacus_cols:
+
+}
+
+% usage: \__atableau_remove_dotted_abacus_cols:
+% Add dots to the columns of the abacus in \l__atableau_dotted_cols_seq
+\cs_new_protected:Nn \__atableau_remove_dotted_abacus_cols:
+{
+ % shift in row-direction
+ \fp_set:Nn \l_tmpa_fp {\l__atableau_ab_row_dx_fp*\l__atableau_abacus_wd_fp}
+ \fp_set:Nn \l_tmpb_fp {\l__atableau_ab_row_dy_fp*\l__atableau_abacus_ht_fp}
+
+ % take a copy of \l__atableau_dotted_cols_seq so that the pop_left's below
+ % do not destroy it
+ \seq_set_eq:NN \l_tmpb_seq \l__atableau_dotted_cols_seq
+ \bool_do_until:nn { \seq_if_empty_p:N \l_tmpb_seq }
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_set:Nn \l__atableau_col_int {\l_tmpa_tl}
+ \int_set:Nn \l__atableau_c_int {\l__atableau_col_int+1}
+
+ % LaTeX3 does not provide \seq_if_in_p:NN, so ...
+ \bool_set_true:N \l_tmpa_bool
+ \bool_do_while:nn { \l_tmpa_bool }
+ {
+ \int_set:Nn \l_tmpa_int {0\seq_item:Nn \l_tmpb_seq 1}
+ \int_compare:nNnTF {\l__atableau_c_int} = {\l_tmpa_int}
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_incr:N \l__atableau_c_int
+ }
+ { \bool_set_false:N \l_tmpa_bool }
+ }
+
+ \__atableau_set_bead_coordinates:nnV {l} { 0 } \l__atableau_col_int
+
+ % set (xa,ya) and (xb,yb) to the "left" and "right" hand coordinates that we want remove
+ \fp_set:Nn \l__atableau_xa_fp {\l__atableau_xl_fp-0.35*\l__atableau_ab_col_dx_fp*\l__atableau_abacus_wd_fp}
+ \fp_set:Nn \l__atableau_ya_fp {\l__atableau_yl_fp-0.35*\l__atableau_ab_col_dy_fp*\l__atableau_abacus_ht_fp}
+ \fp_set:Nn \l__atableau_xb_fp {\l__atableau_xl_fp+(\l__atableau_c_int-\l__atableau_col_int-0.65)*\l__atableau_ab_col_dx_fp*\l__atableau_abacus_wd_fp}
+ \fp_set:Nn \l__atableau_yb_fp {\l__atableau_yl_fp+(\l__atableau_c_int-\l__atableau_col_int-0.65)*\l__atableau_ab_col_dy_fp*\l__atableau_abacus_ht_fp}
+
+ % blank out any line at the top of the abacus and replace it with dots
+ \tl_if_in:nVT {-_} \l__atableau_abacus_top_tl
+ {
+ \draw[aTableau/clearBoxes]
+ (\fp_eval:n{\l__atableau_xa_fp-0.1*\l_tmpa_fp}, \fp_eval:n{\l__atableau_ya_fp-0.1*\l_tmpb_fp})
+ --++(\fp_eval:n{0.2*\l_tmpa_fp},\fp_eval:n{0.2*\l_tmpb_fp})
+ --(\fp_eval:n{\l__atableau_xb_fp+0.1*\l_tmpa_fp}, \fp_eval:n{\l__atableau_yb_fp+0.1*\l_tmpb_fp})
+ --++(\fp_eval:n{-0.2*\l_tmpa_fp},\fp_eval:n{-0.2*\l_tmpb_fp})
+ --cycle
+ ;
+ % first blank out the possible header line and replace with dots
+ %\draw[fill=white,draw=none](\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ \draw[aTableau/dottedLine](\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+
+ % now draw the dots
+ \int_zero:N \l__atableau_row_int
+ \int_step_inline:nn {\l__atableau_rows_int}
+ {
+ \fp_add:Nn \l__atableau_xa_fp {\l_tmpa_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l_tmpb_fp}
+ \fp_add:Nn \l__atableau_xb_fp {\l_tmpa_fp}
+ \fp_add:Nn \l__atableau_yb_fp {\l_tmpb_fp}
+ \draw[aTableau/dottedLine](\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+
+ % blank out any line at the bottom of the abacus and replace it with dots
+ \tl_if_in:nVT {-_} \l__atableau_abacus_bottom_tl
+ {
+ \fp_add:Nn \l__atableau_xa_fp {\l_tmpa_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l_tmpb_fp}
+ \fp_add:Nn \l__atableau_xb_fp {\l_tmpa_fp}
+ \fp_add:Nn \l__atableau_yb_fp {\l_tmpb_fp}
+ \draw[aTableau/clearBoxes]
+ (\fp_eval:n{\l__atableau_xa_fp-0.1*\l_tmpa_fp}, \fp_eval:n{\l__atableau_ya_fp-0.1*\l_tmpb_fp})
+ --++(\fp_eval:n{0.2*\l_tmpa_fp},\fp_eval:n{0.2*\l_tmpb_fp})
+ --(\fp_eval:n{\l__atableau_xb_fp+0.1*\l_tmpa_fp}, \fp_eval:n{\l__atableau_yb_fp+0.1*\l_tmpb_fp})
+ --++(\fp_eval:n{-0.2*\l_tmpa_fp},\fp_eval:n{-0.2*\l_tmpb_fp})
+ --cycle
+ ;
+ % first blank out the possible header line and replace with dots
+ \draw[aTableau/dottedLine](\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+ }
+}
+
+% usage: \__atableau_remove_dotted_abacus_rows:
+% Add dots to the rows of the abacus in \l__atableau_dotted_rows_seq
+\cs_new_protected:Nn \__atableau_remove_dotted_abacus_rows:
+{
+ % shift in column-direction
+ \fp_set:Nn \l_tmpa_fp {\l__atableau_ab_col_dx_fp*\l__atableau_abacus_wd_fp}
+ \fp_set:Nn \l_tmpb_fp {\l__atableau_ab_col_dy_fp*\l__atableau_abacus_ht_fp}
+
+ % take a copy of \l__atableau_dotted_rows_seq so that the pop_left's below
+ % do not destroy it
+ \seq_set_eq:NN \l_tmpb_seq \l__atableau_dotted_rows_seq
+ \bool_do_until:nn { \seq_if_empty_p:N \l_tmpb_seq }
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_set:Nn \l__atableau_row_int {\l_tmpa_tl}
+ \int_set:Nn \l__atableau_r_int {\l__atableau_row_int+1}
+
+ % LaTeX3 does not provide \seq_if_in_p:NN, so ...
+ \bool_set_true:N \l_tmpa_bool
+ \bool_do_while:nn { \l_tmpa_bool }
+ {
+ \int_set:Nn \l_tmpa_int {0\seq_item:Nn \l_tmpb_seq 1}
+ \int_compare:nNnTF {\l__atableau_r_int} = {\l_tmpa_int}
+ {
+ \seq_pop_left:NN \l_tmpb_seq \l_tmpa_tl
+ \int_incr:N \l__atableau_r_int
+ }
+ { \bool_set_false:N \l_tmpa_bool }
+ }
+
+ \__atableau_set_bead_coordinates:non {l} { \int_eval:n{\l__atableau_row_int+1} } { 0 }
+
+ % set (xa,ya) and (xb,yb) to the "left" and "right" hand coordinates that we want remove
+ \fp_set:Nn \l__atableau_xa_fp {\l__atableau_xl_fp-0.35*\l__atableau_ab_row_dx_fp*\l__atableau_abacus_wd_fp}
+ \fp_set:Nn \l__atableau_ya_fp {\l__atableau_yl_fp-0.35*\l__atableau_ab_row_dy_fp*\l__atableau_abacus_ht_fp}
+ \fp_set:Nn \l__atableau_xb_fp {\l__atableau_xl_fp+(\l__atableau_r_int-\l__atableau_row_int-0.65)*\l__atableau_ab_row_dx_fp*\l__atableau_abacus_wd_fp}
+ \fp_set:Nn \l__atableau_yb_fp {\l__atableau_yl_fp+(\l__atableau_r_int-\l__atableau_row_int-0.65)*\l__atableau_ab_row_dy_fp*\l__atableau_abacus_ht_fp}
+
+ \draw[aTableau/clearBoxes]
+ (\fp_eval:n{\l__atableau_xa_fp-0.12*\l_tmpa_fp}, \fp_eval:n{\l__atableau_ya_fp-0.12*\l_tmpb_fp})
+ --++(\fp_eval:n{(\l__atableau_cols_int+0.24)*\l_tmpa_fp},\fp_eval:n{(\l__atableau_cols_int+0.24)*\l_tmpb_fp})
+ --(\fp_eval:n{\l__atableau_xb_fp+(\l__atableau_cols_int+0.12)*\l_tmpa_fp}, \fp_eval:n{\l__atableau_yb_fp+(\l__atableau_cols_int+0.12)*\l_tmpb_fp})
+ --(\fp_eval:n{\l__atableau_xb_fp-0.12*\l_tmpa_fp}, \fp_eval:n{\l__atableau_yb_fp-0.12*\l_tmpb_fp})
+ --cycle
+ ;
+ % first blank out the possible header line and replace with dots
+ \draw[aTableau/dottedLine](\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+
+ % now draw the dots
+ \int_step_inline:nnn {2} {\l__atableau_cols_int}
+ {
+ \fp_add:Nn \l__atableau_xa_fp {\l_tmpa_fp}
+ \fp_add:Nn \l__atableau_ya_fp {\l_tmpb_fp}
+ \fp_add:Nn \l__atableau_xb_fp {\l_tmpa_fp}
+ \fp_add:Nn \l__atableau_yb_fp {\l_tmpb_fp}
+ \draw[aTableau/dottedLine](\fp_use:N\l__atableau_xa_fp,\fp_use:N\l__atableau_ya_fp)--(\fp_use:N\l__atableau_xb_fp,\fp_use:N\l__atableau_yb_fp);
+ }
+
+ }
+}
+
+% ---------------------------------------------------------------------------
+% Keys for the package options and their defaults
+
+% setting TikZ styles via styles = { ... }
+\cs_new_protected:Npn \__atableau_tikzset:nn #1 #2 { \pgfqkeys{/tikz}{#1/.style={#2}} }
+
+% appending to aTableau styles
+\cs_new_protected:Npn \__atableau_tikzset_append:nn #1 #2 { \pgfqkeys{/tikz/aTableau}{#1/.append~style={#2}} }
+
+% aTableau options/keys
+\keys_define:nn { atableau }
+{
+ % ---------------------------------------------------------------------------
+ % general settings
+
+ % tableaux alignment
+ align .choice:,
+ align/top .code:n = { \tikzset{baseline=(current~bounding~box.north)} },
+ align/north .code:n = { \tikzset{baseline=(current~bounding~box.north)} },
+ align/center .code:n = { \tikzset{baseline=(current~bounding~box.center)}},
+ align/centre .code:n = { \tikzset{baseline=(current~bounding~box.center)}},
+ align/bottom .code:n = { \tikzset{baseline=(current~bounding~box.south)} },
+ align/south .code:n = { \tikzset{baseline=(current~bounding~box.south)} },
+ align .unknown .code:n = { \msg_error:nne { aTableau } { unknown-baseline } {#1} },
+ align .initial:n = centre,
+
+ % set the Cartan type
+ cartan .choices:nn = { A, C, AA, DD }
+ {
+ % record the Cartan type for use in abacuses
+ \tl_set:Nn \l__atableau_cartan_tl {#1}
+ % define all of the type dependent functions here...
+ \cs_set_eq:Nc \__atableau_residue:nn {__atableau_residue_#1:nn}
+ },
+ cartan/unknown .code:n = { \msg_error:nne { aTableau } { unknown-cartan } {#1} },
+ cartan .initial:n = A,
+
+ charge .code:n =
+ {
+ % To cater for multipartitions, the charge is a sequence .
+ % Set l__atableau_charge_int is the first item in the sequence
+ \regex_split:nnN {[,\|]} {#1} \l__atableau_charge_seq
+ \int_set:Nn \l__atableau_charge_int { \seq_item:Nn \l__atableau_charge_seq {1} }
+ },
+ charge .value_required:n = true,
+ charge .initial:n = 0,
+
+ % dotted rows and columns for tableaux and abacuses
+ dotted~cols .code:n = { \__atableau_set_multiseq_key:nn {dotted_cols} {#1} },
+ dotted~cols .value_required:n = true,
+
+ dotted~rows .code:n = { \__atableau_set_multiseq_key:nn {dotted_rows} {#1} },
+ dotted~rows .value_required:n = true,
+
+ e .int_set:N = \l__atableau_e_int,
+ e .initial:n = 0,
+
+ entries .tl_set:N = \l__atableau_show_tl, % automatic bead labelling
+ entries .value_required:n = false,
+ entries .initial:n = ,
+
+ halign .choice:,
+ halign/center .code = {\cs_set_eq:NN \__atableau_halign:n \hbox_overlap_center:n},
+ halign/centre .code = {\cs_set_eq:NN \__atableau_halign:n \hbox_overlap_center:n},
+ halign/left .code = {\cs_set_eq:NN \__atableau_halign:n \hbox_overlap_left:n},
+ halign/right .code = {\cs_set_eq:NN \__atableau_halign:n \hbox_overlap_right:n},
+ halign .unknown .code:n = { \msg_error:nne { aTableau } { unknown-halign } {#1} },
+ halign .initial:n = centre,
+
+ % math/text mode for boxes and beads
+ math~entries .code:n = { \cs_set_eq:NN \__atableau_entry:n \__atableau_entry_math:n },
+ text~entries .code:n = { \cs_set_eq:NN \__atableau_entry:n \__atableau_entry_text:n },
+
+ % tableau node name prefix
+ name .tl_set:N = \l__atableau_prefix_tl,
+ name .value_required:n = true,
+ name .initial:n = A,
+
+ % scaling
+ scale .code:n = { \__atableau_set_xscale:n {#1} \__atableau_set_yscale:n {#1} },
+ scale .value_required:n = true,
+
+ star~style .code:n = { \__atableau_tikzset_append:nn {tableauStarStyle} {#1} },
+ star~style .value_required:n = true,
+
+ % shortcut for setting TikZ styles, following a suggestion of Skillmon to use \keyval_parse:nnn
+ styles .code:n =
+ { \keyval_parse:nnn { \msg_error:nnn {aTableau}{missing-style} } { \__atableau_tikzset:nn } { #1 } },
+
+ % tikzpicture environment
+ tikzpicture .tl_set:N= \l__atableau_tikzpicture_tl,
+ tikzpicture .value_required:n = true,
+ tikzpicture .initial:n =,
+
+ % tikz code after
+ tikz~after .tl_set:N = \l__atableau_tikz_after_tl,
+ tikz~after .value_required:n = true,
+ tikz~after .initial:n = ,
+
+ % tikz~ code before
+ tikz~before .tl_set:N = \l__atableau_tikz_before_tl,
+ tikz~before .value_required:n = true,
+ tikz~before .initial:n = ,
+
+ valign .choices:nn = { bottom, center, centre, top }
+ {
+ \cs_set_eq:Nc \__atableau_valign:n { __atableau_valign_#1:n }
+ },
+ valign .unknown .code:n = { \msg_error:nne { aTableau } { unknown-valign } {#1} },
+ valign .initial:n = centre,
+
+ xscale .code:n = { \__atableau_set_xscale:n {#1} },
+ xscale .value_required:n = true,
+ xscale .initial:n =1,
+
+ yscale .code:n = { \__atableau_set_yscale:n {#1} },
+ yscale .value_required:n = true,
+ yscale .initial:n =1,
+
+ % ---------------------------------------------------------------------------
+ % tableau settings
+
+ % convention switches
+ Australian .code:n = \__atableau_set_style:nn {tableau} {australian},
+ australian .code:n = \__atableau_set_style:nn {tableau} {australian},
+ australian .value_required:n = false,
+
+ English .code:n = \__atableau_set_style:nn {tableau} {english},
+ english .code:n = \__atableau_set_style:nn {tableau} {english},
+ english .value_required:n = false,
+ english .initial:n =, % default style
+
+ French .code:n = \__atableau_set_style:nn {tableau} {french},
+ french .code:n = \__atableau_set_style:nn {tableau} {french},
+ french .value_required:n = false,
+
+ ukrainian .code:n = \__atableau_set_style:nn {tableau} {ukrainian},
+ Ukrainian .code:n = \__atableau_set_style:nn {tableau} {ukrainian},
+ ukrainian .value_required:n = false,
+
+ Russian .code:n = \__atableau_set_style:nn {tableau} {ukrainian},
+ russian .code:n = \__atableau_set_style:nn {tableau} {ukrainian},
+
+ border .bool_set:N = \l__atableau_border_bool,
+ border .default:n = true,
+ border .initial:n = true,
+
+ no~border .bool_set_inverse:N = \l__atableau_border_bool,
+ no~border .default:n = true,
+
+ % border colours
+
+ border~color .tl_set:N = \l__atableau_outer_tl, % an alias
+ border~color .value_required:n = true,
+ border~colour .tl_set:N = \l__atableau_outer_tl,
+ border~colour .value_required:n = true,
+ border~colour .initial:n = aTableauMain,
+
+ border~style .code:n = { \__atableau_tikzset_append:nn {borderStyle} {#1} },
+ border~style .value_required:n = true,
+
+ % node height and width
+ box~height .fp_set:N = \l__atableau_box_ht_fp,
+ box~height .value_required:n = true,
+ box~height .initial:n = 0.5,
+
+ box~width .fp_set:N = \l__atableau_box_wd_fp,
+ box~width .value_required:n = true,
+ box~width .initial:n = 0.5,
+
+ % box styling
+ box~fill .tl_set:N = \l__atableau_box_fill_tl,
+ box~fill .value_required:n = true,
+ box~fill .initial:n = white,
+
+ box~font .tl_set:N = \l__atableau_box_font_tl,
+ box~font .value_required:n = true,
+ box~font .initial:n =,
+
+ box~shape .tl_set:N = \l__atableau_box_shape_tl,
+ box~shape .value_required:n = true,
+ box~shape .initial:n = rectangle,
+
+ box~text .tl_set:N = \l__atableau_box_text_tl,
+ box~text .value_required:n = true,
+ box~text .initial:n = aTableauMain,
+
+ box~style .code:n = { \__atableau_tikzset_append:nn {boxStyle} {#1} },
+ box~style .value_required:n = true,
+
+ boxes .bool_set:N = \l__atableau_boxes_bool,
+ boxes .default:n = true,
+ boxes .initial:n = true,
+
+ no~boxes .bool_set_inverse:N = \l__atableau_boxes_bool,
+ no~boxes .default:n = true,
+
+ conjugate .code:n =
+ {
+ \tl_set:Nx \l_tmpa_tl {\str_lowercase:n {#1}}
+ \str_if_eq:VnTF \l_tmpa_tl {true}
+ {
+ \bool_set_true:N \l__atableau_conjugate_bool
+ \cs_set_eq:NN \__atableau_set_box_coordinates:nnn \__atableau_set_box_coordinates_conjugate:nnn
+ }
+ {
+ \bool_set_false:N \l__atableau_conjugate_bool
+ \cs_set_eq:NN \__atableau_set_box_coordinates:nnn \__atableau_set_box_coordinates_normal:nnn
+ }
+ },
+ conjugate .default:n = true,
+ conjugate .initial:n = false,
+
+ inner~wall .tl_set:N = \l__atableau_inner_tl,
+ inner~wall .value_required:n = true,
+ inner~wall .initial:n = aTableauInner,
+
+ inner~style .code:n = { \__atableau_tikzset_append:nn {innerWall} {#1} },
+ inner~style .value_required:n = true,
+
+ % label
+ label .code:n = {
+ \tl_if_in:nnTF {#1} {|}
+ {
+ % unpack the ribbons into \l__atableau_multiribbons_seq
+ \seq_set_split:cnn {l__atableau_multilabel_seq} {|} {#1}
+ }
+ { \tl_set:No \l__atableau_label_tl {#1} }
+ },
+
+ label~style .code:n = { \__atableau_tikzset_append:nn {labelStyle} {#1} },
+ label~style .value_required:n = true,
+
+ % -- paths ---------------------------------------
+ paths .code:n = { \__atableau_set_multiseq_key:nn {paths} {#1} },
+ paths .initial:n = ,
+
+ path~style .code:n = { \__atableau_tikzset_append:nn {pathStyle} {#1} },
+ path~style .value_required:n = true,
+ path~style .initial:n =,
+
+ path~box .tl_set:N = \l__atableau_path_box_tl,
+ path~box .initial:n = ,
+
+ path~box~style .code:n = { \__atableau_tikzset_append:nn {pathBox} {#1} },
+ path~box~style .value_required:n = true,
+ path~box~style .initial:n =,
+
+ % -- ribbons ---------------------------------------
+ ribbons .code:n = { \__atableau_set_multiseq_key:nn {ribbons} {#1} },
+ ribbons .initial:n = ,
+
+ ribbon~style .code:n = { \__atableau_tikzset_append:nn {ribbonStyle} {#1} },
+ ribbon~style .value_required:n = true,
+ ribbon~style .initial:n =,
+
+ ribbon~box .tl_set:N = \l__atableau_ribbon_box_tl,
+ ribbon~box .initial:n = ,
+
+ ribbon~box~style .code:n = { \__atableau_tikzset_append:nn {ribbonBox} {#1} },
+ ribbon~box~style .value_required:n = true,
+ ribbon~box~style .initial:n =,
+
+ % -- snobs ---------------------------------------
+ snobs .code:n = { \__atableau_set_multiseq_key:nn {snobs} {#1} },
+ snobs .initial:n = ,
+
+ snob~style .code:n = { \__atableau_tikzset_append:nn {snobStyle} {#1} },
+ snob~style .value_required:n = true,
+ snob~style .initial:n =,
+
+ snob~box .tl_set:N = \l__atableau_snob_box_tl,
+ snob~box .initial:n = ,
+
+ snob~box~style .code:n = { \__atableau_tikzset_append:nn {snobBox} {#1} },
+ snob~box~style .value_required:n = true,
+ snob~box~style .initial:n =,
+
+ % -- shifted, skew and tabloid shapes ------------
+ shifted .bool_set:N = \l__atableau_shifted_bool,
+ shifted .initial:n = false,
+
+ skew .code:n =
+ {
+ \tl_if_in:nnTF {#1} {|}
+ {
+ % unpack the skew tableau into \l__atableau_multiskew_seq
+ \seq_set_split:Nnn \l__atableau_multiskew_seq {|} {#1}
+ }
+ { \__atableau_set_partition:nn {skew} {#1} }
+ },
+ skew .value_required:n = true,
+ skew .initial:n = 0,
+
+ skew~border .bool_set:N = \l__atableau_skew_border_bool,
+ skew~border .initial:n = false,
+
+ no~skew~border .bool_set_inverse:N = \l__atableau_skew_border_bool,
+ no~skew~border .default:n = true,
+
+ skew~border~style .code:n = { \__atableau_tikzset_append:nn {skewBorder} {#1} },
+ skew~border~style .value_required:n = true,
+
+ skew~boxes .bool_set:N = \l__atableau_skew_boxes_bool,
+ skew~boxes .default:n = true,
+ skew~boxes .initial:n = false,
+
+ no~skew~boxes .bool_set_inverse:N = \l__atableau_skew_boxes_bool,
+
+ skew~box~style .code:n = { \__atableau_tikzset_append:nn {skewBox} {#1} },
+ skew~box~style .value_required:n = true,
+
+ skew colour .tl_set:N = \l__atableau_skew_border_tl,
+ skew color .tl_set:N = \l__atableau_skew_border_tl,
+ skew colour .initial:n = aTableauSkew,
+
+ tabloid .bool_set:N = \l__atableau_tabloid_bool,
+ tabloid .initial:n = false,
+
+ % -- multitableaux and multidiagrams --------------------
+
+ delimiters .code:n = { \__atableau_set_delimiters:nn #1 },
+ delimiters .value_required:n = true,
+ delimiters .initial:n = (),
+
+ left~delimiter .tl_set:N = \l__atableau_left_delimiter_tl,
+ left~delimiter .value_required:n = true,
+
+ right~delimiter .tl_set:N = \l__atableau_right_delimiter_tl,
+ right~delimiter .value_required:n = true,
+
+ empty .tl_set:N = \l__atableau_empty_tl,
+ empty .initial:n = \textendash,
+
+ separators .bool_set:N = \l__atableau_separators_bool,
+ separators .default:n = true,
+ separators .initial:n = true,
+
+ no~separators .bool_set_inverse:N = \l__atableau_separators_bool,
+ no~separators .default:n = true,
+
+ separation .fp_set:N = \l__atableau_separation_fp,
+ separation .value_required:n = true,
+ separation .initial:n = 0.3,
+
+ separator .tl_set:N = \l__atableau_separator_tl,
+ separator .value_required:n = true,
+ separator .initial:n = |,
+
+ separator~colour .tl_set:N = \l__atableau_separator_fg_tl,
+ separator~colour .value_required:n = true,
+ separator~colour .initial:n = aTableauMain,
+
+ separator~color .tl_set:N = \l__atableau_separator_fg_tl,
+ separator~color .value_required:n = true,
+
+ % set rows in abacuses, multitableau and multidiagrams
+ rows .code:n = {
+ \fp_set:Nn \l__atableau_rows_fp {#1}
+ \int_set:No \l__atableau_rows_int {\fp_to_int:N \l__atableau_rows_fp}
+ },
+ rows .value_required:n = true,
+ rows .initial:n = 0,
+
+ xoffsets .code:n = { \regex_split:nnN {[\|,]} {#1} \l__atableau_xoffsets_seq },
+ xoffsets .value_required:n = true,
+ xoffsets .initial:n = 0,
+
+ yoffsets .code:n = { \regex_split:nnN {[\|,]} {#1} \l__atableau_yoffsets_seq },
+ yoffsets .value_required:n = true,
+ yoffsets .initial:n = 0,
+
+ % ---------------------------------------------------------------------------
+ % abacus keys
+
+ south .code:n = \__atableau_set_style:nn {abacus} {south},
+ south .initial:n =,
+ east .code:n = \__atableau_set_style:nn {abacus} {east},
+ north .code:n = \__atableau_set_style:nn {abacus} {north},
+ west .code:n = \__atableau_set_style:nn {abacus} {west},
+
+ % abacus style
+ abacus~ends .code:n = { \__atableau_set_abacus_ends:nn #1 },
+ abacus~ends .value_required:n = true,
+ abacus~ends .initial:n = {-|},
+
+ abacus~ends~style .code:n = { \__atableau_tikzset_append:nn {abacusEnds} {#1} },
+ abacus~ends~style .value_required:n = true,
+
+ abacus~star~style .code:n = { \__atableau_tikzset_append:nn {abacusStarStyle} {#1} },
+ abacus~star~style .value_required:n = true,
+
+ bead .tl_set:N = \l__atableau_bead_tl, % bead colour
+ bead .value_required:n = true,
+ bead .initial:n = aTableauMain,
+
+ bead~font .tl_set:N = \l__atableau_bead_font_tl, % bead font
+ bead~font .initial:n = \small,
+ bead~font .value_required:n = true,
+
+ bead~size .fp_set:N = \l__atableau_bead_size_fp,
+ bead~size .initial:n = 0.4,
+
+ bead~sep .fp_set:N = \l__atableau_abacus_ht_fp, % bead separation
+ bead~sep .value_required:n = true,
+ bead~sep .initial:n = 0.42,
+
+ bead~shape .tl_set:N = \l__atableau_bead_shape_tl, % bead shape colour
+ bead~shape .value_required:n = true,
+ bead~shape .initial:n = circle,
+
+ bead~style .code:n = { \__atableau_tikzset_append:nn {beadStyle} {#1} },
+ bead~style .value_required:n = true,
+
+ bead~text .tl_set:N = \l__atableau_bead_text_tl, % bead text colour
+ bead~text .value_required:n = true,
+ bead~text .initial:n = white,
+
+ beta~numbers .bool_set:N = \l__atableau_beta_numbers_bool,
+ beta~numbers .initial:n = false,
+
+ no~shade .code:n = { \__atableau_tikzset_append:nn {beadStyle} {no~shade,} },
+ no~shade .value_required:n = false,
+
+ runner .tl_set:N = \l__atableau_runner_tl, % runner colour
+ runner .value_required:n = true,
+ runner .initial:n = aTableauInner,
+
+ runner~style .code:n = { \__atableau_tikzset_append:nn {runnerStyle} {#1} },
+ runner~style .value_required:n = true,
+
+ runner~labels .code:n = { \seq_set_split:Nnn \l__atableau_runner_labels_seq {,} {#1} },
+ runner~labels .value_required:n = true,
+
+ runner~label~style .code:n = { \__atableau_tikzset_append:nn {runnerLabelStyle} {#1} },
+ runner~label~style .value_required:n = true,
+
+ runner~sep .fp_set:N = \l__atableau_abacus_wd_fp, % runner separation
+ runner~sep .value_required:n = true,
+ runner~sep .initial:n = 0.42,
+
+ shading .tl_set:N = \l__atableau_shading_tl,
+ shading .value_required:n = true,
+ shading .initial:n = ball,
+
+ tick .tl_set:N = \l__atableau_tick_tl, % tick colour
+ tick .initial:n = aTableauInner,
+
+ tick~length .code:n = { \fp_set:Nn \l__atableau_tick_length_fp {#1/2} }, % (half) tick width separation
+ tick~length .value_required:n = true,
+ tick~length .initial:n = 0.1,
+
+ tick~style .code:n = { \__atableau_tikzset_append:nn {tickStyle} {#1} },
+ tick~style .value_required:n = true,
+}
+
+
+% ---------------------------------------------------------------------------
+% Usage: \__atableau_set_origin:nn (x,y)
+% Set the Cartesian coordinates for the corner of the (1,1) box
+% TODO: allow general TikZ-coorindates. To do this we could, for example, use ideas from
+% https://tex.stackexchange.com/questions/33703/extract-x-y-coordinate-of-an-arbitrary-point-in-tikz
+\cs_new_protected:Npn \__atableau_set_origin:nn (#1,#2)
+{
+ \fp_set:Nn \l__atableau_x_fp {#1}
+ \fp_set:Nn \l__atableau_y_fp {#2}
+}
+
+% usage: \__atableau_tikzpicture:nnn {settings} {origin} {aTableau command}
+% where
+% - #1: settings are a comma separated list of aTableau settings
+% - #2: origin are Cartesian coordinates in the form x,y, or NoValue
+% - #3: an internal aTableau command with parameters for drawing something
+% Apply settings and wrap an aTableau command inside a tikzpicture environment.
+% Add any tikzpicture environments settings and before and after TikZ commands
+\cs_new_protected:Npn \__atableau_tikzpicture:nnn #1 #2 #3
+{
+ \group_begin:
+ % keep changes to settings local by working inside a group
+ \keys_set:nn {atableau} {#1}
+ \IfNoValueTF {#2}
+ { % wrap inside a tikzpicture environment, placing the picture at (0,0)
+ \__atableau_set_origin:nn (0,0)
+ \exp_last_unbraced:Ne \tikz{[\l__atableau_tikzpicture_tl]}
+ {
+ \l__atableau_tikz_before_tl
+ #3
+ \l__atableau_tikz_after_tl
+ }
+ }
+ { % already inside a tikzpicture environment
+ \__atableau_set_origin:nn (#2)
+ \l__atableau_tikz_before_tl
+ #3
+ \l__atableau_tikz_after_tl
+ }
+ \group_end:
+}
+
+% ---------------------------------------------------------------------------
+% Public facing package commands
+
+% Almost all public-facing routines call \__atableau_tikzpicture:nnn,
+% which applies the settings, sets the coordinates of the origin and
+% then ensures that the requested diagram is drawn inside a tikzpicture
+% environment.
+
+% \Abacus (x,y) [style] {#runners} {partition}
+\NewDocumentCommand\Abacus{ d() O{} m m }
+{
+ \__atableau_tikzpicture:nnn {#2} {#1} { \__atableau_abacus:nn {#3} {#4} }
+}
+
+% \Diagram (x,y) [style] {shape}
+\NewDocumentCommand\Diagram{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {#2} {#1} { \__atableau_draw_diagram:n {#3} }
+}
+
+% \Multidiagram (x,y) [style] {entries}
+\NewDocumentCommand\Multidiagram{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {#2} {#1} { \__atableau_multidiagram:n {#3} }
+}
+
+% \Multitableau (x,y) [style] {entries}
+\NewDocumentCommand\Multitableau{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {#2} {#1} { \__atableau_multitableau:n {#3} }
+}
+
+% \RibbonTableau (x,y) [style] {entries}
+\NewDocumentCommand\RibbonTableau{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {#2} {#1} { \__atableau_ribbon_tableau:n {#3} }
+}
+
+% \ShiftedDiagram (x,y) [style] {entries}
+\NewDocumentCommand\ShiftedDiagram{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {shifted,#2} {#1} { \__atableau_draw_diagram:n {#3} }
+}
+
+% \ShiftedTableau (x,y) [style] {entries}
+\NewDocumentCommand\ShiftedTableau{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {shifted,#2} {#1} { \__atableau_draw_tableau:n {#3} }
+}
+
+% \SkewDiagram (x,y) [style] {skew shape} {entries}
+\NewDocumentCommand\SkewDiagram{ d() O{} m m }
+{
+ \__atableau_tikzpicture:nnn {skew={#3},#2} {#1} { \__atableau_draw_diagram:n {#4} }
+}
+
+% \SkewTableau (x,y) [style] {skew shape} {entries}
+\NewDocumentCommand\SkewTableau{ d() O{} m m }
+{
+ \__atableau_tikzpicture:nnn {skew={#3},#2} {#1} { \__atableau_draw_tableau:n {#4} }
+}
+
+% \Tableau (x,y) [style] {entries}
+\NewDocumentCommand\Tableau{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {#2} {#1} { \__atableau_draw_tableau:n {#3} }
+}
+
+% \Tabloid (x,y) [style] {entries}
+\NewDocumentCommand\Tabloid{ d() O{} m }
+{
+ \__atableau_tikzpicture:nnn {tabloid,#2} {#1} { \__atableau_draw_tableau:n {#3} }
+}
+
+\NewDocumentCommand\aTabset{ m }{ \keys_set:nn { atableau } {#1} }
+
+% ---------------------------------------------------------------------------
+% Finally, now that everything is defined, process the package options.
+
+\IfFormatAtLeastTF { 2022-06-01 }
+ { \ProcessKeyOptions [ atableau ] }
+ {
+ \RequirePackage { l3keys2e }
+ \ProcessKeysOptions { atableau }
+ }
+
+\endinput
+
+% ---------------------------------------------------------------------------
+% CHANGE LOG
+%
+% Version 1.0
+% - initial version
+% - Young diagrams, tabloids, tableaux, shifted tableaux, Ukrainian tableaux, abacuses, braids
+%
+% Version 2.0
+% - completely rewritten using LaTeX3
+% - key interface for the tableaux options
+% - macros can be used both in and outside tikzpicture environments
+% - a quark-based interface allows styles to be applied to each tableau entry
+% - support for different conventions (english, french, ukrainian, australian)
+% - support diagrams, tableaux, including tabloids, skew and shifted tableaux and ribbon tableaux
+% - stars and styles
+
+% ---------------------------------------------------------------------------
+%
+% Copyright (C) 2022-25 by Andrew Mathas <andrew.mathas@gmail.com>
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License (LPPL), either
+% version 1.3c of this license or (at your option) any later
+% version. The latest version of this license is in the file:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Andrew Mathas.
+%
+% This package consists of the files:
+% atableau.ini
+% atableau.pdf
+% atableau.sty
+% atableau.tex
+% LICENSE
+% README.md
+%
+% ---------------------------------------------------------------------------
+
+% end of atableau.sty
diff --git a/macros/latex/contrib/atableau/atableau.tex b/macros/latex/contrib/atableau/atableau.tex
new file mode 100644
index 0000000000..8574fcace3
--- /dev/null
+++ b/macros/latex/contrib/atableau/atableau.tex
@@ -0,0 +1,4359 @@
+% ----------------------------------------------------------------------
+% Title: aTableau. Author: Andrew Mathas Created: October 2023
+% Modified: 22:42 Wednesday, 22 January 2025
+% ----------------------------------------------------------------------
+\documentclass{amsart}
+\usepackage[svgnames,table]{xcolor}
+\usepackage{atableau}
+\usepackage{xspace}
+\usepackage{manfnt}
+\usepackage{booktabs}
+\usepackage{xltabular}
+\usepackage{siunitx}
+\usepackage{array}
+\newcolumntype{L}{>{\sffamily\color{MidnightBlue}\textbackslash}l}
+
+% ----------------------------------------------------------------------
+\usepackage{bm}
+\usepackage{mathtools}
+
+% ----------------------------------------------------------------------
+\usepackage{bbding}
+\newcommand\No{\textcolor{red}{\XSolidBrush}}
+% \Yes, which adds a hyperlink, is defined below
+
+% ----------------------------------------------------------------------
+\usepackage[a4paper,hmargin=24mm, vmargin=18mm, footskip=10mm]{geometry}
+\synctex=1
+\hfuzz=5pt
+\parindent=0pt
+\parskip=4mm
+
+\makeatletter
+\def\@evenhead{\hfill\aTableau\hfill}
+\let\@oddhead\@evenhead
+\def\@oddfoot {\color{aTableauInner} Version \atableau@version~(\atableau@release)\hfill\thepage}
+\def\@evenfoot{\color{aTableauInner} \thepage\hfill Version \atableau@version~(\atableau@release)}
+\makeatother
+
+% ----------------------------------------------------------------------
+\newcommand\aTableauColour[1]{%
+ \tikz[baseline={(current bounding box.south)}]\node[minimum width=8mm, minimum height=2ex,fill=aTableau#1]{};%
+}
+
+\usepackage{enumitem}
+\setlist{itemsep=2mm, parsep=2mm}
+\newlist{options}{description}{1}
+% remove the colon from the description label by redefining \makelabel
+\newcommand\optionlabel[1]{\sffamily\bfseries\color{aTableauInner}#1\hss}
+\setlist[options]{
+ before=\let\makelabel\optionlabel,
+ labelwidth=\textwidth,
+ nosep,
+}
+
+\ExplSyntaxOn
+\NewDocumentCommand\Yes{o}
+{
+ \IfNoValueTF{#1}
+ {
+ \hyperref[\g_lastlink_tl]{\textcolor{ForestGreen}{\CheckmarkBold}}
+ }
+ {
+ \hyperref[\g_lastlink_tl-\str_lowercase:f{#1}]{\textcolor{ForestGreen}{\CheckmarkBold}}
+ }
+}
+
+% Add hyperinks for (new displayed) options
+\tl_new:N \g_lastlink_tl
+\prop_new:N \l__atableau_options_prop
+\NewDocumentCommand\AddKeyLink{m}
+{
+ \tl_gset:Nx \g_lastlink_tl {Key:\str_lowercase:f{#1}}
+ \prop_if_in:NVF \l__atableau_options_prop \g_lastlink_tl
+ {
+ \phantomsection\exp_args:Nf\label{Key:\str_lowercase:f{#1}}% add a label for references
+ \prop_put:NVn \l__atableau_options_prop \g_lastlink_tl {}
+ }
+}
+% \option*[default value]{option name}[accepted values]<hyperlink context>
+% The \option command is slightly overloaded, both in terms of arguments
+% (there are five) and in terms of use.
+% 1. If #2 is given then \option gives the syntax for the using this key:
+% - #1=* determines whether a \newline or \bigskip is inserted. The
+% *-version is used when a block of keys are listed together
+% - #2 gives the default options
+% - #3 is the key name and optionally may take the form key=value
+% to describe the allowed values. If the value is given then it is
+% printed in orange after the key inside \langle...\rangle. This is
+% intended for "generic values like 'value' or 'style'.
+% The key component of #2 is used to add a hyperlink to the current
+% location, which takes the form Key:<key>-<context>, where the
+% <context> is added only if #5 is supplied
+% - any accepted values in #3 are printed in the right-hand margin
+% 2. When #2 is omitted, this an inline citation of the key. A
+% hyperlink is added
+
+% The *-version does not do a \bigskip before the option. A hyperlink is
+% added for new displayed options. If #2 is blank then the *-version
+% puts (no) before the option key. If #5 is given then it is added to
+% to the hyperlink.
+\NewDocumentCommand\option{ somo d<> }
+{%
+ \seq_set_split:Nnn \l_tmpa_seq {=} {#3}%
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl%
+ \seq_if_empty:NTF \l_tmpa_seq
+ { \tl_clear:N \l_tmpb_tl }
+ { \tl_set:No \l_tmpb_tl { \seq_use:Nn \l_tmpa_seq {=} } }
+ \IfNoValueTF{#2}
+ {%
+ \tl_gset:Nx \g_lastlink_tl {Key:\str_lowercase:f{\l_tmpa_tl}}
+ \IfNoValueF{#5} { \tl_gput_right:No \g_lastlink_tl {\str_lowercase:f{-#5}} }
+ \hyperref[\g_lastlink_tl]{\textsf{\color{aTableauInner}\IfBooleanT{#1}{(no)~}\l_tmpa_tl}}
+ \index{\l_tmpa_tl}%
+ \tl_if_empty:NF \l_tmpb_tl { \textsf{\,$=$\,}\textsf{\textcolor{orange}{\l_tmpb_tl}} }
+ }
+ {%
+ % encourage page breaks *before* the option, rather than after it
+ \IfBooleanTF{#1}{\newline}{\bigskip\pagebreak[0]}%
+ % adjust #3 if it contains a *, when we add = <value>
+ % add a label for references
+ \IfNoValueTF{#5} { \AddKeyLink{\l_tmpa_tl} }{ \AddKeyLink{\l_tmpa_tl-#5} }
+ \noindent\textsf
+ {
+ \textcolor{aTableauInner}{\l_tmpa_tl}
+ \tl_if_empty:NF \l_tmpb_tl { \textcolor{orange}{$\,=\,\langle$\l_tmpb_tl$\rangle$} }
+ }
+ \tl_if_blank:nF {#2}
+ { ~ \tl_if_eq:nnTF{#2} {-} {(default)} {(default:~\textcolor{DarkRed}{#2})} }%
+ \hfill%
+ \IfNoValueF{#4}{\textcolor{Grey}{[accepts:~#4]}}%
+ \index{\l_tmpa_tl|underline}%
+ \nopagebreak[4]%
+ }%
+}
+
+% index command ignoring the backslash and capitalisation
+\cs_new_protected:Npn \l_addto_index:nn #1#2 { \index{#2@\textbackslash #1} }
+\cs_generate_variant:Nn \l_addto_index:nn {Vo}
+\NewDocumentCommand\indexcmd{m}
+{
+ \tl_set:Nn \l_index_tl {#1}
+ \l_addto_index:Vo \l_index_tl { \str_lower_case:n\l_index_tl }
+}
+
+\clist_new:N \l_atableau_keys_clist
+\clist_set:Nn \l_atableau_keys_clist
+{
+ Australian,
+ English,
+ French,
+ Ukrainian,
+ align,
+ australian,
+ border,
+ box,
+ boxes,
+ no boxes,
+ color,
+ colour,
+ cols,
+ conjugate,
+ left delimiter,
+ right delimiter,
+ delimiters,
+ dotted,
+ e,
+ east,
+ english,
+ entries,
+ font,
+ french,
+ halign,
+ height,
+ inner,
+ label,
+ left,
+ math,
+ nodes,
+ north,
+ ribbon,
+ ribbons,
+ right,
+ rows,
+ scale,
+ separator,
+ separators,
+ shape,
+ shifted,
+ skew,
+ snobs,
+ snob style,
+ ribbon style,
+ path style,
+ snob box,
+ ribbon box,
+ path box,
+ snob box style,
+ ribbon box style,
+ path box style,
+ valign,
+ south,
+ star style,
+ abacus star style,
+ tabloid,
+}
+\NewDocumentCommand\HighlightKeys{m}
+{
+ \clist_if_in:NnTF \l_atableau_keys_clist {#1}
+ {
+ \textcolor{orange}{#1}
+ }
+ {
+ #1
+ }
+}
+\ExplSyntaxOff
+
+% ---------------------------------------------------------------------------
+% the index
+
+\usepackage{imakeidx}
+\indexsetup{level=\section*, toclevel=section, noclearpage}
+\makeindex[columns=3]
+\renewcommand*{\seename}{see}
+
+% ---------------------------------------------------------------------------
+%\renewcommand\thesubsection{\thesection\Alph{subsection}}
+\setcounter{secnumdepth}{3}
+\setcounter{tocdepth}{3}
+\renewcommand\thesubsection{\thesection\Alph{subsection}}
+\renewcommand\thesubsubsection{\thesubsection.\arabic{subsubsection}}
+
+\makeatletter
+\def\l@subsection{\@tocline{2}{0pt}{2.5pc}{5pc}{}}
+\def\l@subsubsection{\@tocline{2}{0pt}{3.5pc}{3pc}{}}
+\makeatother
+
+\newenvironment{warning}{\trivlist\item[\hskip\labelsep\textcolor{red}{\textdbend}]}{\endtrivlist}
+
+% ---------------------------------------------------------------------------
+\usepackage[skins]{tcolorbox}
+\usepackage{hyperref}
+\hypersetup{
+ colorlinks=true,
+ linkcolor=MediumBlue,
+ citecolor=FireBrick,
+}
+\tcbuselibrary{listings, breakable}
+
+\DeclareTotalTCBox\keyword{ O{} v }
+{
+ bottom=0pt,
+ colback = Ivory,
+ colupper = aTableauInner,
+ fontupper= \bfseries,
+ fontlower= \bfseries,
+ left = 0mm,
+ right = 0mm,
+ size = tight,
+ skin = tile,
+ top = 0pt,
+ nobeforeafter,
+ on line,
+ shrink tight,
+ verbatim,
+ #1}
+{#2}
+
+\newcommand\aTableau{\textcolor{aTableauMain}{\sffamily aTableau}\xspace}
+
+% hyperref links to ctan
+\newcommand\ctan[1]{\href{https://www.ctan.org/pkg/#1}{\texttt{#1}}}
+\newcommand\TikZ{\href{https://www.ctan.org/pkg/tikz}{Ti\textit{k}Z}\xspace}
+
+\lstdefinestyle{atableau}
+{
+ style=tcblatex,
+ classoffset=0,
+ texcsstyle=*\color{MediumBlue},%
+ deletetexcs={begin, end},
+ commentstyle=\color{Peru},
+ moretexcs={,% aTableau package commands
+ aTabset,
+ Abacus,
+ Diagram,
+ Multidiagram,
+ Multitableau,
+ RibbonTableau,
+ ShiftedDiagram,
+ ShiftedTableau,
+ SkewTableau,
+ SkewDiagram,
+ Tableau,
+ Tabloid,
+ },%
+% classoffset=1, % aTableau package options
+% keywordstyle=\color{aTableauInner},%
+% morekeywords={
+% Australian,
+% English,
+% French,
+% Ukrainian,
+% align,
+% australian,
+% border,
+% box,
+% boxes,
+% color,
+% colour,
+% cols,
+% conjugate,
+% delimiter,
+% delimiters,
+% dotted,
+% e,
+% east,
+% english,
+% entries,
+% finite,
+% font,
+% french,
+% halign,
+% height,
+% infinite,
+% inner,
+% label,
+% left,
+% math,
+% no,
+% nodes,
+% north,
+% only,
+% ribbon,
+% ribbons,
+% right,
+% rows,
+% scale,
+% separator,
+% separators,
+% shape,
+% shifted,
+% skew,
+% snobs,
+% valign,
+% south,
+%% star,
+%% style,
+% tabloid,
+% text,
+% text,
+% type,
+% ukrainian,
+% wall,
+% west,
+% width,
+% xoffset,
+% xscale,
+% yoffset,
+% yscale,
+% },
+% classoffset=2, % aTableau values
+% keywordstyle=\color{orange},%
+% morekeywords={
+% A, C, DD, AA,
+% beta,
+% bottom,
+% center,
+% centre,
+% contents,
+% false,
+% first,
+% hooks,
+% last,
+% left,
+% residues,
+% right,
+% row,
+% top,
+% true,
+% },
+% classoffset=3, % TikZ and LaTeX commands
+% keywordstyle=\color{teal},%
+% morekeywords={
+% draw,
+% foreach,
+% node,
+% small,
+% tiny,
+% tikz,
+% tikzpicture,
+% tikzset,
+% },
+% classoffset=4,% TikZ keys
+% keywordstyle=\color{red},
+% morekeywords={
+% circle,
+% fill,
+% overlay,
+% picture,
+% radius,
+% remember,
+% style,
+% },
+ classoffset=5, % commands that we want to hide :)
+ keywordstyle=\color{LightSkyBlue!10},
+ morekeywords={
+ bigskip,
+ medskip,
+ newline,
+ par,
+ qquad,
+ quad,
+ smallskip,
+ },
+}
+
+\newcounter{examples}
+\numberwithin{examples}{subsection}
+\newcommand\examplesautorefname{Example}
+
+\NewTCBListing[use counter=examples, number within=subsection,%crefname={Example}{Examples}
+]{example}{ !O{} }{%
+ enhanced,
+ skin=bicolor,
+ colframe=RoyalBlue!70,
+ colbacklower=OldLace,
+ colback=LightSkyBlue!10,
+ colbacktitle=RoyalBlue!70,
+ attach boxed title to top right={xshift=0mm,yshift=-3.1mm},
+ boxed title style={
+ size=small,
+ arc=1mm,
+ bottom=-1mm,
+ sharp corners=northwest,
+ sharp corners=southeast,
+ },
+ sharp corners=northeast,
+ parbox=false,
+ lefthand width=0.35\textwidth,
+ listing style=atableau,
+ parbox=false,
+ parskip=4mm
+ sidebyside,
+ sidebyside align=top seam,
+ sidebyside gap=2mm,
+ text and listing,
+ text outside listing,
+ boxsep = 0pt,
+ left=0mm,
+ right=2mm,
+ title={\tiny\thetcbcounter},
+ #1
+}
+
+
+\DeclareTCBListing[use counter=examples, number within=subsection,%crefname={Example}{Examples}
+]{Example}{ !O{} }{%
+ enhanced,
+ skin=bicolor,
+ colframe=RoyalBlue!50,
+ colbacklower=OldLace,
+ colback=LightSkyBlue!20,
+ colbacktitle=RoyalBlue!70,
+ breakable,
+ width=\textwidth,
+ attach boxed title to top right={xshift=0mm,yshift=-3.1mm},
+ boxed title style={
+ size=small,
+ arc=1mm,
+ bottom=-1mm,
+ sharp corners=northwest,
+ sharp corners=southeast,
+ },
+ title={\tiny\thetcbcounter},
+ sharp corners=northeast,
+ parbox=false,
+ listing style=atableau,
+ text and listing,
+ listing above text,
+ %text outside listing,
+ center lower,
+ #1
+}
+
+% ---------------------------------------------------------------------------
+\NewDocumentCommand\set{ O{} >{\SplitArgument{1}{|}}m }{#1\{\,\SetContents{#1}#2\,#1\}}
+\NewDocumentCommand\SetContents{mmm}{\IfNoValueTF{#3}{#2}{#2\,#1|\,\mathopen{}#3}}
+
+\newcommand\T{\mathsf{t}}
+\newcommand\blam{{\bm{\lambda}}}
+
+% ---------------------------------------------------------------------------
+% manual title
+\makeatletter
+\author{Andrew Mathas}
+\usepackage{tikz}
+\usetikzlibrary{
+ backgrounds,
+ decorations.pathmorphing,
+ matrix,
+ patterns,
+ shadows.blur,
+ shapes.geometric,
+}
+\tikzset{
+ shadowed/.style={
+ blur shadow={shadow blur steps=5},
+ bottom color=RoyalBlue,
+ draw=NavyBlue!70,
+ shade,
+ font=\normalfont\Huge\bfseries\scshape,
+ %rounded corners=8pt,
+ top color=LightSkyBlue!30,
+ },
+ boxes/.style={draw=RoyalBlue,
+ fill=AliceBlue,
+ font=\sffamily\small,
+ inner sep=5pt,
+ rectangle,
+ rounded corners=8pt,
+ text=MidnightBlue,
+ }
+}
+
+% define the heading as a command because it contains \atableau@version
+\newcommand\aTableauHeader{%
+ \begin{center}
+ \begin{tikzpicture}
+ \aTabset{border=false}
+ \draw[shadowed, rounded corners](30mm,0) rectangle node[white]{ } (\paperwidth-30mm,22mm);
+ \begin{scope}[shift={(2.6,-0.2)}]
+ \aTabset{scale=0.5, ribbon style={fill=LightSkyBlue!10}, inner wall=MidnightBlue}
+ \Diagram(4,2) [ribbons={11,12,13,21,23,31,32,33,41,43,51,53}]{} % A
+ \Diagram(5,2) [ribbons={11,12,13,22,32,42,52}]{} % T
+ \Diagram(6,2) [ribbons={11,12,13,21,23,31,32,33,41,43,51,53}]{} % A
+ \Diagram(7,2) [ribbons={11,12,13,21,23,31,32,33,41,43,51,52,53}]{} % B
+ \Diagram(8,2) [ribbons={11,21,31,41,51,52,53}]{} % L
+ \Diagram(9,2) [ribbons={11,12,13,21,31,32,33,41,51,52,53}]{} % E
+ \Diagram(10,2)[ribbons={11,12,13,21,23,31,32,33,41,43,51,53}]{} % A
+ \Diagram(11,2)[ribbons={11,13,21,23,31,33,41,43,51,52,53}]{} % U
+ \end{scope}
+ \node[anchor=west,boxes] at (4cm,0cm) {Andrew Mathas};
+ \node[anchor=east,boxes] at (\paperwidth-4cm,0) {Version \atableau@version};
+ \end{tikzpicture}
+ \end{center}
+}
+
+% ----------------------------------------------------------------------
+\hypersetup{
+ pdfcreator={ Generated by pdfLaTeX },
+ pdfinfo={
+ Author ={ Andrew Mathas },
+ Keywords={ Algebraic combinatorics, representation theory, abacus, Young diagram, tableau, symmetric groups },
+ License ={ LaTeX Project Public License v1.3c or later },
+ Subject ={ LaTeXing tableaux and friends },
+ Title ={ ATableau - \atableau@version }
+ },
+ colorlinks=true,
+ linkcolor=blue,
+ urlcolor=MediumBlue,
+}
+
+\makeatother
+
+% ----------------------------------------------------------------------
+\numberwithin{equation}{subsection}
+\def\equationautorefname~#1\null{(#1)\null}
+\renewcommand\sectionautorefname{Chapter}
+\renewcommand\subsectionautorefname{Section}
+\renewcommand\subsubsectionautorefname{Subsection}
+
+\begin{document}
+
+ % --------------------------------------------------------------
+ % title page
+ \begin{center}
+
+ \aTableauHeader
+
+ \begin{quote}
+ A \LaTeX\ package for symmetric group combinatorics, including Young
+ diagrams, tableaux, tabloids, skew tableaux, shifted tableaux, ribbon
+ tableaux, multitableaux, abacuses.
+ \end{quote}
+
+ \begin{minipage}{0.75\textwidth}
+ \tableofcontents
+ \end{minipage}
+
+ \aTabset{scale=0.6}
+ \tikzset{
+ B/.style={fill=blue,text=white},
+ G/.style={fill=ForestGreen,text=yellow},
+ R/.style={fill=red,text=white},
+ Y/.style={fill=yellow,text=ForestGreen},
+ b/.style={ball color=blue},
+ r/.style={ball color=red},
+ w/.style={ball color=white},
+ }
+ \begin{tikzpicture}
+ \Tableau(0,0){[R]1[B]2,[G]3,[Y]4} \quad
+ \Tableau(2.25,1)[australian]{[R]1[B]2,[G]3,[Y]4} \quad
+ \Tableau(3.5,1.75)[skew={0,2}]{[Y]4[G]3[R]1,[B]2} \quad
+ \Tableau(6,0)[ukrainian,skew={0,1^2}]{[B]2[R]1,[G]3,[Y]4} \quad
+ \Tableau(7.5,-1)[french,skew={0,1^2}]{[B]2[R]1,[G]3,[Y]4} \quad
+ \Tableau(6.0,-2.25)[ukrainian]{[R]1[G]3[Y]4,[B]2} \quad
+ \Tableau(3.5,-3.0)[french]{[R]1[G]3[Y]4,[B]2} \quad
+ \Tableau(2,-1)[australian]{[B]2,[R]1[G]3[Y]4} \quad
+ \Abacus(4,0.5)[abacus ends=--,scale=1.4]{3}{[b]9,[w]8,[r]8,[b]6,[b]6,[r]2,[b]1}
+ \end{tikzpicture}
+
+ \end{center}
+
+ % --------------------------------------------------------------
+ \section{Introduction}
+
+ The package provides commands for drawing common objects in algebraic
+ combinatorics and representation theory, together with styling options
+ and a key-value interface for additional customization. Under the
+ hood, everything is drawn using \TikZ (and \LaTeX3). These commands
+ can be used either as standalone commands or as part of a
+ \keyword{tikzpicture} environment. This package started as code for
+ drawing the diagrams that I need in my own research. It is written as
+ flexibly as possible in the hope that it will draw the diagrams that
+ others need.
+
+ For the impatient, here is a basic example that shows how to use the
+ two main commands provided by the \aTableau package:
+
+ \begin{example}
+ \Abacus{4}{4^3,2,1^2,0} \qquad
+ \Tableau{1239,456{10},78}
+ \end{example}
+
+ If you already know what tableaux and abacuses are, then you can
+ probably work out the (basic) syntax of these two commands from this
+ example and start using the package. If you do not know what tableaux
+ and abacuses are, then you probably don't need this package! In any
+ case, you will not find the precise mathematical definitions of these
+ objects in this manual, so please consult textbooks like
+ \cite{Mathas:ULect,Macdonald} if you need them. For more advanced
+ usage, such as adding styling, I recommend skimming through the
+ manual, and looking at the many examples. \autoref{S:keys} gives
+ quick summary of all \aTableau commands and their options.
+
+ The \aTableau commands are intended to be easy to use and easy to
+ customise. For example, partitions can be entered either as a (weakly
+ decreasing list of non-negative) integers, or using exponential
+ notation, or as a sequence of beta numbers (for the \keyword{\Abacus}
+ command), and tableaux are entered as comma-separated words. The
+ commands support the main conventions for drawing tableaux and
+ diagrams.
+
+ By way of example, the following table shows how to draw a
+ Young diagram of shape $\lambda=(4,3^2,2)$ using the four tableaux
+ conventions supported by \aTableau:
+
+ \begin{center}
+ \aTabset{align=centre}
+ \begin{tabular}{lp{0.6\textwidth}l} \toprule
+ \textcolor{aTableauMain}{Convention} &\textcolor{aTableauMain}{\aTableau command} & \textcolor{aTableauMain}{Picture} \\ \midrule
+ English & \keyword{\Tableau[english]{1234,567,89{10},{11}{12}}}\newline(the default)
+ & \Tableau{1234,567,89{10},{11}{12}}\\[10mm]
+ French & \keyword{\Tableau[french]{1234,567,89{10},{11}{12}}}
+ & \Tableau[french]{1234,567,89{10},{11}{12}}\\[10mm]
+ Ukrainian\footnotemark
+ & \keyword{\Tableau[ukrainian]{1234,567,89{10},{11}{12}}}
+ & \Tableau[ukrainian]{1234,567,89{10},{11}{12}}\\[10mm]
+ Australian\footnotemark
+ & \keyword{\Tableau[australian]{1234,567,89{10},{11}{12}}}
+ & \Tableau[australian]{1234,567,89{10},{11}{12}} \\[10mm]
+ \bottomrule
+ \end{tabular}
+ \index{english@English}
+ \index{french@French}
+ \index{ukrainian@Ukrainian}
+ \index{australian@Australian}
+ \footnotetext[1]{Some authors call this the Russian convention.}
+ \footnotetext[2]{I have not seen a name for this convention in the literature. Calling this the
+ \textit{Australian convention} seems apt.}
+ \end{center}
+
+ This table shows how the commands provided by \aTableau work: there
+ are basic commands for drawing pictures, and these pictures can be
+ embellished using optional arguments, which use a key-value interface.
+
+ The different conventions for diagrams, and tableaux, are listed in
+ order of (my perception of) their popularity in the literature. By
+ default, the \textit{English} convention is used, so we can omit
+ \emph{english}:
+ \begin{example}[lefthand width=0.4\textwidth]
+ \Tableau{1234,567,89{10},{11}{12}}
+ \end{example}
+ for the first tableau in the table. These four conventions are used
+ in exactly the same way with the \keyword{\Diagram} command:
+ \begin{example}[lefthand width=0.4\textwidth]
+ \Diagram{4,3,3,1} \qquad
+ \Diagram[ukrainian]{4,3^2,1}
+ \end{example}
+ This example shows that partitions can either be typed out in full, as
+ a comma-separated list of positive integers, or using exponential
+ notation, which is usually shorter and easier to read.
+
+ To use the package, add the following line to your document preamble:
+
+ \indexcmd{usepackage}
+ \begin{quote}
+ \keyword{\usepackage[options]{atableau}}
+ \end{quote}
+
+ Here, the \textit{options} is an optional comma-separated list of
+ \aTableau options, or keys. We describe the possible options below.
+ For example, to make the tableaux and Young diagrams commands use the
+ \option{French} convention, by default, you could write:
+
+ \begin{quote}
+ \keyword{\usepackage[french]{atableau}}
+ \end{quote}
+
+ You can change the default options at any point in your document using
+ the \keyword{\aTabset} command, and you can change them for any
+ diagram.
+ \indexcmd{aTabset}
+
+ Each of the \aTableau commands is designed to be easy to use, easy to read,
+ and easy to customise. Each command accepts an optional list
+ of key-value options that modify and embellish the diagrams. In addition, optional
+ styling can be applied to entries of a tableau and the beads in an
+ abacus. Each command can be used as a standalone object in a
+ document, or they can be incorporated into a larger
+ \keyword{tikzpicture} environment, making it possible to use
+ these commands to create more complicated pictures.
+
+ The general syntax of an \aTableau command is:
+ \begin{quote}
+ \keyword{\Command (x,y) [options] {...specifications...}}
+ \end{quote}
+
+ \index{Cartesian coordinates}
+ The $(x,y)$-Cartesian coordinates%
+ \footnote{Currently, only Cartesian coordinates are supported. For
+ example, it is not possible to use named or polar coordinates.}
+ are optional, being necessary if (and only if), the diagram is part of
+ a~\keyword{tikzpicture} environment. See \autoref{SS:coordinates} and
+ \autoref{SS:abcoordinates} for more detail about how these coordinates
+ work for tableaux and abacuses, respectively.
+
+ The key-value \emph{options}, or \emph{keys}, control the style and
+ appearance of the final diagram. The keys are optional and are
+ described in detail below, with examples. This section emphasises only
+ some of these options together with the fact that every key can be set
+ ``globally'' (inside the current \LaTeX\ group), by using
+ \keyword{\aTabset{...options...}}, or ``locally'', for the current
+ picture. As discussed already, the default options for the entire
+ document can also be set via
+ \keyword{\usepackage[options]{atableau}}.\indexcmd{aTabset}
+
+ Many of the \aTableau options are specific to the particular diagrams
+ being drawn. The full list of the \aTableau commands and their options
+ is given in \autoref{S:keys}, with the following sections giving more
+ details and many examples. The following options are common to all
+ \aTableau commands.
+
+ \begin{options}
+ \item[align]\index{align}
+ Sets the baseline for vertically aligning diagrams. The options
+ are \keyword{align=top}, \keyword{align=center}, and
+ \keyword{align=bottom}, which aligns the baseline of the diagram
+ with the top, centre or bottom of the surrounding objects,
+ respectively. By default, all \aTableau pictures are centered.
+
+ \item[math entries, text entries]\index{math entries}\index{text entries}
+ Determines whether tableaux entries, and bead labels, are typeset as
+ mathematics or text.
+
+ \item[name]\index{name}
+ Set the prefix for the \TikZ \emph{named anchors} for the boxes and
+ beads in \aTableau diagrams.
+
+ \item[scale, xscale,
+ yscale]\index{scale}\index{xscale}\index{yscale}
+ Use \option{scale} to rescale all \aTableau diagrams. Use
+ \option{xscale} to rescale in the $x$-direction and \option{yscale}
+ to rescale in the $y$-direction.
+
+ \item[styles]\index{styles}
+ A short-hand for defining single-use \TikZ-styles for the current
+ picture.
+
+ \item[tikzpicture]\index{tikzpicture}
+ When used without Cartesian coordinates, all \aTableau commands are
+ implicitly drawn inside a \keyword{tikzpicture} environment. Use
+ \option{tikzpicture=keys} to set the optional argument of this
+ environment: \keyword{\begin{tikzpicture}[ keys ]...\end{tikzpicture}}.
+
+ \item[tikz before, tikz after]\index{tikz before}\index{tikz after}
+ Use the \option{tikz before} and \option{tikz after} keys to inject
+ \TikZ code into the \keyword{tikzpicture} environment, before and
+ after the picture drawn by \aTableau.
+
+ \end{options}
+
+ With boolean options, which are set to \textsf{true} or
+ \textsf{false}, the value can typically be omitted. For example,
+ \option{border} is equivalent to \option{border=true} and to
+ \option{no border=false}. The \option{no border} key is inverse to
+ \option{border}, so \option{no border} is equivalent to \option{no
+ border=true}, and to \option{border=false}.
+
+ \index{American dialect}
+ For all keys, American spelling variations are tolerated. For example, you
+ can use \emph{center} and \emph{color} instead of the correct
+ spellings of \emph{centre} and \emph{colour}, respectively.
+
+ \begin{warning}
+ Unlike the egalitarian \aTableau settings, \TikZ-style settings
+ \emph{do not} countenance English spelling of the English language!
+ \end{warning}
+
+ The next example contrasts using the \keyword{\Diagram} command both
+ outside and inside a \keyword{tikzpicture} environment. More
+ explicitly, the second \keyword{\Diagram} command has Cartesian
+ coordinates because it is being used inside a \keyword{tikzpicture}
+ environment. Otherwise, these two \keyword{\Diagram} commands are
+ identical, except that the second diagram is embellished with labels
+ that are drawn by the other commands in the \keyword{tikzpicture}
+ environment.
+
+ \begin{Example}
+ % \usetikzlibrary{patterns}
+ \tikzset{
+ B/.style={pattern=north east lines, pattern color=blue},
+ G/.style={pattern=north west lines, pattern color=ForestGreen},
+ }
+ \Diagram[ribbons={(G)16ccccrrr, (B)16crrcccr}]{6,5^2,2} % outside tikzpicture
+ \qquad \qquad
+ \begin{tikzpicture} % inside tikzpicture with labels
+ \Diagram(0,0)[ribbons={(G)16ccccrrr, (B)16crrcccr}]{6,5^2,2}
+ % add the labels
+ \draw[->](1.5, 0.5)node[right]{$\alpha=(1,2)$} to [out=180,in=90] (A-1-2.base);
+ \draw[->](1.5,-2.5)node[right]{$f_\alpha=(4,2)$} to [out=180,in=270] (A-4-2.base);
+ \draw[red,<->]([xshift=-1mm]A-1-1.south west)
+ --node[rotate=90,above]{$l_\alpha=3$}([xshift=-1mm]A-4-1.south west);
+ \end{tikzpicture}
+ \end{Example}
+
+ The first diagram shows that most of the right-hand diagram is drawn
+ by the~\keyword{\Diagram} command, even though most of the commands in
+ the example are \TikZ commands. In particular, the shading of the
+ boxes in the \emph{$(1,2)$-hook} and \emph{$(1,2)$-rim hook} is done
+ by the \option{ribbons} key. (In fact, the right-hand picture could be
+ drawn without using a \keyword{tikzpicture} environment by using
+ the \option{tikz after} key to add the \keyword{\draw}-commands.)
+
+ The top of the last example defines two \TikZ-styles, \textsf{B} and
+ \text{G}, which add the \textsf{b}lue and \textsf{g}reen coloured
+ hatchings of the two hooks. Inside the \keyword{tikzpicture}
+ environment, the Young diagram is placed at position $(0,0)$ by the
+ \keyword{\Diagram} command. The three \keyword{\draw} commands are
+ used to add the three labelled arrows to the picture. Please consult
+ the very readable \TikZ manual for more details on the \TikZ-commands
+ in this example.
+
+ From the viewpoint of \aTableau, the most important point of the last
+ example is that the first \keyword{\Diagram} command is a standalone
+ diagram, whereas the second one is part of a \keyword{tikzpicture}
+ environment because it was given the Cartesian coordinate $(0,0)$. The
+ second important point is that this example uses four \emph{named
+ coordinates}: (\textsf{A-1-1}), (\textsf{A-1-2}), (\textsf{A-4-1}),
+ and (\textsf{A-4-2}). When \aTableau draws a tableau, or a diagram, it
+ creates a \TikZ named coordinate (\textsf{A-r-c}) for every box in the
+ diagram, where (\textsf{A-r-c}) is the box in row~\textsf{r} and
+ column~\textsf{c}. These named coordinates, or anchors, are
+ \textit{only} defined for the boxes in the tableau. Giving finer
+ control, the following standard \TikZ \textit{anchors} are available,
+ depending on which tableaux convention you are using:
+
+ \begin{equation}\label{E:NodeNames}
+ \begin{tikzpicture}[every node/.style={font=\tiny, text=gray}]
+ \Diagram(0,0)[scale=4]{1}
+ \node[label={above:(A-r-c)}] at (A-1-1){$\color{red}\bullet$};
+ \node[label={above:(A-r-c.north)}] at (A-1-1.north){$\color{red}\bullet$};
+ \node[label={below:(A-r-c.south)}] at (A-1-1.south){$\color{red}\bullet$};
+ \node[label={right:(A-r-c.east)}] at (A-1-1.east){$\color{red}\bullet$};
+ \node[label={left:(A-r-c.west)}] at (A-1-1.west){$\color{red}\bullet$};
+ \node[label={above right:(A-r-c.north east)}] at (A-1-1.north east){$\color{red}\bullet$};
+ \node[label={above left:(A-r-c.north west)}] at (A-1-1.north west){$\color{red}\bullet$};
+ \node[label={below right:(A-r-c.south east)}] at (A-1-1.south east){$\color{red}\bullet$};
+ \node[label={below left:(A-r-c.south west)}] at (A-1-1.south west){$\color{red}\bullet$};
+ \end{tikzpicture}
+ \qquad
+ \begin{tikzpicture}[every node/.style={font=\tiny, text=gray}]
+ \Diagram(0,0)[ukrainian, scale=4]{1}
+ \node[label={above:(A-r-c)}] at (A-1-1){$\color{red}\bullet$};
+ \node[label={above:(A-r-c.north)}] at (A-1-1.north){$\color{red}\bullet$};
+ \node[label={below:(A-r-c.south)}] at (A-1-1.south){$\color{red}\bullet$};
+ \node[label={right:(A-r-c.east)}] at (A-1-1.east){$\color{red}\bullet$};
+ \node[label={left:(A-r-c.west)}] at (A-1-1.west){$\color{red}\bullet$};
+ \node[label={above right:(A-r-c.north east)}] at (A-1-1.north east){$\color{red}\bullet$};
+ \node[label={above left:(A-r-c.north west)}] at (A-1-1.north west){$\color{red}\bullet$};
+ \node[label={below right:(A-r-c.south east)}] at (A-1-1.south east){$\color{red}\bullet$};
+ \node[label={below left:(A-r-c.south west)}] at (A-1-1.south west){$\color{red}\bullet$};
+ \end{tikzpicture}
+ \end{equation}
+
+ You can change the prefix \textsf{A} in these anchors using the
+ \option{name} key. Similar anchors are created for abacus beads.
+ These \textit{anchors} are a standard part of \TikZ. If you change
+ the shape of the node, then the available anchors may change; for more
+ information see the \TikZ manual.
+
+% The previous example also shows that the \keyword{\Diagram} command
+% accepts a \option{ribbons} option, which adds one or more
+% \textit{ribbons} to the diagram. Both the ribbon and the individual
+% boxes in the ribbon can be given \TikZ styling; see
+% \autoref{S:RibbonTableaux}. All of the options to these commands are
+% described in the following sections.
+
+ In the example above, the Cartesian coordinate $(0,0)$ is necessary
+ because the \keyword{\Diagram} command is used inside a
+ \keyword{tikzpicture} environment, but the choice of coordinate is not
+ important in the sense that changing the coordinate will not change
+ the picture. Cartesian coordinates become more meaningful when the
+ \keyword{tikzpicture} environment has more components. In the next
+ example, the key \option{name=B} makes the named
+ coordinates for the second diagram take the form (\textsf{B-r-c}),
+ instead of the default node names (\textsf{A-r-c}), which are used in
+ the first diagram. This allows us to draw (wavy) lines between boxes
+ in the two tableaux.
+
+ \begin{example}[lefthand width=0.14\textwidth, sidebyside gap=0mm,label={Ex:ABnames}]
+ % \usetikzlibrary{decorations.pathmorphing}
+ \begin{tikzpicture}[wave/.style={thick,red,->,decorate,decoration=snake}]
+ \aTabset{ribbon style={fill=blue!20, opacity=0.4}}
+ \Diagram(0,0)[e=2,entries=residues,ribbons={13crc}]{3,2}
+ \Diagram(0,-2.5)[e=2,entries=residues,ribbons={12rcr},name=B]{2^2,1}
+ \draw[wave]([shift={(0,-0.05)}]A-2-1.south east)
+ --([shift={(0,0.05)}]B-1-1.north east);
+ \end{tikzpicture}
+ \end{example}
+
+ In this example, the entries in the two tableaux were added by the key
+ \option{entries=residues}, which automatically puts the
+ \option{e}-residue into each of the boxes in the two tableaux. The
+ shading is done by the \option{ribbons} commands. Notice that
+ \option{ribbon style}, which sets the \TikZ-style of the ribbons,
+ includes \keyword{opacity=0.4}. This necessary because the ribbons
+ are drawn \textit{after} the tableau entries; see \autoref{SS:order}.
+ Alternatively, these tableau entries could be included in the ribbon
+ specifications, as described in \autoref{S:RibbonTableaux}.
+
+ The final example in the introduction uses \keyword{\ShiftedTableau}
+ inside a \emph{matrix of nodes}:
+
+ \begin{Example}
+ % \usetikzlibrary{matrix}
+ \begin{tikzpicture}[scale=0.8, arr/.style={->,SteelBlue, thick}]
+ \matrix (M)[matrix of nodes,row sep=4mm,column sep=4mm]{
+ & & & \ShiftedTableau{1234,567} \\
+ & & \ShiftedTableau{1235,467}
+ & & \ShiftedTableau{1243,567}\\
+ & \ShiftedTableau{1236,457}
+ & & \ShiftedTableau{1245,367}
+ & & \ShiftedTableau{1253,467}\\
+ \ShiftedTableau{1237,456}
+ & & \ShiftedTableau{1246,357}
+ & & \ShiftedTableau{1254,367}\\
+ & \ShiftedTableau{1247,356}\\
+ };
+ \draw[arr](M-1-4)--node[above]{$\sigma_4$}(M-2-3);
+ \draw[arr](M-1-4)--node[above]{$\sigma_3$}(M-2-5);
+ \draw[arr](M-2-3)--node[above]{$\sigma_5$}(M-3-2);
+ \draw[arr](M-2-3)--node[above]{$\sigma_3$}(M-3-4);
+ \draw[arr](M-2-5)--node[above]{$\sigma_4$}(M-3-6);
+ \draw[arr](M-3-2)--node[above]{$\sigma_6$}(M-4-1);
+ \draw[arr](M-3-2)--node[above]{$\sigma_3$}(M-4-3);
+ \draw[arr](M-3-4)--node[above]{$\sigma_5$}(M-4-3);
+ \draw[arr](M-3-4)--node[above]{$\sigma_4$}(M-4-5);
+ \draw[arr](M-3-6)--node[above]{$\sigma_3$}(M-4-5);
+ \draw[arr](M-4-1)--node[above]{$\sigma_3$}(M-5-2);
+ \draw[arr](M-4-3)--node[above]{$\sigma_6$}(M-5-2);
+ \end{tikzpicture}
+ \end{Example}
+
+ Notice that even though the \keyword{\SkewTableau} commands are being
+ used inside a \keyword{tikzpicture} environment they do not need
+ coordinates because the skew tableaux are being placed by the \TikZ
+ \keyword{\matrix} command. That is, the \keyword{\SkewTableau}
+ commands are not explicit components of the \keyword{tikzpicture}
+ environment as hey are all (implicitly) inside \TikZ-nodes.
+
+ The following sections describe the commands defined by the \aTableau
+ package and how to use them. We start with the \keyword{\Tableau}
+ command because all of the diagram and tableau commands, except for
+ \keyword{\RibbonTableau}, are derived from \keyword{\Tableau}.
+
+ % --------------------------------------------------------------
+ \section{Tableaux and Young diagrams}
+
+ \emph{Partitions} are weakly decreasing sequences of non-negative
+ integers. They are fundamental objects in algebraic combinatorics
+ and representation theory.\index{partition} Rather than working
+ with sequences of integers, it is often useful to visualise
+ partitions as Young \emph{diagrams}, which are arrays of
+ \emph{boxes}, or \emph{nodes}, in the plane\footnote{In this manual,
+ we normally refer to the entries of tableaux and diagrams as
+ \textit{boxes}, rather than \textit{nodes}. This is to avoid any
+ ambiguity with \TikZ-nodes.}. A \emph{tableau} is a (Young) diagram
+ where the boxes are labelled using some alphabet. Equivalently, a
+ diagram is a tableau with empty labels.
+ \index{young diagram@Young diagram|see{diagram}}
+ \index{diagram}
+ \index{tableau}
+ \index{box}
+ \index{node}
+ \index{node|see{box}}
+ \index{exponential notation}
+ \index{partition!exponential notation}
+
+ For example, $\lambda=(4,3,3,2,0,0,\dots)$ is a partition of $12$,
+ since the entries sum to~$12$. It is customary to omit the zeros
+ when writing partitions and to use exponents for repeated parts, so
+ we can write this partition in \emph{exponential notation} as
+ $\lambda=(4,3^2,2)$. Many authors identity a
+ partition~$\lambda=(\lambda_1,\lambda_2,\dots)$ with its
+ \emph{diagram}, which is the set $[\lambda] = \set{(r,c)|1\le
+ c\le\lambda_r\text{ for }r\ge1}$. When using the \emph{English
+ convention}, the diagram of~$\lambda$ is visualised as a left
+ justified array of boxes in the plane, where the first row has~$4$
+ boxes, the next two lower rows have~$3$ boxes and the last row
+ has~$2$ boxes. The \emph{shape} of a diagram is the partition that
+ gives the number of boxes in each row. Diagrams and tableaux drawn
+ using the \emph{French} convention are given by reflecting in a
+ horizontal line above the diagrams, whereas the \emph{Ukrainian} and
+ \emph{Australian} conventions are given by appropriately rotating
+ these diagrams. All of these conventions are used in the literature,
+ with some papers using more than one convention.
+
+ % --------------------------------------------------------------
+ \subsection{Tableaux}
+ \indexcmd{Tableau}
+ \label{S:Tableau}
+ This section describes the \keyword{\Tableau} command, which draws
+ tableaux or labelled diagrams. The syntax of this command is:
+
+ \keyword{\Tableau (x,y) [options] {tableau entries}}
+
+ where:
+
+ \begin{options}
+ \item[$(x,y)$]\index{xy@$(x,y)$} The Cartesian coordinates $(x,y)$
+ are needed if, and only if, the tableau is a component of a
+ \keyword{tikzpicture} environment.
+ \item[options] Optional arguments. Described, with examples, below.
+ \item[tableau entries]\index{tableau entries} The
+ \keyword{tableau entries} are given as a comma-separated list, with commas
+ separating rows and each \textit{token}, or braced-group of
+ tokens, being in a separate column. As we explain below, each
+ tableau entry can be prefixed by (optional) \TikZ-styling
+ specifications.
+ \end{options}
+
+ We show by example how to use the \keyword{\Tableau} command,
+ starting with basic usage and finishing with style. Inside
+ \keyword{\Tableau}\!, the rows are separated by commas, with the
+ columns given by the ``letters'' in the word for each row:
+
+ \begin{example}
+ \Tableau{ 1234, 56, 7, 8 } \qquad
+ \Tableau{ \alpha\gamma\delta q,
+ xy\eta,
+ \lambda\mu,
+ \pi\sum }
+ \end{example}
+
+ The tableau specifications can be put on a single line, without any
+ spaces. Alternatively, as shown here, spaces and line breaks can be
+ added to improve readability. The one restriction is that you cannot
+ have blank lines inside a \keyword{\Tableau} command. As this example
+ suggests, by default, the entries in a tableau are typeset in
+ mathematics-mode, but this can be changed using the
+ \option{text entries} key, which is described below.
+
+ As the examples above show, the tableau entries can be individual
+ characters, or they can be \TeX\ commands. Tableaux frequently contain
+ entries that are not single characters, or given by commands. Such
+ entries can be added to a tableau by enclosing them in braces:
+
+ \begin{example}
+ \Tableau{ 13{10}{11}{2x}, 2{x^2}, {r_1} }
+ \end{example}
+
+ % There is one additional caveat for braced-entries: any
+ % \textit{singleton} braced entry \keyword{{...}} in a row needs to be
+ % \textit{double-braced}. Double-bracing is only necessary when you have
+ % a row that has only one column, and you have a multi-letter column
+ % entry. The need for double-bracing is a consequence of how \LaTeX3
+ % detects braced commas in comma-separated lists.
+ % \index{tableau entries!double-braced}
+ % \index{double-braced}
+
+ % The following example shows the difference between single and
+ % double-bracing for tableau entries.
+ % \index{tableau entries!double-braced}
+
+ % \begin{example}
+ % \Tableau{ 1345, 8{10}, {11}, {12} } \qquad
+ % \Tableau{ 1345, 8{10}, {{11}}, {{12}} }
+ % \end{example}
+
+ % The $10$'s in these tableaux do not need to be doubled-braced because
+ % they appear in a row of length~$2$, whichi s greater than~$1$!. In
+ % contrast, because they are not doubled-braced, the~$11$ and~$12$ in
+ % the first tableau are both treated as being two characters in
+ % different columns in the first tableau. In the second tableau,
+ % the~$11$ and~$12$ each appear in a separate column because they are
+ % double-braced.
+
+ % --------------------------------------------------------------
+ \subsubsection{Adding style}
+ \index{star}
+ \index{*|see{star}}
+ \index{tableau entries!style}
+ \index{tableau entries!star}
+
+ The \aTableau package provides several different ways to add \TikZ
+ style specifications to the boxes in diagrams and tableaux. This is
+ done by adding style prefixes to the tableau entries. To take
+ advantage of these styles you need to have at least rudimentary
+ knowledge of \TikZ-styling. The examples in this manual might be
+ enough to get you started as they give a good indication of what is
+ possible. For anything more exotic, please consult the \TikZ manual.
+
+ The simplest way to change the style of an entry in a tableau is to
+ add a $*$-prefix to the entry:
+
+ \begin{example}
+ \Tableau{ 1*2*3*4*5, 6*789, {10}*{11}{12}, {13} }
+ \end{example}
+
+ In this tableau, there is an asterisk before each of the entries $2$,
+ $3$, $4$, $5$ and $8$, which gives the corresponding boxes the
+ \option{star style}. The $*$-entries are given the
+ \TikZ-styling, which is \keyword{fill=}\aTableauColour{StarStyle} by default. You can
+ change the default $*$-style using the \option{star style} key:
+
+ \begin{example}
+ \Tableau[star style={fill=red!20,draw=red,thick}]
+ { 1*2*3*4*5, 6*789, {10}*{11}{12}, {13} }
+ \end{example}
+
+ Note that the $*$-styling overrides the default styling of the
+ surrounding boxes. This is because the boxes with the default styling
+ are placed first, in the order that they are entered, after which the
+ boxes with custom styles are placed.
+
+ The $*$-syntax is a quick shorthand for adding emphasis to some boxes
+ in a tableau, but all of the $*$-entries are given the same style.
+ It is possible to give every box in the tableau different styles by
+ putting \TikZ-styling specifications inside square brackets,
+ \keyword{[...]}, before the corresponding letter in the tableau
+ specification. You can mix the $*$-syntax and the
+ \keyword{[...]}-style syntax for different entries, although only one
+ of these style settings can be applied to any given box.
+
+ \begin{example}
+ \Tableau[french]{
+ 1 [blue!20]2 [circle]3 [red]4 [cyan]5,
+ 6 *7 8 9,
+ {10} *{11} {12},
+ {13} }
+ \end{example}
+
+ It is not necessary to add spaces between the entries in the way that
+ this example does. This is done only to make it clearer how the
+ style specifications are applied to the different entries in the tableau.
+
+ Omitting some technicalities, each box in a tableau is constructed as
+ a \TikZ node, so any \TikZ-styling specifications for a node can be
+ used. This example shows that some care is needed when changing the
+ style because simply giving a colour changes both the colour used to
+ \textit{fill} the box and the \textit{text colour}, which is why some
+ of tableau entries in the last example appear to be blank. If you are
+ already familiar with \TikZ then you probably already know what to do.
+ If not, then here is a short list of useful style specifications for
+ \TikZ nodes:
+ \begin{center}\index{fill}\index{text}\index{draw}\index{font}
+ \begin{tabular}{ll}\toprule
+ Style & Meaning \\\midrule
+ \keyword{draw}$=\langle\text{colour}\rangle$
+ & Sets the boundary colour of the node\\
+ \keyword{fill}$=\langle\text{colour}\rangle$
+ & Sets the fill, or background, colour of the node\\
+ \keyword{font}$=\langle\text{font commands}\rangle$
+ & Sets the font \\
+ \keyword{opacity}$=\langle\text{value}\rangle$
+ & Sets both the drawing and filling opacity to $=\langle\text{value}\rangle$\\
+ \keyword{text}$=\langle\text{colour}\rangle$
+ & Sets the text colour in the node \\
+ \bottomrule
+ \end{tabular}
+ \end{center}
+ In the style settings, any valid \LaTeX\ colour name can be used; see, for
+ example, the \ctan{xcolor} manual. In addition, the style specifications
+ \keyword{thin}\!,
+ \keyword{thick}\!,
+ \keyword{very thick}\!,
+ \keyword{ultra thick}\!,
+ \keyword{dashed}\!,
+ \keyword{dotted}\!, $\dots$.
+ change the border thickness, and its properties.
+ \autoref{SS:TableauOptions} below describes how to use these options
+ to customise the tableau style.
+
+ If you want to apply ``complicated'' style settings, such as
+ \keyword{draw=cyan,ultra thick}, which consists of a comma-separated
+ list of $\TikZ-$style settings, then the entire style must be put
+ inside matching square brackets and curly braces \keyword{[{...}]}.
+ This is necessary to ensure that \LaTeX\ does not get confused by the
+ commas in the style setting (since commas are also used to separate
+ the rows of the tableau).
+
+ \begin{example}
+ \Tableau[australian]{
+ 1 [fill=blue!20]2 3 [text=red]4 5,
+ [{circle,fill=orange}]6 *7 8 9,
+ [{draw=cyan,ultra thick}]{10} *{11} {12},
+ [{dashed,draw=red,ultra thick}]{13} }
+ \end{example}
+
+ % The last example shows that it is not necessary to double-brace
+ % singleton entries when they have a style specification.
+
+ This example shows that modifying the borders of a box is problematic
+ because boxes placed later are likely to overwrite the new border
+ style (see \autoref{SS:order}). As a result, modifying the borders of
+ the boxes is often not a good way to add emphasis to a tableau, so
+ use this sparingly. In addition, the orange circle in this example
+ looks too big, but it is what we asked for because the diameter of the
+ circle is the horizontal width of the box. The next example shows that
+ we get a better result with \textit{minimum size} specification when
+ using the \textit{Australian} and \textit{Ukrainian} conventions for
+ tableaux.
+
+ For complex or frequently used styles, we recommend using the
+ \keyword{\tikzset} command to define the style outside of the
+ \keyword{\Tableau} command. This makes your code both easier to read
+ and easier to change. If you need to define a style for a single
+ picture, then you can also use the \option{styles} key.
+
+ \begin{example}[lefthand width=0.3\textwidth]
+ \tikzset{
+ B/.style={fill=blue!40, text=yellow},
+ G/.style={fill=green!80!blue,circle,minimum size=5mm},
+ R/.style={fill=red,text=white, font=\tiny},
+ Y/.style={fill=yellow!20, text=blue}
+ }
+ \Tableau[french]{[R]1[B]2,[G]3,[Y]4} \quad
+ \Tableau[ukrainian]{[R]1[B]2,[G]3,[Y]4} \newline
+ \Tableau[english]{[R]1[B]2,[G]3,[Y]4} \quad
+ \Tableau[australian]{[R]1[B]2,[G]3,[Y]4}
+ \end{example}
+
+ In this example, the \TikZ-styles \textsf{B}, \textsf{G} \textsf{R},
+ and \textsf{Y} are applied to the tableaux entries labelled $1$, $2$,
+ $3$, and $4$, respectively. Note the use of \emph{minimum size} to
+ control the size of the circle. The colours used here, and throughout
+ this manual, are for demonstration purposes only. I recommend against
+ such garish choices in any self-respecting document!
+
+ % --------------------------------------------------------------
+ \subsubsection{Tableau coordinates}\label{SS:coordinates}
+ \index{xy@$(x,y)$}
+ \index{Cartesian coordinates!tableau}
+
+ The $(x,y)$-coordinates are required if, and only if, the
+ \keyword{\Tableau}command is used inside a \keyword{tikzpicture}
+ environment, in which case $(x,y)$ gives the coordinates of the
+ ``outside corner'' of the box in row~$1$ and column~$1$ of the
+ tableau. The following example shows how tableaux are placed using
+ $(x,y)$-coordinates inside a \keyword{tikzpicture} environment. The example
+ also shows that, by default, the tableau boxes are square and half a unit wide.
+
+ \tikzset{
+ add grid/.code = {
+ % draw coordinate axes
+ \draw[help lines, step=0.5,thin, LightGrey](-0.5,-1.5) grid (4,2.5);
+ \draw[help lines, step=1,thin, Grey](-0.5,-1.5) grid (4,2.5);
+ \foreach \pt in {0,...,3} {
+ \node[below,font=\tiny] at (\pt,-1.5){$\pt$};
+ }
+ \foreach \pt in {-1,...,2} {
+ \node[left, font=\tiny] at (-0.5,\pt){$\pt$};
+ }
+ }
+ }
+
+ \begin{example}
+ \begin{tikzpicture}[add grid]
+ \Tableau(0,0) [english] {123,45}
+ \Tableau(0,0.5) [french] {123,45}
+ \Tableau(2.5,0.5)[ukrainian] {123,45}
+ \Tableau(2.5,0) [australian]{123,45}
+ \end{tikzpicture}
+ \end{example}
+
+ % --------------------------------------------------------------
+ \subsubsection{Tableau keys}
+ \label{SS:TableauOptions}
+
+ The optional $*$-styles and $[\ldots]$-styles are the main mechanism
+ for styling the individual boxes in a tableau. Using a key-value
+ syntax, you can change aspects of the tableau produced by the
+ \keyword{\Tableau} command. The rest of this section describes these
+ keys, their default values, and gives examples of how to use them.
+
+ The options below can be applied to the \keyword{\Tableau}
+ command by giving them as a comma-separated list inside square
+ brackets:
+ \begin{center}
+ \keyword{\Tableau [options] {tableau entries}}\quad or \quad
+ \keyword{\Tableau (x,y) [options] {tableau entries}}.
+ \end{center}
+ The options can appear in any order, with later options having
+ precedence over earlier ones.
+
+ When used inside a \keyword{\Tableau} command, the options only affect
+ that particular tableau. Most of these options, or keys, can also be
+ used in the \keyword{\aTabset} command, to change the default settings
+ of all tableaux in the same \LaTeX\ group, or as optional arguments in
+ \keyword{\usepackage[..]{atableau}}, to change the default settings
+ for the entire document. For example, if you put the command
+ \keyword{\aTabset[ukrainian]} in the preamble of your document then,
+ by default, all subsequent tableaux and Young diagrams will be drawn
+ using the Ukrainian convention.
+
+ \option[-]{english}
+ \option*[]{french}
+ \option*[]{ukrainian}
+ \option*[]{australian}
+
+ These four (mutually exclusive) options change the convention, or
+ orientation, that is used when drawing the tableaux. Rather than
+ defining these conventions precisely, we use the tired and true method
+ in combinatorics of defining by example.
+
+ \begin{example}[lefthand width=0.3\textwidth]
+ \Tableau[ukrainian, styles={R={fill=red!20,draw=red}}]
+ {12[R]3,45}
+ \end{example}
+
+ \begin{example}[lefthand width=0.3\textwidth]
+ \tikzset{R/.style={fill=red!20, circle, draw=red, ultra thick}}
+ \Tableau[french]{12[R]3,45}
+ \end{example}
+
+ \begin{example}[lefthand width=0.3\textwidth]
+ \tikzset{B/.style={fill=blue!20, dashed, thick}}
+ \Tableau[english]{12[B]3,45}
+ \end{example}
+
+ \begin{example}[lefthand width=0.3\textwidth]
+ \Tableau[australian, styles={B={fill=blue!20, text=white}}]
+ {12[B]3,45}
+ \end{example}
+
+ Changing the convention sets the \option{box height} and \option{box
+ width}, relative to the current \option{scale}. If you want to use a
+ custom box height and box width, then you need to set them
+ \emph{after} specifying the convention.
+
+ By default, the \option{english} convention is used to draw tableaux
+ and Young diagrams. The default convention can be changed using
+ \keyword{\aTabset}. Capitalised names, \keyword{Australian}\!,
+ \keyword{English}\!, \keyword{French} and \keyword{Ukrainian}\!, are also
+ recognised. If, for example, your document is only going to draw
+ \option{french} tableaux and diagrams, then you can specify this when
+ you load the package using \keyword{\usepackage[french]{atableau}}\!,
+ or by adding \keyword{\aTabset{french}} to your document preamble.
+
+ \option[centre]{align=value}[centre/bottom/top]
+
+ By default, the baseline of a tableau is its centre. This can be
+ changed using the \option{align} key.
+
+ \begin{example}
+ % the default
+ Some \Tableau[align=centre]{124,357,68} words
+ \end{example}
+
+ \begin{example}
+ Some \Tableau[align=top]{124,357,68} words
+ \end{example}
+
+ \begin{example}
+ Some \Tableau[align=bottom]{124,357,68} words
+ \end{example}
+
+ Similarly, use \option{align} to control how tableaux are aligned
+ in displayed equations.
+
+ \begin{example}
+ \aTabset{align=bottom}
+ \Tableau{124,357,68}\qquad
+ \Tableau{124,35}
+ \end{example}
+
+ \begin{example}
+ % by default: align=centre
+ \Tableau{124,357,68}\qquad
+ \Tableau{124,35}
+ \end{example}
+
+ \begin{example}
+ \aTabset{align=top}
+ \Tableau{124,357,68}\qquad
+ \Tableau{124,35}
+ \end{example}
+
+ \option[true]{border}[true/false] \newline
+ \option[false]{no border}[false/true]
+
+ The \option{border} and \option{no border} keys enable and disable The
+ \option{no border} key is inverse to \option{border}, so \option{no
+ border} is equivalent to \option{no border=true}the drawing of the
+ (thick) border wall around a tableau.
+
+ \begin{example}
+ \Tableau[ukrainian, border=false]{123,455,674} \qquad
+ \Tableau[french, no border]{123,455,674} \qquad
+ \end{example}
+
+ \option[\aTableauColour{Main}]{border colour=colour}[a \LaTeX~colour]
+ \option*[thick, line~cap=rect]{border style=style}[\TikZ-styling]
+
+ The \option{border colour} option sets the colour of the border wall,
+ whereas \option{border style} sets the \TikZ-styling of the border wall.
+ (So, \option{border style} can override \option{border colour}.)
+
+ \begin{example}
+ \Tableau[ukrainian, border colour=red]{123,455,674} \qquad
+ \Tableau[french, border style={dashed,orange}]{123,455}
+ \end{example}
+
+ The \option{border style} key \emph{appends} any \TikZ-styles to the
+ current styling of the wall.
+
+ % nodes
+ \option[none]{box fill=colour}[a \LaTeX~colour]
+
+ The \option{box fill} option sets the background colour of a box in a
+ tableau, which is used in exactly the same way as the \textsf{fill} key for a \TikZ-node. If you use
+ a dark fill colour, then you will almost certainly want to change the
+ text colour using the \option{box text} key -- and you may also want to
+ change the colours of the border walls and inner walls using
+ \option{border colour} and \option{inner wall}, respectively.
+
+ \begin{example}
+ \Tableau[box fill=blue, box text=yellow]{123,455,674} \qquad
+ \Tableau[box fill=red!10]{123,455}
+ \end{example}
+
+ \option[]{box font=font command}[\LaTeX\ font command]
+
+ The \option{box font} key sets the font used to type the entries of a
+ tableau. By default, tableau entries are typeset as mathematics, so
+ this is mainly useful for changing the font size (because, for example
+ \keyword{\bfseries $1$} does not make the $1$ bold). It is only when
+ you are using \option{text entries} that font commands like
+ \keyword{\itshape} and \keyword{\bfseries} will have any effect.
+
+ \begin{example}
+ \Tableau[box font=\tiny]{123,455,674} \qquad
+ \Tableau[text entries, box font=\bfseries]{123,455}
+ \end{example}
+
+ \option[0.5]{box height=number}[a decimal giving the height in \unit{cm}]
+ \option*[0.5]{box width=number}[a decimal giving the width in \unit{cm}]
+
+ Sets the width and height of the boxes in the tableau. The default
+ height and width of the boxes is \qty{0.5}{cm} when using the
+ \option{english} and \option{french} conventions and
+ \qty{0.7012}{cm}, which is approximately $1/\sqrt{2}$\unit{cm}, when
+ using the \option{ukrainian} and \option{australian} conventions. (In
+ all cases, the default side length of the boxes is \qty{0.5}{cm}.)
+
+ \begin{example}
+ \aTabset{align=top}
+ \Tableau[box height=0.8]{123,455,674} \qquad
+ \Tableau[box width=0.2, ukrainian]{123,455}
+ \end{example}
+
+ The \option{box height} and \option{box width} keys need to be set
+ \emph{after} changing the tableau convention using
+ \option{australian}, \option{english}, \option{french}, or
+ \option{ukrainian} because the conventions change the height and width
+ of the tableau boxes (and later conventions override earlier ones). In
+ particular, in the last example, \option{box width=0.2} has no effect
+ because following \option{ukrainian} key sets the box width to
+ \qty{0.7012}{cm}.
+
+ \begin{example}
+ \aTabset{align=top}
+ \Tableau[box height=0.3]{123,455,674} \qquad
+ \Tableau[ukrainian, box width=0.3]{123,455}
+ \end{example}
+
+ See also the \option{scale}, \option{xscale} and \option{yscale}
+ options.
+
+ \option[\aTableauColour{Main}]{box text=colour}[a \LaTeX~colour]
+
+ As for a \TikZ-nodes, use \option{box text} to set the default text
+ colour for the entries of the tableau boxes.
+
+ \begin{example}
+ \Tableau[box text=red]{123,45} \qquad
+ \Tableau[box text=blue, french]{123,45}
+ \end{example}
+
+ \option[]{box style=style}[\TikZ~styling]
+
+ All of the preceding keys for tableau boxes can be overridden by using
+ \option{box style} to set the style of the tableau boxes directly.
+
+ \begin{example}
+ \Tableau[box style={text=red, draw=orange,shape=circle}]{123,45} \qquad
+ \Tableau[box style={font=\small}, french]{123,45}
+ \end{example}
+
+ \option[false]{conjugate}[false/true]
+
+ Draws the \emph{conjugate} tableau, where the rows and columns are
+ swapped.
+
+ \begin{example}
+ \Tableau{123,45,67} \qquad
+ \Tableau[conjugate]{123,45,67}
+ \end{example}
+
+ \option[centre]{halign=value}[centre, left, right]
+ \option*[centre]{valign=value}[bottom, centre, top]
+
+ By default, the entries in tableaux are centered, both horizontally
+ and vertically, and it is your responsibility to ensure that the
+ entries fit inside the tableau boxes (you can change the box
+ dimensions using the \option{box height}, \option{box width} and
+ \option{scale} keys). The \option{halign} and \option{valign} keys
+ provide a crude way to change the horizontal and vertical alignment of
+ the box entries.
+
+ \begin{example}
+ \Tableau[halign=left]{1{11}{11},{11}1} \quad
+ \Tableau[halign=centre]{1{11}{11},{11}1} \quad
+ \Tableau[halign=right]{1{11}{11},{11}1}
+ \end{example}
+
+ \begin{example}
+ \Tableau[valign=bottom]{qf,gpt,jb} \quad
+ \Tableau[valign=centre]{qf,gpt,jb} \quad
+ \Tableau[valign=top]{qf,gpt,jb}
+ \end{example}
+
+ These keys are provided for completeness only. We recommend not using them!
+
+ \option[\aTableauColour{Inner}]{inner wall=colour}[\LaTeX~colour]
+ \option*[thin, line cap=rect]{inner style=style}[\TikZ-styling]
+
+ The \option{inner wall} option sets the colour of the inner wall,
+ whereas \option{inner style} sets the \TikZ-styling of the inner wall.
+ (In particular, \option{inner style} can be used to override
+ \option{inner wall}.)
+
+ \begin{example}[label=Ex:dashed]
+ \Tableau[australian, inner wall=red]{123,455,674} \qquad
+ \Tableau[inner style=dashed]{123,455}
+ \end{example}
+
+
+ \index{dashed}
+ \index{style!dashed}
+ If you closely at the second tableau in \autoref{Ex:dashed}, you will
+ notice that the dashes are not very clean. This is because, for
+ example, the dashes on bottom of one box do not properly match up with
+ the dashes on the top of the adjacent box below it. Rather than
+ using \option{inner style=dashes} it is better to use something like
+ \option{inner style=\{dash pattern=on 1pt off 2pt\}}.
+
+ \begin{example}
+ \Tableau[inner style={dash pattern=on 1pt off 2pt}]
+ {123,455}
+ \end{example}
+
+ You can use \option{inner wall=none}, to remove the inner tableau walls. Alternatively, use \option{no boxes}.
+
+ \begin{example}
+ \Tableau[ukrainian, inner wall=none]{123,45,67} \qquad
+ \Tableau[ukrainian, no boxes]{123,45,67}
+ \end{example}
+
+ \option[none]{label=text}[any character/text]
+ \option*[font=\textbackslash scriptsize, text=\aTableauColour{Inner}]{label style=style}[\TikZ-styling]
+
+ The \option{label} key adds a label to a tableau next to the
+ $(1,1)$-box. The style of the label can
+ be changed using the \option{label style} key.
+
+ \begin{example}
+ \Tableau[ukrainian, label={\mathtt{t}}]{13,25,4} \quad
+ \Tableau[french, label=0, label style={red}]{13,5} \quad
+ \Tableau[label style={draw=orange,circle, inner sep=0pt,
+ minimum size=2mm}, label=1] {12,35,5}
+ \end{example}
+
+ Like tableau entries, \option{label} is typeset as mathematics by default .
+
+ \option[true]{math entries}[true/false]
+ \option*[false]{text entries}[true/false]
+
+ Use the \option{math entries} and \option{text entries} to have the
+ tableau entries typeset as either mathematics or text, respectively.
+ By default, the entries of a tableau are typeset as mathematics.
+
+ \begin{example}
+ \Tableau[math entries]{ABCD, efg, HI}\qquad% the default
+ \Tableau[text entries]{ABCD, efg, HI}
+ \end{example}
+
+ \option[A]{name=text}[string]
+
+ By default, the boxes can be referenced using the node names
+ \textsf{(A-1-1)}, \textsf{(A-1-2)}, \textsf{(A-1-3)}, \dots, with
+ \textsf{(A-$r$-$c$)} referring to the box in row~$r$ and column~$c$.
+ Use the \option{name} key to change the \emph{prefix} \textsf{A} to
+ anything else that you like. This feature is most useful when you
+ have several tableaux inside a \keyword{tikzpicture} environment
+ because by using \option{name} you can refer to boxes in the different
+ diagrams. If you only have one tableau, then you would not normally
+ need to change the default prefix for the node names. See
+ \autoref{E:NodeNames} for a description of the anchor names. For
+ examples using node names and anchors see \autoref{Ex:ABnames},
+ \autoref{Ex:pointing} and \autoref{Ex:waves}.
+
+ \option[]{paths=path specifications}[list of paths]
+ \option*[]{path style=style}[\TikZ-styling]
+
+ Use the \option{paths} key to add a comma-separated list of
+ \emph{ribbon paths} to the tableau. This allows you to draw certain
+ types of paths inside your tableaux and diagrams.
+
+ Ribbon paths are specified using the \keyword{\RibbonTableau} syntax,
+ where you first specify the row and column indices of the \emph{head}
+ of the ribbon, which is the unique node of maximal content in the
+ ribbon, and then give a sequence of \textsf{r}'s and \textsf{c}'s
+ depending on whether the row index increases, or the column index
+ decreases, respectively. As always, you have the option of adding
+ style --- and you can also specify the contents of each box in the
+ ribbon. For more details about the ribbon specifications, with
+ examples, see \autoref{S:RibbonTableaux}, which describes the
+ \keyword{\RibbonTableau} command.
+
+ \begin{example}
+ \Tableau[styles={R={red,thick}, C={cyan,thick}},
+ paths={(R)14ccrc,(C)23rcc}]{1234,567,89{10}}
+ \end{example}
+
+ The \option{path style} key changes the default style of the path:
+
+ \begin{example}
+ \Tableau[styles={R={red,thick}, C={cyan,thick}},
+ paths={(R)14ccrc,(C)23rcc},
+ path style={rounded corners}]{1234,567,89{10}}
+ \end{example}
+
+ \option[]{path box=text}[a node entry]
+ \option*[]{path box style=style}[\TikZ-styling]
+
+ The \option{path box} sets the default entry for every box on a path.
+ The \option{path box} is only used if you have not specified a box
+ entry as a subscript in the path/ribbon specification. This key is
+ useful if you want to mark all of the boxes in every path with the
+ same symbol.
+
+ \begin{example}
+ \tikzset{R/.style={red,thick},C/.style={cyan,thick}}
+ \Tableau[paths={(R)14ccrc,(C)23rcc},
+ path box=\bullet
+ ]{1234,567,89{10}}
+ \end{example}
+
+ Use the \option{path box style} to change the style of the boxes in
+ the path.
+
+ \begin{example}
+ \Tableau[styles={R={red,thick}, C={cyan,thick}},
+ paths={(R)14ccrc,(C)23rcc},
+ path box style={draw,circle, minimum size=4mm}
+ ]{1234,567,89{10}}
+ \end{example}
+
+ By combining \option{path box style} and \option{path style}, you can
+ ``decorate'' the boxes on a path.
+
+ \begin{example}
+ \Tableau[styles={R={red,thick}, C={cyan,thick}},
+ paths={(R)14ccrc,(C)23rcc},
+ path box style={draw,circle, minimum size=4mm},
+ path style={draw=none},
+ ]{1234,567,89{10}}
+ \end{example}
+
+ Another way to do this is to change the style of the individual paths,
+ which gives more control because different paths can be given
+ different styling.
+
+ \begin{example}
+ \Tableau[styles={R={draw=none,text=red,thick},
+ C={cyan,thick}},
+ paths={(R)14ccrc,(C)23rcc},
+ path box style={draw,circle, minimum size=4mm},
+ ]{1234,567,89{10}}
+ \end{example}
+
+ \option[]{ribbons=ribbon specifications}[list of ribbons]
+ \option*[draw=\aTableauColour{Inner}, thin]{ribbon style=style}[\TikZ-styling]
+ \option*[]{ribbon box=text}[A node entry]
+ \option*[]{ribbon box style=style}[\TikZ-styling]
+
+ Use the \option{ribbons} key to add a comma-separated list of
+ \emph{ribbons} to a tableau. The ribbon specifications are identical
+ to those used for \option{paths}. For more details see
+ \autoref{S:RibbonTableaux}, which describes the
+ \keyword{\RibbonTableau} command.
+
+ The \option{ribbons} key works in almost exactly the same way
+ as the \option{paths} key, with the difference being that we are
+ adding ribbons to the tableau rather than lines. The
+ \option{ribbon style} key controls the default ribbon style. The
+ \option{ribbon box} and \option{ribbon box style} keys work in the
+ same way as \option{path box} and \option{path box style},
+ respectively.
+
+ \TikZ-styling can be added to ribbons using \option{ribbon style} and
+ \option{ribbon box style}. The \option{ribbon style} changes the
+ default style of the entire ribbon, whereas \option{ribbon box style}
+ changes the default style of the individual boxes in the ribbon.
+
+ \begin{example}
+ \Tableau[ribbon style={fill=blue!20,opacity=0.4},
+ ribbons={22rc}]{123,45,67}
+ \end{example}
+
+ Use the \option{ribbon box style} key to change the default style of the
+ boxes in a ribbon. For example, noting that a box is a ribbon of
+ length~$1$, the following code uses ribbons of length one (that is,
+ nodes), to highlight the addable nodes of this tableau.
+
+ \begin{example}
+ \Tableau[star style={fill=green!80!blue,text=white},
+ ribbon style={fill=yellow,text=red},
+ ribbons={15_A,24_B,42_C,51_D},
+ ]{123*4,567,89*{10},*{11}}
+ \end{example}
+
+ As this example indicates, ribbons are assumed to be contained inside
+ the diagram of the tableau, so they do not change the border of a
+ tableau.
+
+ \option[]{snobs=snob specifications}[list snobs]
+ \option*[draw=\aTableauColour{Inner}, thin]{snob style=style}[\TikZ-styling]
+ \option*[]{snob box=text}[A node entry]
+ \option*[]{snob box style=style}[\TikZ-styling]
+
+ Use \option{snobs} to add ribbons to the tableau, which are ribbons
+ that are placed \textit{after} the border of the diagram is drawn.
+ (Writing \textit{ribbons} backwards gives \textit{snob}bir.) The
+ \option{snob style} key controls the default style of snobs.
+
+ \begin{example}
+ \Tableau[star style={fill=green!80!blue, text=white},
+ snob style={fill=yellow, text=red},
+ snobs={15_A,24_B,42_C,51_D},
+ ]{123*4,567,89*{10},*{11}}
+ \end{example}
+
+ The difference between this pictures and the one given above using
+ \option{ribbons} is that in the \option{snobs} are drawn over the top
+ of the tableau border, causing the border to disappear for these
+ nodes. For this reason, in most cases you should normally avoid
+ \option{snobs} and use \option{ribbons}. This said, \option{snobs} are
+ exactly what are needed in \autoref{Ex:Garnir}.
+
+ The \option{snob box} and \option{snob box style} keys work in the
+ same way as the \option{path box} and \option{ribbon box}, and
+ \option{path box style} and \option{ribbon box style}, keys.
+
+ \option[1]{scale=number}[a decimal number]
+ \option*[1]{xscale=number}[a decimal number]
+ \option*[1]{yscale=number}[a decimal number]
+
+ By design, boxes in tableaux do not automatically resize to fit
+ their contents. For example, consider:
+
+ \begin{example}
+ \Tableau{ 13{10}{11}{1+x}, 2{1+x} }
+ \end{example}
+
+ This is unlikely to be the desired output! The options \option{scale},
+ \option{xscale} and \option{yscale} can be used to rescale the boxes
+ in tableaux and diagrams. The names are slightly misleading because
+ \option{xscale} rescales in the direction of increasing column index
+ and \option{yscale} rescales in the direction of increasing row index.
+
+ \begin{example}
+ \Tableau[scale=2]{ 13{10}{11}{1+x}, 2{1+x} }
+ \end{example}
+
+ \begin{example}
+ \Tableau[xscale=2]{ 13{10}{11}{1+x}, 2{1+x} }
+ \end{example}
+
+ When using the \textsf{australian} and \textsf{ukrainian} conventions,
+ \option{xscale} and \option{yscale} scale in both the \textsf{x}
+ direction and the \textsf{y}-direction, reflecting how these tableaux
+ grow with increasing column and row index, respectively.
+
+ \begin{example}
+ \Tableau[ukrainian, xscale=2]{ 13{10}{11}{1+x}, 2{1+x} }
+ \end{example}
+
+ \begin{example}
+ \Tableau[australian, yscale=2]{ 13{10}{11}{1+x},2{1+x} }
+ \end{example}
+
+ \begin{warning}
+ The options, \option{scale}, \option{xscale}, and \option{yscale},
+ affect all \aTableau diagrams, including tableaux, Young diagrams
+ and abacuses. If you want to use \keyword{\aTabset} to change the
+ default sizes of the diagrams and tableaux in your document, then it
+ is probably better to use the \option{box height} and \option{box
+ width} options.
+ \end{warning}
+
+ \option[false]{shifted}[true/false]
+
+ Set to \textsf{true} for a shifted tableau or shifted diagram. Shifted
+ tableaux, and shifted diagrams, are discussed in more detail in
+ \autoref{S:Shifted}, which describes the \keyword{\ShiftedDiagram} and
+ \keyword{\ShiftedTableau} commands.
+
+ \begin{example}
+ \Tableau[shifted]{123,45} \qquad
+ \Diagram[shifted]{3,2^2}
+ \end{example}
+
+ See \autoref{S:Shifted} for the options specific to shifted tableaux and
+ shifted diagrams.
+
+ \option[(0)]{skew=partition}[a partition]
+
+ Specify the skew shape for a skew tableau or skew diagram. Skew
+ tableaux, and skew diagrams, are discussed in more detail in
+ \autoref{S:Skew}, which describes the \keyword{\SkewDiagram} and
+ \keyword{\SkewTableau} commands.
+
+ \begin{example}
+ \Tableau[skew={2}]{123,45} \qquad
+ \Diagram[skew={2^2,1}]{3,2^2}
+ \end{example}
+
+ See \autoref{S:Skew} for the options specific to skew tableaux and skew diagrams.
+
+ \option[fill=\aTableauColour{StarStyle}]{star style=style}[\TikZ-styling]
+
+ Use the \option{star style} to add to the style of the starred entries
+ of a tableau. (In \TikZ parlance, \option{star style} \emph{appends}
+ appends these styles to the default \option{star style}.)
+
+ \begin{example}
+ \Tableau[star style={text=magenta, draw=cyan, thick}]
+ {1*2*3,4*5} \qquad
+ \Tableau[star style={fill=orange!50}]{1*2*3,4*5}
+ \end{example}
+
+ Note that the tableau border is drawn \textit{after} the
+ \option{star style} is applied. You can use \option{snobs} to draw
+ over the top of the border.
+
+ \option[]{styles=\TikZ styles}[List of styles]
+
+ The \option{styles} key is a shorthand for defining \TikZ-styles that
+ are only used in the current picture. For example, instead of writing
+
+ \begin{example}
+ \tikzset{
+ B/.style={fill=blue!40, text=yellow},
+ G/.style={fill=green!80!blue,circle,minimum size=5mm},
+ R/.style={fill=red,text=white, font=\tiny},
+ Y/.style={fill=yellow!20, text=blue}
+ }
+ \Tableau[french]{[R]1[B]2,[G]3,[Y]4}
+ \end{example}
+
+ you can save some typing using the \option{styles} key:
+
+ \begin{example}
+ \Tableau[french, styles={
+ B={fill=blue!40, text=yellow},
+ G={fill=green!80!blue,circle,minimum size=5mm},
+ R={fill=red,text=white, font=\tiny},
+ Y={fill=yellow!20, text=blue},
+ }]{[R]1[B]2,[G]3,[Y]4}
+ \end{example}
+
+ Styles defined this way will only be available in the current picture.
+ Use \keyword{\tikzset} whenever you are defining styles that are likely
+ to be used more than once.
+
+ \option[false]{tabloid}[true/false]
+
+ Use the \option{tabloid} key to draw a tabloid. This key is discussed in
+ more detail in \autoref{S:Tabloid}, which describes the
+ \keyword{\Tabloid} command.
+
+ \begin{example}
+ \Tableau[tabloid]{123,45} \qquad
+ \Diagram[tabloid]{3,2^2}
+ \end{example}
+
+ See \autoref{S:Tabloid} for the options specific to tabloids.
+
+ \option[]{tikz before=commands}[\TikZ commands]
+ \option*[]{tikz after=commands}[\TikZ commands]
+
+ These keys inject \TikZ code into the underlying \keyword{tikzpicture}
+ environment, where the tableau is constructed, before and after the
+ \keyword{\Tableau} command, respectively.
+
+ \begin{example}[lefthand width=0.24\textwidth]
+ \Tableau[
+ tikz before={\draw[help lines, step=0.5](-0.5,-2)grid(2,0.5);},
+ tikz after={\draw[ultra thick, red]
+ (A-1-3.north east)--(A-1-3.south east)
+ --(A-2-1.north east)--(A-3-1.south east)
+ --(A-3-1.south west);
+ }]{134,567,89}
+ \end{example}
+
+ Both before and after hooks are provided because the order in which
+ you place \TikZ commands affects the final picture because later commands
+ are drawn over the top of earlier ones. Note that the \emph{before}
+ code cannot use the named nodes \textsf{A-r-c} because this code is
+ executed before these nodes are constructed, which happens when the
+ tableau is drawn. For more examples, see \autoref{SS:order}.
+
+ \option[]{tikzpicture=keys}[\TikZ-keys]
+
+ This command adds an optional argument to the underlying
+ \keyword{tikzpicture} environment, which contains the tableau. The
+ \option{tikzpicture} option is ignored when the \keyword{\Tableau}
+ command is equipped with $(x,y)$-coordinates.
+
+ As a first example, we use \keyword{tikzpicture={rotate=30}}
+ to rotate a tableau by 90 degrees:
+
+ \begin{example}
+ \Tableau[tikzpicture={rotate=90}]{123,45} \qquad
+ \begin{tikzpicture}[rotate=90]
+ \Tableau(0,0){123,45}
+ \end{tikzpicture}
+ \end{example}
+
+ The two tableaux constructions in this example are equivalent. An
+ oddity with both of these examples is that the numbers in the tableaux
+ have not been rotated, which is because the \TikZ \emph{rotate} key
+ does not affect component objects, such as nodes, inside a \TikZ
+ picture. You can rotate the entire picture using the
+ \TikZ-key \textit{transform canvas}
+
+ \vspace*{15mm}
+
+ \begin{example}[valign=top, lefthand width=0.3\textwidth]
+ \Tableau[tikzpicture={transform canvas={rotate=90}}]{123,45}
+ \end{example}
+
+ A more interesting example is that by using
+ \option{tikzpicture=remember picture} we can add annotations to
+ a tableau. For example, consider:
+
+ \begin{example}[lefthand width=0.3\textwidth, label={Ex:pointing}]
+ \Tableau[ukrainian, name=A,
+ tikzpicture={remember picture}]
+ { 1[fill=blue!20]23[text=red]45,
+ 6*78[{draw=cyan,ultra thick}]9,
+ [{circle,fill=orange}]{10}*{11}{12},
+ [{dashed,draw=red,ultra thick}]{13}
+ }
+ \end{example}
+
+ Since \option{name}=A, the nodes in this tableau are referenced as
+ \textsf{(A-1-1)}, \textsf{(A-1-2)}, \textsf{(A-1-3)}, \dots. As the
+ example uses \textit{remember picture}, other \keyword{tikzpicture}
+ environments can reference the node names in last tableau, which
+ allows us to do things like this:
+
+ \vspace*{3mm}
+
+ \begin{example}[lefthand width=0.3\textwidth]
+ \tikz[remember picture, overlay]
+ \draw[very thick, ->, red]
+ (0,0) node[right,align=left]
+ {This circle is too big!\\Use minimum size=5mm}
+ to [out=135, in=225](A-3-1);
+ \end{example}
+
+ % --------------------------------------------------------------
+ \subsubsection{Compositions}
+ \index{composition}
+
+ As we have defined them, tableaux are always of \textit{partition}
+ shape, in the sense that the lengths of the rows is a weakly
+ decreasing sequence. In fact, the \keyword{\Tableau} command also
+ accepts tableaux of \emph{composition} shape, where the lengths of the
+ rows are not necessarily in decreasing order:
+
+ \begin{example}
+ \Tableau{ 45,2751,31 } \qquad
+ \SkewTableau{1,2}{ 45,27,31 }
+ \end{example}
+
+ Even though it is possible to draw compositions, and tableaux of
+ composition shape, compositions are not supported in the sense that
+ many of the options/keys assume that the diagrams are of partition
+ shape. In addition, some options assume that tableaux and diagrams do
+ not contain empty rows, and that the diagrams are \textit{connected}.
+ (For disconnected tableaux and diagrams, see the
+ \keyword{\Multidiagram} and \keyword{\Multitableau} commands in
+ \autoref{S:Multitableau}.)
+
+ % --------------------------------------------------------------
+ \subsubsection{Drawing order}
+ \label{SS:order}
+ \index{tableau!drawing order}
+
+ When \TikZ constructs a picture, later objects are drawn over the top
+ of earlier ones, which can obscure earlier features. Consequently,
+ for more complicated diagrams and tableaux it helps to know the order
+ in which the different parts of these diagrams are drawn, which is the
+ following:
+ \begin{itemize}[nosep]
+ \item First, the tableau entries that use the default styling are
+ placed, in the order that they appear in the \textit{tableau
+ specifications}.
+ \item Secondly, the styled tableau entries are placed, in the order
+ that they appear in the \textit{tableau specifications}.
+ \item Next, the nodes in any \option{ribbons} and ribbon
+ \option{paths} are placed, again in the order that the ribbons are
+ listed. For each ribbon, first the border of the ribbon is drawn,
+ together with any styling for the ribbon, and then the boxes in the
+ ribbon, together with any styling, are added.
+ \item When enabled by \option{skew border}, the skew border is
+ drawn, after which the border of the tableau is drawn.
+ \item The \option{dotted rows} and \option{dotted cols} keys are
+ applied to replace the specified rows and columns with dots.
+ \item Finally, any \option{snobs} are drawn, in the order that they are listed.
+ \end{itemize}
+
+ All of the tableau and Young diagram commands use this drawing order.
+
+ % --------------------------------------------------------------
+ \subsubsection{Special characters}
+ \index{tableau!special characters}
+ \index{tableau!comma}
+ \index{tableau!*}
+ \index{tableau![}
+
+ The characters \textsf{[]}, \textsf{,}, and \textsf{*} have
+ special meanings in the \textit{tableau specifications}. Enclose these characters in
+ braces when you want to use these characters as entries in a tableau:
+
+ \begin{example}
+ \Tableau{ 13{,}5], 8{[}, {*} }
+ \end{example}
+
+ There is no need to enclose~\keyword{]} in braces because it only
+ becomes special when it is preceded by~\keyword{[}.
+
+ % --------------------------------------------------------------
+ \subsection{Young diagrams}
+ \label{S:Diagram}
+ \indexcmd{Diagram}
+ \index{young diagram@Young diagram|see{diagram}}
+ \index{diagram}
+ \index{diagram}
+ \index{partition!diagram}
+
+ A \emph{Young diagram}, or simply a \emph{diagram}, is an unlabelled
+ tableau. Diagrams can be drawn using the \keyword{\Tableau} command:
+
+ \begin{example}
+ \Tableau{~~~,~~~,~~,~}
+ \end{example}
+
+ This approach works, but it is cumbersome, hard to proofread, and easy to miscount.
+ For this reason, \aTableau provides the \keyword{\Diagram} command. The
+ \keyword{\Diagram} command uses almost the same syntax as the
+ \keyword{\Tableau} command:
+
+ \keyword{\Diagram (x,y) [options] {partition}}
+
+ As with the \keyword{\Tableau} command, the $(x,y)$-coordinates are
+ needed if, and only if, the diagram is inside a \keyword{tikzpicture}
+ environment. The \keyword{\Diagram} command allows the
+ \emph{partition} to be specified as either a comma-separated list of
+ \emph{weakly decreasing positive integers}, or by using \emph{exponential
+ notation}:
+ \index{exponential notation}
+ \index{partition!exponential notation}
+ \index{diagram!exponential notation}
+
+ \begin{example}
+ \Diagram{4,3^2,1^3} \qquad
+ \Diagram{4,3,3,1}
+ \end{example}
+
+ Internally, \keyword{\Diagram} actually does something like the first
+ example in this section, so all of the options for the
+ \keyword{\Tableau} command can be used with \keyword{\Diagram}. Rather
+ than repeating all of the \keyword{\Tableau} options in this section,
+ we highlight the more interesting options together with some new,
+ diagram specific, options.
+
+ \begin{samepage}
+ Just like the \keyword{\Tableau} command, \keyword{\Diagram} supports the
+ four different conventions for diagrams, with \option{english} being
+ the default:
+
+ \option[-]{english}
+ \option*[]{french}
+ \option*[]{ukrainian}
+ \option*[]{australian}
+ \end{samepage}
+
+ \begin{example}
+ \Diagram[australian]{3,2,1} \qquad
+ \Diagram[australian]{3,1^3}
+ \end{example}
+
+ \begin{example}
+ % English is the default convention
+ \Diagram[english]{3,2,1} \qquad
+ \Diagram{3,1^3}
+ \end{example}
+
+ \begin{example}
+ \Diagram[french]{3,2,1} \qquad
+ \Diagram[french]{3,1^3}
+ \end{example}
+
+ \begin{example}
+ \Diagram[ukrainian]{3,2,1} \qquad
+ \Diagram[ukrainian]{3,1^3}
+ \end{example}
+
+ \option[true]{border}[true/false]
+ \option*[false]{no border}[false/true]
+
+ If \option{border} is true, which it is by default, then the border of
+ the tableau is drawn. If \option{border} is false, then the border of
+ the tableau is not drawn. Notice that the border refers only to the
+ outside border of the diagram, and not to the internal borders of the
+ boxes on the diagram, which can be disabled using
+ \option{no boxes}.
+
+ \begin{example}
+ \Diagram[border=false]{3,2,1} \qquad
+ \Diagram[no border, french]{3^2,1}
+ \end{example}
+
+ The \option{no border} option, and similar options, are provided only
+ for completeness because it is the inverse of \option{border}. That
+ is, \option{no border} is equivalent to \option{border=false}, and
+ \option{no border=false} is equivalent to \option{border=true}.
+
+ \option[true]{boxes}[true/false]
+ \option*[false]{no boxes}[false/true]
+
+ The \option{boxes} and \option{no boxes} keys control whether or not
+ the internal wall around the boxes are drawn, with these two keys
+ being inverses of each other. By default, \option{boxes} is true, so
+ the internal boxes are drawn. When \option{no boxes} is in force
+ (equivalently, \option{boxes} is false), the internal walls around
+ boxes are not drawn.
+
+ \begin{example}
+ \Diagram[no boxes]{3,2,1} \qquad
+ \Tableau[french, no boxes, no border]{123,45}
+ \end{example}
+
+ \option[false]{conjugate}[false/true]
+
+ Draws the conjugate diagram, which has the rows and columns
+ interchanged.
+
+ \begin{example}
+ \Diagram[conjugate]{3,2,2} \qquad
+ \Diagram[ukrainian, conjugate]{2,1^3}
+ \end{example}
+
+ \option[]{dotted cols=column indices}[comma separated list of columns]
+ \option*[]{dotted rows=row indices}[comma separated list of rows]
+
+ The \option{dotted rows} and \option{dotted cols} keys draw diagrams
+ where the specified rows and columns are replaced with dots. This
+ makes it possible to draw \emph{generic} diagrams, where the number of
+ rows and columns is not fully specified.
+
+ \begin{example}
+ \aTabset{scale=0.7}
+ \Diagram[dotted rows={2,4,5}]{4^2,2^2,1^3} \qquad
+ \Diagram[dotted cols={5,3,4},
+ no boxes] {6,5,4,3,2,1}
+ \end{example}
+
+ As shown, if row and columns indices are in increasing
+ \textit{consecutive} order, then the corresponding rows or columns are
+ replaced as a block. Non-consecutive indices are treated separately.
+
+ \begin{example}
+ \aTabset{scale=0.7, no boxes}
+ \Diagram[dotted rows={4,5,3}] {6,5,5,5,2,1} \qquad
+ \Diagram[dotted cols={5,3,4}] {6,5,5,5,2,1}
+ \end{example}
+
+ \index{tableau!dotted rows}
+ \index{tableau!dotted cols}
+ The \option{dotted rows} and \option{dotted cols} keys work by
+ overwriting the content on the specified rows and columns, so
+ anything that was drawn in these rows and columns will disappear. The
+ \option{dotted rows} and \option{dotted cols} keys can be used with
+ the \keyword{\Tableau} command, with the caveat that this will remove
+ all boxes, with their contents, in the specified rows and columns.
+
+ When the \option{dotted rows} and \option{dotted cols} keys are
+ used together, the \option{dotted rows} are applied first.
+
+ \begin{example}
+ \Diagram[scale=0.7, no boxes,
+ dotted rows={4,5},
+ dotted cols={4,5},
+ ] {6,5,5,5,2,1}
+ \end{example}
+
+ When using these two keys together, you need to be careful when
+ choosing which rows and columns to remove because, otherwise,
+ artefacts can remain. Ideally, the endpoints of the rows and columns
+ being removed should not overlap. For example, consider the two
+ pictures:
+
+ \begin{example}
+ \aTabset{scale=0.7, no boxes}
+ \Diagram[dotted cols={3}]{6,5,5,5,2,1}\qquad
+ \Diagram[dotted cols={4,5,3}, dotted rows={4,5,3},
+ tikz after={ \draw[red](0.9,-1.4)circle(0.2); }
+ ]{6,5,5,5,2,1}
+ \end{example}
+
+ The circled horizontal dots in the right-hand diagram are a ``user
+ error'', not a bug. The left-hand diagram shows that these dots come
+ from column $3$ with \option{dotted cols} \emph{after} first removing
+ rows 4--5 with \option{dotted rows}.
+
+ The \option{dotted rows} and \option{dotted cols} keys are not
+ designed to be used with the \option{conjugate} key.
+
+ \option[]{ribbons=ribbon specifications}[list of ribbon specifications]
+ \option*[]{paths=path specifications}[list of ribbon specifications]
+ \option*[]{snobs=snobs specifications}[list of ribbon specifications]
+
+ Use \option{ribbons}, \option{paths} and \option{snobs} to add
+ ribbons, ribbon paths and snobs to a diagram, respectively. The
+ \option{snobs} are drawn after the border of the diagram.
+
+ \begin{example}
+ \Diagram[french, ribbons={*22*c_4*r*r}]{3,2^2,1} \qquad
+ \end{example}
+
+ As described in \autoref{S:Tabloid}, there are additional keys that
+ control the behaviour of paths, ribbons and snob. For example, the
+ keys \option{path style}, \option{path box} and \option{path box
+ style} are associated to \option{paths}.
+
+ \begin{example}
+ \Diagram[ukrainian, inner style=dotted,
+ styles={b={fill=blue!20,opacity=0.4},
+ R={red,text=red,thick},
+ B={blue,text=blue,thick},
+ }, path style={thick},
+ path box=\bullet,
+ paths={(R)15rccrc[b]rc,(B)43[b]rcc}
+ ]{5^2,3^3}
+ \end{example}
+
+ A description of the ribbon specifications, with examples, can be
+ found in \autoref{S:RibbonTableaux}, which describes the
+ \keyword{\RibbonTableau} command.
+
+ % --------------------------------------------------------------
+ \subsubsection{Diagrams with entries}\label{SS:entries}
+ \index{contents}
+ \index{first tableau}
+ \index{hooks}
+ \index{last tableau}
+ \index{residues}
+ \index{first tableau}
+ \index{tableau!contents}
+ \index{tableau!first}
+ \index{tableau!hooks}
+ \index{tableau!last}
+ \index{tableau!residues}
+
+ The \option{entries} key provides a shortcut for drawing some common
+ tableaux of a specified shape.
+
+ \option[]{entries=value}[contents, first, hooks, last, residues]
+
+ The possible choices are:
+
+ \begin{itemize}
+
+ \item\option{entries=first} print the \emph{first}
+ \textbf{standard} tableau of this shape, with respect to the Bruhat
+ order. This is the tableau that has the numbers $1,2\dots,n$ entered
+ in order from top left to right along down successive rows (with
+ appropriate modifications for the non-English conventions).
+
+ \index{first tableau}
+ \index{tableau!first}
+ \index{entries!first}
+ \begin{example}
+ \Diagram[entries=first]{3,2,2} \qquad
+ \Diagram[ukrainian, entries=first]{3^2,2}
+ \end{example}
+
+ \item\option{entries=last} print the \emph{last} \textbf{standard}
+ tableau of this shape, with respect to the Bruhat order. This is the
+ tableau that has the numbers $1,2\dots,n$ entered in order from top
+ to bottom down successive columns (with appropriate modifications
+ for the non-English conventions).
+
+ \index{last tableau}
+ \index{tableau!last}
+ \index{entries!last}
+ \begin{example}
+ \Diagram[entries=last]{3,2,2} \qquad
+ \Diagram[australian, entries=last]{2^2,1}
+ \end{example}
+
+ \item\option{entries=hooks} print the diagram where each box is
+ labelled by the corresponding \emph{hook length}. If $\lambda$ is a
+ partition and $\lambda'$ is its conjugate partition then the hook
+ length of the box in row~$i$ and column~$j$ is
+ $\lambda_i-i+\lambda'_j-j+1$.
+
+ \index{tableau!hook lengths}
+ \index{hook lengths}
+ \index{entries!hook lengths}
+ \begin{example}
+ \Diagram[entries=hooks]{3,2,2} \qquad
+ \Diagram[ukrainian, entries=hooks]{2^2,1}
+ \end{example}
+
+ \item\option{entries=contents} print the diagram where each box is
+ labelled by its \emph{content}, which is the row index minus the
+ column index.
+
+ \index{tableau!contents}
+ \index{contents}
+ \index{entries!contents}
+ \begin{example}
+ \Diagram[entries=contents]{3,2,1} \qquad
+ \Diagram[french, entries=contents]{2^2,1}
+ \end{example}
+ \AddKeyLink{contents}
+ \AddKeyLink{residues}
+ \AddKeyLink{charge}
+
+ \smallskip\noindent Inside a tableau, the default minus sign for a
+ negative number looks too long, so \aTableau uses
+ \keyword{\shortminus} for negative contents. For example, it prints
+ \keyword{\shortminus 1} instead of \keyword{-1}, which look like
+ $\shortminus1$ and $-1$, respectively.\indexcmd{shortminus}
+
+ \item\option{entries=residues} prints the diagram where each box is
+ labelled by its \emph{residue}, which is the row index minus the
+ column index modulo an integer~$e\ge2$, which must also be supplied.
+
+ \index{residue}
+ \index{tableau!residues}
+ \index{affine quiver}
+ \begin{example}
+ \Diagram[entries=residues, e=2]{3,2,1} \qquad
+ \Diagram[french, entries=residues, e=3]{3,2,1}
+ \end{example}
+
+ \noindent\AddKeyLink{cartan}\AddKeyLink{e}
+ By default, residue sequences for affine type $A^{(1)}_e$, or the symmetric
+ group and friends, are given. In addition, residues in affine types
+ $C^{(1)}_e$, $A^{(2)}_{2e}$ and $D^{(2)}_e$, which can be accessed
+ using \option{cartan=C}, \option{cartan=AA}, and \option{cartan=DD},
+ respectively.
+
+ \smallskip
+ \begin{example}
+ % affine type C
+ \Diagram[french, entries=residues,
+ e=2, cartan=C] {8,4,2}
+ \end{example}
+
+ \begin{example}
+ % twisted affine type A
+ \Diagram[ukrainian, entries=residues,
+ e=2, cartan=AA] {8,4,2}
+ \end{example}
+
+ \begin{example}
+ % twisted affine type D
+ \Diagram[australian, entries=residues,
+ e=2, cartan=DD] {8,4,2}
+ \end{example}
+
+ \end{itemize}
+ Use the \option{charge} key to add offsets to the \option{contents} and \option{residues}.
+
+ \begin{example}
+ \Diagram[entries=contents, charge=2]{3,2,1} \qquad
+ \Diagram[entries=residues, e=3, charge=1]{3,2,1}
+ \end{example}
+
+ % --------------------------------------------------------------
+ \subsection{Skew tableaux and skew diagrams}
+ \label{S:Skew}
+ \indexcmd{SkewTableau}
+ \indexcmd{SkewDiagram}
+ \index{diagram!skew}
+ \index{partition!skew}
+ \index{tableau!skew}
+
+ A partition $\mu$ is \emph{contained} in another partition $\lambda$, which
+ is written as~$\mu\subseteq\lambda$, if $\mu_k\le\lambda_k$, for
+ $k\ge0$. If $\mu\subseteq\lambda$ then the \emph{skew partition}
+ $\lambda/\mu=\set{(r,c)\in\lambda|(r,c)\notin\mu}$ is the set of nodes
+ that are in~$\lambda$ and not in~$\mu$. In this manual, $\mu$ is
+ the \emph{inner shape} and $\lambda/\mu$ is the outer shape. A
+ \emph{skew tableau} is a labelling of the nodes in the diagram of a
+ skew partition. Skew partitions and skew tableau can be drawn using
+ the commands:
+
+ \keyword{\SkewDiagram (x,y) [options] {inner shape} {outer shape}}\newline
+ \keyword{\SkewTableau (x,y) [options] {inner shape} {skew tableau specifications}}
+
+ \index{exponential notation}
+ As with the previous commands, the $(x,y)$--coordinates should be given
+ if, and only if, the picture is inside a \keyword{tikzpicture}
+ environment. The inner and outer shapes can either be given as a
+ comma-separated list of non-negative integers, or in exponential notation.
+
+ Skew tableau and skew diagrams should always be connected. Use
+ \keyword{\Multidiagram} and \keyword{\Multitableau} to draw
+ disconnected diagrams.
+
+ In fact, the \keyword{\SkewTableau} is just an alias for the
+ \keyword{\Tableau}, using the \option{skew} key to set the inner
+ shape. For this reason, all of the options for the \keyword{\Tableau}
+ command can be used with \keyword{\SkewTableau}. The entries in a
+ \keyword{\SkewTableau} are specified in exactly the same way as in the
+ \keyword{\Tableau} command. In particular, the entries of skew
+ tableaux can, optionally, be given style prefixes, both using a~$*$ to
+ add the current \option{star style}, or arbitrary \TikZ-styling using
+ \keyword{[...]}.
+
+ \begin{example}
+ \tikzset{R/.style={fill=red!20,text=red}}
+ \SkewTableau[french]{1^2}{13,5*7,[R]79} \qquad
+ \Tableau[french, skew={1^2}]{13,5*7,[R]79}
+ \end{example}
+
+ Similarly, the \keyword{\SkewDiagram} command is an alias for the
+ \keyword{\Diagram} command, with a \option{skew} key.
+
+ \begin{example}
+ \SkewDiagram[french]{1^2}{2^3} \qquad
+ \Diagram[french, skew={1^2}]{2^3}
+ \end{example}
+
+ As the \keyword{\SkewTableau} and \keyword{\SkewTableaua} commands
+ are shortcuts, all of the options for the \keyword{\Tableau} and
+ \keyword{\Diagram} commands can be used with the
+ \keyword{\SkewTableau} and \keyword{\SkewDiagram} commands,
+ respectively. In addition, the following options are supported:
+
+ \option[false]{skew border}[true/false]
+ \option*[true]{no skew border}[false/true]
+
+ These two keys are inverse to each other. When
+ \option{skew border} is \textsf{true}, the border of the (inner) skew
+ shape is drawn.
+
+ \begin{example}
+ \tikzset{R/.style={fill=red!20,circle}}
+ \SkewTableau[skew border]{2,1^2}{12[R]3,45,67}
+ \SkewTableau[french, skew border]{2,1^2}{12[R]3,45,67}
+ \end{example}
+
+ Note that \option{skew border} only draws the border of the skew shape
+ and not the boxes inside the inner skew shape. Use \option{skew boxes}
+ to draw the interior walls of the boxes in the skew shape.
+
+ \option[draw=\aTableauColour{Skew}, fill=\aTableauColour{SkewFill}, thick]{skew border style=style}[\TikZ-styling]
+
+ Use \option{skew border style} to change the style of the skew border.
+ Since the skew border is only drawn when \option{skew border} is set,
+ the \option{skew border style} does not have any effect unless
+ \option{skew border} has been set to \textsf{true}.
+
+ \begin{example}
+ \SkewTableau[skew border style={draw=yellow},
+ skew border]{2,1^2}{123,45,67} \qquad
+ \SkewDiagram[skew border style={dashed,fill=red!10},
+ skew border]{1^2}{2^3}
+ \end{example}
+
+ \option[false]{skew boxes}[false/true]
+ \option*[true]{no skew boxes}[true/false]
+ \option*[thin, fill=\aTableauColour{SkewFill}]{skew box style=style}[\TikZ-styling]
+
+ The \option{skew boxes} key adds walls to the boxes inside the inner
+ partition of a skew shape. Use \option{skew box style} to change the
+ default shading of these boxes.
+
+ \begin{example}
+ \SkewTableau[skew boxes] {2,1^2}{123,45,67}
+ \SkewTableau[skew boxes,
+ skew box style={dash pattern=on 1pt off 2pt}
+ ] {2,1^2}{123,45,67,89}
+ \end{example}
+
+ Using the options \option{skew border} and the \option{skew boxes}
+ together gives the skew (inner) shape both inner and outer borders.
+
+ \begin{example}
+ \SkewTableau[skew border, skew boxes] {2^2,1}{123,45,67}
+ \end{example}
+
+ % --------------------------------------------------------------
+ \subsection{Shifted tableaux and shifted diagrams}
+ \label{S:Shifted}
+ \indexcmd{ShiftedTableau}
+ \indexcmd{ShiftedDiagram}
+ \index{diagram!shifted}
+ \index{strict partition}
+ \index{partition!strict}
+ \index{shifted tableau}
+ \index{tableau!shifted }
+
+ \emph{Strict partitions}, which have strictly increasing parts, and
+ \emph{shifted tableaux}, which are of strict partition shape, appear
+ in several places in representation theory, such as in the study of
+ projective representations of the symmetric groups. These tableaux and
+ diagrams are drawn with row~$r$ shifted by $(r-1)$-units along the
+ row, so that the first box in each row has content~$0$. These diagrams
+ and tableaux can be drawn using the following commands:
+
+ \keyword{\ShiftedDiagram (x,y) [options] {partition }}\newline
+ \keyword{\ShiftedTableau (x,y) [options] {tableau specification}}
+
+ As usual, the $(x,y)$-coordinates are necessary if, and only if, these
+ commands are used inside a \keyword{tikzpicture} environment. The
+ partition in a~\keyword{\ShiftedDiagram} can be given using
+ exponential notation and the tableau specification for a
+ \keyword{\ShiftedTableau} can include the usual optional style
+ prefixes.
+
+ \begin{example}
+ \tikzset{R/.style={fill=red!20,circle}}
+ \ShiftedTableau{12[R]3,45,*6} \qquad
+ \ShiftedDiagram[french]{3,2,1}
+ \end{example}
+
+ In the literature, shifted tableaux and shifted diagrams almost
+ always have strict partition shape, however, this is not enforced by
+ these commands. Under the hood, the \keyword{\ShiftedTableau} is the
+ \keyword{\Tableau} command with the \option{shifted} option set
+ to true. Similarly, \keyword{\ShiftedDiagram} is the same as using
+ the \keyword{\Diagram} command with the \option{shifted} option. Consequently,
+ all of the options for the \keyword{\Tableau} and \keyword{\Diagram}
+ commands can be used with \keyword{\ShiftedTableau} and
+ \keyword{\ShiftedDiagram}, respectively. In particular, options like
+ \option{skew boxes} can be used to highlight the shifted part of the
+ diagram
+
+ \begin{example}
+ \ShiftedTableau[skew boxes]{1*23,4*5} \quad
+ \ShiftedDiagram[skew border]{3,2}
+ \end{example}
+
+ The \option{entries} key works as expected for shifted diagrams:
+
+ \begin{Example}
+ \ShiftedDiagram[entries=contents]{3,2,1} \qquad
+ \ShiftedDiagram[entries=first]{4,2,1} \qquad
+ \ShiftedDiagram[entries=hooks]{4,2,1} \qquad
+ \ShiftedDiagram[entries=last]{4,2,1} \qquad
+ \ShiftedDiagram[entries=residues, e=3]{4,2,1}
+ \end{Example}
+
+ The definition of hook lengths for shifted diagrams can be found, for
+ example, in \cite{Konvalinka:ShiftedHookLengths}.
+
+ % --------------------------------------------------------------
+ \subsection{Tabloids}
+ \label{S:Tabloid}
+ \indexcmd{Tabloid}
+
+ A \emph{tabloid} is an equivalence class of tableau, where two tableaux
+ are equivalent if they have the same entries in each row, up to a
+ permutation. In the literature, tabloids are usually drawn with lines
+ above and below each row, and without side borders. Tabloids can be
+ drawn with the \keyword{\Tabloid} command.
+
+ \keyword{\Tabloid (x,y) [options] {partition }}
+
+ The \keyword{\Tabloid} command functions in the same way as the
+ \keyword{\Tableau} command, except that it draws tabloids. In fact,
+ the \keyword{\Tabloid} is a special case of the \keyword{\Tableau}
+ command with the \option{tabloid} option set.
+
+ \begin{example}
+ \tikzset{R/.style={fill=red!20,circle,minimum size=5mm}}
+ \Tabloid[ukrainian]{12[R]3,45}\quad
+ \Tabloid[english] {12[R]3,45}\quad
+ \Tabloid[french] {12[R]3,45}
+ \end{example}
+
+ The \aTableau package does not provide a dedicated command for tabloid
+ diagrams, however, they can be drawn using the \keyword{\Diagram}
+ command together with the \option{tabloid} option:
+
+ \begin{example}
+ \Diagram[tabloid]{3^2,1} \qquad
+ \Diagram[tabloid, french]{3,1^2}
+ \end{example}
+
+ Some authors work with \emph{column tabloids}. Such tableaux do not
+ have a dedicated \aTableau command, however, they can be drawn using the
+ \option{conjugate} option: \index{tabloids!column}
+
+ \begin{example}
+ \Tabloid[conjugate]{123,4} \qquad
+ \Diagram[conjugate, tabloid]{3,1} \qquad
+ \end{example}
+
+ Similarly, skew tabloids and shifted tabloids can be drawn using the \option{skew}
+ option.
+ \label{tabloids!skew}
+
+ \begin{example}
+ \Tabloid[skew={2,1}]{19{11},29{10},6} \qquad
+ \Tabloid[conjugate, skew={0,1,2}]{19{11}7,29{10},6}
+ \end{example}
+
+
+ % --------------------------------------------------------------
+ \subsection{Ribbon tableaux}\label{S:RibbonTableaux}
+ \indexcmd{RibbonTableau}
+ \index{ribbon!head}
+ \index{tableau!ribbon tableau}
+
+ A \emph{ribbon} in a tableau, or a diagram, is a connected strip of
+ boxes~$R$ that are totally ordered by their contents. (Recall from
+ \autoref{SS:entries} that the content of the box in row~$a$ and
+ column~$b$ is $b-a$.) Therefore, a ribbon does not contain a
+ \Diagram[scale=0.3, border=false, align=bottom]{2^2}-square, and if
+ $(a,b)\in R$ then at most one of $(a+1,b)$ and $(a,b-1)$ belongs
+ to~$R$. The \emph{head} of a ribbon~$R$ is the unique node of maximal
+ content. A \emph{ribbon tableau} is a tableau that is tiled by
+ ribbons. A box is a ribbon of length~$1$, so every tableau is a ribbon
+ tableau.
+
+ \keyword{\RibbonTableau (x,y) [options] {ribbon specifications}}
+
+ Like the other commands, the $(x,y)$-coordinates are optional and are
+ required if, and only if, the diagram is being used as part of a
+ \keyword{tikzpicture} environment. All options for the
+ \keyword{\Tableau} command can be used for the ribbon command, so we
+ refer to \autoref{S:Tableau} for a description of the available
+ options.
+
+ % --------------------------------------------------------------
+ \subsubsection{Ribbon specifications}
+ Unlike the \keyword{\Tableau} command, the entries of a ribbon tableau
+ are given by ribbon specifications (rather than tableau)
+ specifications. Ribbon specifications are also used by the three keys
+ \option{ribbons}, \option{paths}, and \option{snobs}, which were
+ introduced in \autoref{SS:TableauOptions}.
+
+ To understand the ribbon specifications, observe that if $(a,b)$ is
+ the head of a ribbon, then we can walk along the ribbon by specifying
+ whether the \textsf{r}ow index increases or the \textsf{c}olumn index
+ decreases. That is, a ribbon is uniquely determined by specifying its
+ head $(a,b)$ together with a sequence of $\textsf{r}$'s and
+ \textsf{c}'s to indicate when the row index increases, or the column
+ index decreases, respectively. For example, vertical and horizontal
+ ribbons are given by a sequences of \textsf{r}'s and \textsf{c}'s,
+ respectively:
+
+ \begin{example}
+ \aTabset{align=top, no border}
+ \RibbonTableau{11rrrr} \qquad
+ \RibbonTableau{16ccccc}
+ \end{example}
+
+ The border of a ribbon tableau is the smallest (skew) partition that
+ contains all of its ribbons. In the last example shows, the
+ \option{no border} key is used to disable the ribbon tableau border so
+ that we can better see the ribbon, which is the full diagram in these
+ two cases.
+
+ The following diagram shows a see-sawing ribbon with head in row~$1$
+ and column~10, and tail in row~$5$ and column~$1$.
+
+ \begin{example}
+ \RibbonTableau{1{10}crcrcrcrccccc}
+ \end{example}
+
+ As with tableau entries, each box in a ribbon can be preceded with a
+ style specification, either using \keyword{*} for the \option{star
+ style} or using \keyword{[...]} for more customised style
+ specifications.
+
+ \begin{example}
+ \RibbonTableau{
+ *1{10}c*rc*rc*rc*rc*cc*cc,
+ *18c[fill=red]rc[fill=blue]rc*rc*cc[fill=teal]c,
+ [fill=green]16c*rc*rc*cc,
+ *14c[{draw=purple,ultra thick}]cc[fill=orange]r,
+ [{fill=yellow,draw=red,ultra thick}]23
+ }
+ \end{example}
+
+ In particular, the yellow box in this example highlights that boxes
+ are ribbons of length~$1$. Most of the time, you want to style the
+ entire ribbon rather than styling the individual boxes in the ribbon.
+ Optionally, the style for the entire ribbon can be given inside
+ parentheses $(...)$ at the \textit{start} of the ribbon. Unlike the
+ other style specifications, the $*$-shorthand for the \option{star
+ style} cannot be applied to an entire ribbon.
+
+ \begin{example}
+ \RibbonTableau{
+ (fill=red)1{10}crcrcrcrccc_Ccc,
+ (fill=orange)18crcrc*rcc_Bcc,
+ (fill=yellow)16crcr[fill=cyan]c_Acc,
+ (fill=green)14cccr,
+ (fill=blue)23
+ }
+ \end{example}
+
+ Any styles for a ribbon are applied to the region bounded by the
+ closed path given by the border of the ribbon. The ribbon style is
+ applied first, after which any styled boxes in ribbon are drawn. As
+ this example shows, the optional style of any box in the ribbon takes
+ precedence over the style of the full ribbon.
+
+ Finally, it is often necessary to label some of the boxes in the
+ ribbon. Optionally, text can be added to the boxes in a ribbon by
+ supplying it as a \textit{subscript} to the corresponding entry in the
+ ribbon specification:
+
+ \begin{example}
+ \RibbonTableau[french] { 12_1 c_2 r_3 } \quad
+ \RibbonTableau[ukrainian] { 12_a c_b r_c } \quad
+ \RibbonTableau[australian]{ 12_{1_a} c_{2_b} r_{3_c} }
+ \end{example}
+
+ Here we have put spaces between the entries for the different boxes
+ in the ribbon for clarity. There are often many ways to draw the same
+ ribbon tableau, especially if the entries have styling.
+
+ \begin{example}
+ \tikzset{Fill/.style={fill=#1!20!white},
+ B/.style={Fill=blue}, R/.style={Fill=red}, Y/.style={Fill=yellow}}
+ \RibbonTableau{ [B]12_1 [R]c_2 [Y]r_3} \qquad
+ \RibbonTableau{ [B]12_1, [R]11_2, [Y]21_3 } \qquad
+ \Tableau{ [B]2 [R]1, [Y]3 }
+ \end{example}
+
+ As shown, the easiest way to draw this particular tableau is using the \keyword{\Tableau} command.
+
+ There is no dedicated syntax for putting a label on the boundary
+ between two boxes in the diagram, but this can be done using the named
+ anchors of~\autoref{E:NodeNames}.
+
+ \begin{example}
+ \RibbonTableau[shifted, tikz after={
+ \node at (A-1-2.east){$1$};
+ \node at (A-2-2.east){$2$};
+ }]{ 14c, 12c, 23c }
+ \end{example}
+
+ Here is an example of a $3$-ribbon skew tableau.
+
+ \begin{example}
+ \RibbonTableau[skew={2^2,1^2}, skew border]{
+ 14c_0r,15r_1c, 18c_7c,26r_9r,
+ 34c_2c,35r_8r,42r_3c, 44c_4r,
+ 54r_6c,62c_5r
+ }
+ \end{example}
+
+ We have now seen the full ribbon specifications. To summarise:
+ \begin{itemize}[nosep]
+ \item The ribbon specification starts with optional \TikZ-styling
+ for the ribbon (or path), enclosed in $(...)$.
+ \item The first entry in the ribbon is given as
+ \textsf{a}\textsf{b}, if the head of the ribbon is in row
+ \textsf{a} and column \textsf{b}. The remaining entries in the
+ ribbon are specified by a sequence of \textsf{r}'s and \textsf{c}'s,
+ depending on whether the next box in the ribbon is given by
+ increasing the row index, or decreasing the column index,
+ respectively.
+ \item Optionally, each box in the ribbon, including the head, can be
+ given \TikZ-styling by prefixing it with a $*$, which gives the
+ box the \option{star style}, or by giving \TikZ-styling keys inside
+ square brackets $[...]$.
+ \end{itemize}
+
+ Finally, when drawing the border, all ribbons in a
+ \keyword{\RibbonTableau} are assumed to be contained in the smallest
+ Young diagram that contains the ribbons. This said, it is up to you to
+ ensure that the boxes in the ribbon do not have negative column
+ indices. Inside a \keyword{\Diagram} or \keyword{\Tableau} command,
+ any ribbons added using \option{paths}, \option{ribbons}, or
+ \option{snobs} do not affect the border of the diagram or tableau. You
+ can draw paths, ribbons, and snobs so that their boxes are either
+ inside or outside the border of the diagram or tableau. It can be
+ useful to place boxes outside of the diagrams.
+
+ \option[]{paths=path specifications}[comma separated ribbon specifications]<ribbons>
+ \option*[]{ribbons=ribbon specifications}[comma separated ribbon specifications]<ribbons>
+ \option*[]{snobs=snob specifications}[comma separated ribbon specifications]<ribbons>
+
+ You can add \option{ribbons}<ribbons>, \option{paths}<ribbons> and
+ \option{snobs}<ribbons> to a \keyword{\RibbonTableau} in exactly the
+ same way that you add them to \keyword{\Tableau}. At first sight, it
+ seems unnecessary to add \option{ribbons}<ribbons> and
+ \option{snobs}<ribbons> because ribbon tableaux are composed of
+ ribbons. The point is that any ribbon added to a tableau using
+ \option{ribbons}<ribbons> or \option{snobs}<ribbons> is not assumed to
+ be inside the border of the tableau.
+
+ \begin{example}
+ \RibbonTableau[
+ styles={A={fill=green!10, text=teal}, R={fill=yellow!10, text=red}},
+ ribbons={[A]15_A,[A]24_A,[A]41_A, [R]14_R,[R]33_R}
+ ]{11, (fill=blue!10)12rc, 14crrcc}
+ \end{example}
+
+ Here is a cute use of \option{paths} to add arrows to a skew
+ $2$-ribbon tableau:
+
+ \begin{example}[lefthand width=0.35\textwidth]
+ \RibbonTableau[skew={4,3,2,1},
+ styles={L={red,semithick,->}, R={red,semithick,<-}},
+ paths ={ (L)15c, (L)17c, (L)24c, (L)26c,
+ (R)32r,(R)41r,(R)52r,(R)61r, (R)34c},
+ tikz after = { % node labels: row/col/label
+ \foreach \r/\c/\l in {1/6/0,1/8/6,2/5/3,2/7/8}
+ { \node at (A-\r-\c.west){\l};}
+ \foreach \r/\c/\l in {5/1/1,4/2/2,3/3/5,7/1/4,6/2/7}
+ { \node at (A-\r-\c.south){\l};}
+ }
+ ]{ 16c,18c, 25c, 27c, 33r, 42r, 51r, 62r,71r }
+ \end{example}
+
+ The arrows are added by the \option{paths} key using the two styles
+ \textsf{L} and \textsf{R}, which draws ``left'' and ``right'' arrows
+ between the two boxes, where left and right is with respect to the
+ line-order of the two boxes in the corresponding draw command. The
+ two \keyword{\foreach}-statements might look complicated, but they are
+ just loops that add the entries to the tableau. These loops set
+ \keyword{\r}, \keyword{\c} and \keyword{\l} equal to the row index,
+ column index and label, respectively, using the two lists of
+ \keyword{\r}\!/\!\keyword{\c}\!/\!\keyword{\l} triples given above.
+
+ \option[draw=\aTableauColour{Inner}, thin]{ribbon style=style}{\TikZ-styling}
+ \option*[]{ribbon box style=style}{\TikZ-styling}
+
+ Use the \option{ribbon style} and \option{ribbon box} options to
+ append to the default styling of the ribbons and the boxes in the
+ ribbons, respectively. By default, the full ribbons has an inner wall,
+ but the boxes in ribbons have no styling. If you want inner walls,
+ then they can be added using the \option{ribbon box} key.
+
+ \begin{example}
+ \RibbonTableau[ribbon style={draw=red, thick,
+ fill=orange!20}]{16_1r_2c_3c_4c_5c_6r_7c_8}
+ \RibbonTableau[ribbon box style={fill=orange!20,
+ draw=magenta}]{16_1r_2c_3c_4c_5c_6r_7c_8}
+ \end{example}
+
+ Ribbons are drawn by first drawing the full ribbon, applying
+ \option{ribbon style}, then the empty boxes in the ribbon are drawn,
+ and, finally, any boxes in the ribbon that have styling or an entry
+ are added. In particular, if the style \option{ribbon box} draws an
+ outline around a box then this has precedence over any outline added
+ by \option{ribbon style} since \option{ribbon box} is applied last.
+
+ \option[]{ribbon box=text}{default box contents}
+
+ You can add content to the boxes in a ribbon using subscripts in
+ the ribbon specifications. Alternatively, you can use
+ \option{ribbon box} if you want to add the same
+ content to each box in the ribbon.
+
+ \begin{example}
+ \RibbonTableau[ribbon box=\times]{14rccrc}\qquad
+ \RibbonTableau[ribbon box=\bullet]{14_1rc_2cr_3c}
+ \end{example}
+
+ As shown, whenever a box entry is given as a subscript it is used
+ instead of the value of \option{ribbon box}. If a ribbon
+ tableau contains multiple ribbons, then \option{ribbon box} is used
+ for all ribbons.
+
+ Similarly, there are keys \option{path style}, \option{path box},
+ \option{path box style}, \option{snob style}, \option{snob box} and
+ \option{snob box style} that work in exactly the same way. Most of the
+ \keyword{\Tableau} keys work as expected for ribbon tableaux.
+
+ % --------------------------------------------------------------
+ \subsection{Multidiagrams and multitableaux}\label{S:Multitableau}
+ \indexcmd{Multidiagram}
+ \indexcmd{Multitableau}
+ \index{diagram!multidiagram}
+ \index{tableau!multitableau}
+
+ Multitableaux and multidiagrams are $\ell$-tuples of tableaux and
+ diagrams, respectively. Such diagrams appear in many places in representation
+ theory, such as when considering representations of wreath products
+ or cyclotomic Hecke algebras. For convenience, \aTableau provides
+ the \keyword{\Multidiagram} and \keyword{\Multitableau} commands for
+ drawing these diagrams, even though it is possible to construct
+ such tableaux and diagrams using the \keyword{\Tableau} and
+ \keyword{\Diagram} commands.
+
+ \keyword{\Multidiagram (x,y) [options] {multipartition specifications} }\newline
+ \keyword{\Multitableau (x,y) [options] {multitableau specifications} }
+
+ \index{components}
+ \index{multidiagram!components}
+ \index{multitableau!components}
+ Our preferred notation for a multipartition $\blam$ is to write
+ $\blam=(\lambda^{(1)}|\lambda^{(2)}|\dots|\lambda^{(\ell)})$, where
+ $\ell\ge1$ is the \emph{level} and the partitions
+ $\lambda^{(1)},\dots,\lambda^{(\ell)}$ are the \emph{components}
+ of~$\blam$. Similarly, a multitableau is written as
+ $\T=(\T^{(1)}|\dots|\T^{(\ell)})$, where the tableaux
+ $\T^{(1)},\dots,\T^{(\ell)}$ are the \emph{components} of~$\T$.
+ Accordingly, in the \keyword{\Multidiagram} and
+ \keyword{\Multitableau} commands, the pipe symbol \keyword{|} is used
+ to separate components:
+
+ \begin{example}
+ \aTabset{scale=0.7}
+ \Multidiagram{3,2^2|2,1,1|1}
+ \Multitableau[box font=\tiny]
+ { 123,45,67 | 89,{10},{11} | {12}{13}{14} }
+\end{example}
+
+ As shown, the \keyword{\Multidiagram} command accepts exponential
+ notation for multipartitions. The entries in a \keyword{\Multitableau} can
+ be given optional styling specifications, exactly as inside the
+ \keyword{\Tableau} command.
+
+ \begin{example}
+ \tikzset{R/.style={fill=red!10,text=magenta}}
+ \Multitableau{1*24,*68 | [R]9{10},{11}}
+ \end{example}
+
+ Multitableaux and multidiagrams can, in principle, have arbitrary
+ level. In practice, the level is constrained by the page width.
+
+ \begin{example}
+ \Multitableau[french]{1,2 | 3,4 | 5,6 | 7,8 | 9,{10}}
+ \end{example}
+
+ Both the \keyword{\Multitableau} and \keyword{\Multidiagram} commands
+ accept a special component, \keyword{...}, that is used to add dots between the
+ separators:
+
+ \begin{example}
+ \aTabset{scale=0.7}
+ \Multidiagram{3,2^2|...|1}
+ \Multitableau[box font=\tiny]
+ {123,45,67 | ... | {12}{13}{14}}
+ \end{example}
+
+ The \keyword{\Multitableau} and \keyword{\Multidiagram} commands
+ accept most of the options of the \keyword{\Tableau} and
+ \keyword{\Diagram} commands, together with a few options that are
+ specific to multitableaux and multidiagrams. This section describes
+ the new options, and highlights how some of the other options are used.
+
+ \option[-]{english}
+ \option*[]{french}
+ \option*[]{ukrainian}
+ \option*[]{australian}
+
+ All four tableaux conventions are supported for multitableaux and
+ multidiagrams, with the caveat that all component diagrams use the
+ same convention.
+
+ \begin{example}
+ \aTabset{scale=0.7}
+ \Multidiagram[french]{3,2^2|...|1}
+ \Multitableau[ukrainian, box font=\tiny]
+ {123,45,67 | ... | {12}{13}{14}}
+ \end{example}
+
+ \option[]{conjugate}
+ \index{conjugate!multidiagram}
+ \index{conjugate!multitableau}
+ \index{multidiagram!conjugate}
+ \index{multitableau!conjugate}
+
+ The \option{conjugate} option prints the conjugate multitableaux and
+ multidiagrams. Conjugation for multitableaux and multidiagrams reverses
+ the order of the components and then conjugates the component
+ diagrams.
+
+ \begin{example}
+ \aTabset{scale=0.6, box font=\scriptsize}
+ \Multitableau[conjugate]{ 123,45 | 67,89} \quad
+ \Multidiagram[conjugate]{ 3,2 | 1^2 }
+ \end{example}
+
+ \option[()]{delimiters}[pair of \LaTeX{} delimiters]
+ \option*[(]{left delimiter}[a \LaTeX{} delimiter]
+ \option*[)]{right delimiter}[a \LaTeX{} delimiter]
+
+ The delimiter options control the delimiters that are put on the left
+ and right of multitableaux and multidiagrams. These options accept any
+ \LaTeX{} delimiter.
+
+ \begin{example}
+ \aTabset{scale=0.7}
+ \Multidiagram[left delimiter=\langle,
+ right delimiter={]}]{2,1|1} \quad
+ \Multidiagram[delimiters={\|}{\}} ]{1^2|2}
+ \end{example}
+
+ To remove a delimiter, set \option{left delimiter} or
+ \option{right delimiter} to nothing.
+
+ \begin{example}
+ \Multitableau[left delimiter=, right delimiter=]
+ {123,45,67|{12}{14}}
+ \end{example}
+
+ \option[\textbackslash textendash]{empty=text}[any \LaTeX{}]
+
+ The \option{empty} option determines what is printed when a component
+ diagram is empty. By default, the en-dash symbol \textendash{} is
+ used.
+
+ \begin{example}
+ \Multitableau{ 123,45 | | 67,89} \par\bigskip
+ \Multidiagram[empty=$\emptyset$]{ 3,2 | | 2^2 }
+ \end{example}
+
+ \option[]{entries=value}[contents, first, hooks, last, residues]<multitableau>
+ \option*[]{charge=offsets}[$|$-separated list of charges]<multitableau>
+
+ \index{contents}
+ \index{residues}
+ \index{contents!multitableau}
+ \index{first tableau!multitableau}
+ \index{hooks!multitableau}
+ \index{last tableau!multitableau}
+ \index{residues!multitableau}
+ \index{entries!multitableau}
+ \index{multidiagram!show}
+ \index{multitableau!contents}
+ \index{multitableau!first}
+ \index{multitableau!hooks}
+ \index{multitableau!last}
+ \index{multitableau!residue}
+
+ The \option{entries} key automatically fills in particular types of
+ entries for you to draw the requested tableau of the specified shape.
+ Use \option{charge} to provide offsets in each component when using
+ \option{entries=contents} and \option{entries=residues} (and no charge
+ should be set when using \option{entries=first} and
+ \option{entries=last}).
+
+ \nopagebreak[0]
+ The possible choices are:
+ \begin{itemize}
+
+ \item\option{entries=first} print the \emph{first} \textbf{standard} tableau of this
+ shape, which has the numbers $1,2\dots,n$ entered in order from top
+ left to right along down successive rows (with appropriate modifications for
+ the non-English conventions).
+
+ \begin{example}
+ \Multidiagram[entries=first]{3,1^2|2^2,1}
+ \end{example}
+
+ \item\option{entries=last} print the \emph{last} \textbf{standard} tableau of this
+ shape, which has the numbers $1,2\dots,n$ entered in order from top
+ to bottom down successive columns, and right to left along components (with appropriate modifications for
+ the non-English conventions).
+
+ \begin{example}
+ \Multidiagram[entries=last]{3,2,2|2^2}
+ \end{example}
+
+ \item\option{entries=hooks} print the diagram where each box in each
+ component is labelled by the corresponding \emph{hook length}.
+
+ \begin{example}
+ \Multidiagram[entries=hooks]{3,1^2|3^3}
+ \end{example}
+
+ \item\option{entries=contents} print the diagram where each box is
+ labelled by its \emph{content}, which is the row index minus the
+ column index.
+
+ \begin{example}
+ \Multidiagram[entries=contents,
+ charge={0,2}] {3,2,1|2^2}
+ \end{example}
+
+ As shown, the \option{charge} offsets the contents in each
+ component.
+
+ \item\option{entries=residues} print the diagram where each box is
+ labelled by its \emph{residue}, which is the row index minus the
+ column index modulo some integer~$e$, which must also be supplied.
+
+ \index{residues}
+ \index{tableau!residues}
+ \begin{example}
+ \Multidiagram[entries=residues, e=2]{3,2,1|1^3}
+ \end{example}
+
+ Specifying the \option{charge} offsets the residues in each component.
+
+ \begin{example}
+ \Multidiagram[french, entries=residues, e=3,
+ charge={1,2}]{3,2,1|1^2}
+ \end{example}
+
+ \medskip\noindent
+ As in \autoref{SS:entries}, residues for the other affine Cartan types
+ can be specified using \option{cartan=value}.
+
+ \end{itemize}
+
+ \option[]{label=labels}[a $|$-separated list of labels]
+
+ Use the \option{label} key to add labels to the component diagrams.
+
+ \begin{example}
+ \Multitableau[label={1|2}]{123,45,67|{12}{14}}
+ \end{example}
+
+ No extra space is allowed for the labels, so use the
+ \option{separation} key, or \option{xoffsets} and \option{yoffsets},
+ to adjust for wide labels.
+
+ \option[A]{name=text}[character]<multi>
+
+ The \option{name} option is used to change the default prefix for the
+ box node names. In a tableau, or diagram, the box names depend on the
+ \emph{row} and \emph{column} indices. In a multitableau, or
+ multidiagram, the box names depend on the \emph{component}, \emph{row}
+ and \emph{column} indices. Explicitly, by default, in multitableaux
+ and multidiagrams the names of the take the form \textsf{A-k-r-c},
+ where~\textsf{k} is the component index,~\textsf{r} is the row index,
+ and~\textsf{c} is the column index of the box.
+ \footnote{This follows the convention for nodes in multidiagrams
+ from~\cite{EvseevMathas:DeformedKLR}, rather than the somewhat misguided
+ convention that the author introduced in~\cite{DJM:cyc}.}
+ The \textsf{B} can be changed like using the \option{name} key.
+
+ \begin{example}
+ \Multitableau[name=A, tikz after = {
+ \draw[red, thick,<->](A-1-2-2.south east) to
+ [out=315,in=225] (A-2-2-1.south west);
+ }] { 123,4*5 | 67,*89}
+ \end{example}
+
+ \option[]{paths=path specifications}[a $|$-separated list of ribbon path specifications]<multi>
+ \option*[]{ribbons=ribbon specifications}[a $|$-separated list of ribbon specifications]<multi>
+ \option*[]{snobs=snob specifications}[a $|$-separated list of ribbon specifications]<multi>
+
+ The \option{paths}<multi>, \option{ribbons}<multi>, and
+ \option{snobs}<multi> keys work in exactly the same way for
+ multitableaux and multidiagrams as they do for tableaux and diagrams,
+ except that the ribbons for different components are separated by a
+ pipe $|$.
+
+ \begin{example}
+
+ \Multitableau[ribbons={(R)11*r | (Y)12rc},
+ styles={R={fill=red!10, opacity=0.5},
+ Y={fill=yellow!20, opacity=0.5}
+ }] { 123,45 | 67,89}
+ \end{example}
+
+ Notice that the $4$ is the first component has disappeared because
+ the second node in the ribbon \textsf{(R)11*r} has $*$-styling, which
+ writes over the $4$. (One way to recover the missing entry is to use the
+ ribbon specification \textsf{(R)11*r\textunderscore4}.)
+
+ \option[]{rows=number}[a decimal number]
+
+ The \option{rows} option sets the number of rows covered by the
+ delimiters in multitableaux and multidiagram. By default, the
+ \keyword{\Multitableau} and \keyword{\Multidiagram} set
+ the size of the delimiters so that they match the component diagrams, which may
+ not be what you want especially when using the \option{australian} and
+ \option{ukrainian} conventions. The value of \option{rows} can be a
+ decimal number.
+
+ \begin{example}
+ \Multidiagram[ukrainian, scale=0.5]{3,2^2|...|2,1^2}
+ \end{example}
+
+ \begin{example}
+ \Multitableau[rows=3, scale=0.8, box font=\tiny]
+ {{1_1}{1_1}{1_1}{2_1},{2_1}{2_1}{2_1} |
+ {1_2}{3_3},{2_2} |
+ {1_3}{1_3},{2_3}}
+ \end{example}
+
+ \begin{example}
+ \Multitableau[ukrainian, rows=2.5, scale=0.8, box font=\tiny]
+ {{1_1}{1_1}{1_1}{2_1},{2_1}{2_1}{2_1} |
+ {1_2}{3_3},{2_2} |
+ {1_3}{1_3},{2_3}}
+ \end{example}
+
+ \option[true]{separators}[true/false]
+ \option*[false]{no separators}[false/true]
+
+ When \option{separators} is true, delimiters are drawn around the
+ component diagrams in a multitableaux and a multidiagram and
+ separators are drawn between the component shapes, and
+ \option{no separators} is the inverse option. By default, separators
+ and delimiters are drawn.
+
+ \begin{example}
+ \Multitableau[separators, scale=0.8]
+ {123,45,67 | 89,{10}{11}} \par\bigskip
+ \Multidiagram[no separators, scale=0.7]
+ {3,2^2|2,1^2} \par\bigskip
+ \end{example}
+
+ \option[$|$]{separator=text}[character]
+
+ The \option{separator} determines what is printed between the
+ component diagrams in multitableaux and multipartition. By default,
+ \option{separator=$|$} draws a straight line between the
+ components, but any character can be used.
+
+ \begin{example}
+ \Multitableau[separator={,}]{ 123,45 | 67,89} \par\bigskip
+ \Multidiagram[separator=:]{ 3,2 | 2^2 }
+ \end{example}
+
+ \option[\aTableauColour{Main}]{separator colour=colour}[a \LaTeX{} colour]
+
+ The \option{separator colour} sets the colour of the delimiters and
+ the separator between component diagrams. By default, the separators
+ are the same colour as the diagram border.
+
+ \begin{example}
+ \Multitableau[separator colour=red]{123,45 | 67,89} \par\bigskip
+ \Multidiagram[separator color=brown, separator=:]
+ {3,2 | 2^2 }
+ \end{example}
+
+ \option[0.3]{separation=number}[a decimal number (the distance in \unit{cm})]
+
+ The \option{separation} key sets the distance between the separators
+ and the component tableaux and diagrams.
+
+ \begin{example}
+ \Multitableau[separation=0.1]{123,45 | 67,89} \par\bigskip
+ \Multidiagram[separation=0.8]{3,2 | 2^2}
+ \end{example}
+
+ \option[]{skew=partitions}{a $|$-separated list of partitions}
+
+ Skew multishapes can be drawn using the \option{skew} option to
+ specify a $|$-separated list of inner shapes.
+
+ \begin{example}
+ \Multitableau[skew={2,1|1}]{ 123,45 | 7{10},89} \par\bigskip
+ \Multidiagram[skew={1|2,1}, skew boxes]{ 3,2 | 2^2 }
+ \end{example}
+
+ There is no command for drawing shifted multitableau or multidiagrams.
+ Such diagrams can be drawn using the
+ \option{skew} key. In the same way, it is possible to draw
+ multitableaux and multidiagrams with components that are a mixture of
+ non-skew, skew and shifted shapes.
+
+ \begin{example}
+ \Multitableau[skew={0,1|0,1}]{ 1236,45 | 7{10}{11},89} \par\bigskip
+ \Multidiagram[skew={|0,1}]{ 3,2 | 2,1 }
+ \end{example}
+
+ \option[true]{tabloid}[true/false]
+
+ Use the \option{tabloid} key for multitabloid diagrams and tableaux.
+
+ \begin{example}
+ \Multitableau[tabloid]{ 123,45 | 67,89} \par\bigskip
+ \Multidiagram[tabloid]{ 4,2 | 2^2 }
+ \end{example}
+
+ \option[0]{xoffsets=offsets}[$|$-separated list of $x$-offsets]
+ \option*[0]{yoffsets=offsets}[$|$-separated list of $y$-offsets]
+
+ The \keyword{\Multitableau} and \keyword{\Multidiagram} commands try
+ to draw the diagrams as compactly as possible with their first rows
+ aligned, and the distance between the separators given by the value of
+ \option{separation}. Use the \option{xoffsets} to offset the
+ $x$-coordinates of the component diagrams and \option{yoffsets} to
+ offset their $y$-coordinates.
+
+ \begin{example}
+ \Multitableau[xoffsets={0.5,0.2}]{ 123,45 | 67,89} \par\bigskip
+ \Multidiagram[yoffsets={0,1.5}]{ 4,2 | 2^2 }
+ \end{example}
+
+ When using \option{xoffsets} or \option{yoffsets}, you may want to use
+ \option{no separators} to disable the separators between component
+ shapes. For example, here is a homogeneous Garnir tableau using the
+ style of~\cite{KMR:UniversalSpecht}, where no separators are used and
+ the component tableaux are stacked vertically.
+
+ \begin{example}[label=Ex:Garnir]
+ \Multidiagram[entries=first, no separators,
+ xoffsets={0|-1.1}, yoffsets={0|-1},
+ styles={O={fill=orange!50}, P={fill=purple!50}},
+ snob style={draw=red,double,thick,fill=white},
+ snobs={|(O)24_{15}c_{14}, (P)26_{17}c_{16}, 27_{18},
+ 31_{11}, (P)33_{13}c_{12}}
+ ]{1|7^2,4,1}
+ \end{example}
+
+ This is a slightly lazy way of drawing this multitableau because
+ \option{entries=first} is used to automatically populate most of the
+ entries and then \option{snobs=...} are used to rewrite the ``bricks''
+ in the homogeneous Garnir belt.
+
+ % --------------------------------------------------------------
+ \section{Abacuses} \label{S:Abacus} \index{abacus} \indexcmd{Abacus}
+
+ Gordon James introduced the abacus, with beads and runners, as another
+ way to represent a partition~\cite{James:YoungD}. The abacus is
+ particularly useful in modular representation theory, where the number
+ of runners is the (quantum) characteristic. Abacus combinatorics are
+ now used to help many algebras beyond their initial appearance in the
+ representation theory of the symmetric groups.
+
+ The partition corresponding to an abacus is given by counting the
+ number of empty bead positions before each bead on the abacus. The
+ \keyword{\Abacus} command, which draws an abacus representation of a
+ partition, has a similar syntax to the tableau and diagram commands.
+
+ \keyword{\Abacus (x,y) [options] {number of runners} {bead specifications}}
+
+ As with other \aTableau commands, the $(x,y)$-coordinates are
+ necessary if, and only if, the abacus is part of a
+ \keyword{tikzpicture} environment. The number of runners is a
+ positive integer that specifies the number of abacus runners.
+
+ % --------------------------------------------------------------
+ \subsection{Bead specifications}
+
+ In their simplest form, the bead specifications are a comma separated
+ list of non-negative integers specifying a partition. Partitions can
+ be given either as comma separated lists of non-negative integers, or
+ using exponential notation. The full bead specifications add optional
+ styling and bead labels.
+
+ Here are some examples showing basic usage of the \keyword{\Abacus}
+ command:
+
+ \begin{Example}
+ \aTabset{align=top}
+ \Abacus{1}{2,1,1} \qquad \Abacus{2}{2,1^2,0^3} \qquad \Abacus{3}{2,1^2,0^5} \qquad
+ \Abacus{4}{2,1^2,0^5} \qquad \Abacus{5}{2,1^2,0^5} \qquad \Abacus{6}{2,1^2,0^5}
+ \end{Example}
+
+ The beads in an abacus correspond to the parts of the partition. Just
+ as with the \keyword{\Tableau} command, each of the beads can be given
+ optional styling, which can either be given by prepending a
+ \keyword{*}, which applies the \option{abacus star style}, or by
+ giving \TikZ styling-keys inside square brackets \keyword{[...]}.
+ When exponential notation is used, the styles are applied to all of the
+ associated beads.
+
+ \begin{example}
+ \aTabset{align=top}
+ \Abacus{3}{3,*2^3,1} \qquad
+ \Abacus{4}{2,*1,[ball color=red]1^2, *1,
+ [ball color=orange]1,[ball color=brown]0}
+ \end{example}
+
+ In particular, in the right-hand abacus, the two beads corresponding
+ to \keyword{1^2} are coloured red, whereas the other three beads that
+ correspond to a~$1$ are either orange or an off-white colour, which is
+ the default \option{abacus star style}. As with the tableaux commands,
+ we recommend using \keyword{\tikzset} to define more complicated bead styles.
+
+ In addition to applying style to the individual beads on the abacus,
+ \emph{labels} for any bead can (optionally) be given as a subscript in the
+ bead specifications. Again, the same labels are applied to all of the
+ corresponding beads when exponential notation is used.
+
+ \begin{example}
+ \Abacus{2}{5_5, 4_4, 3_3, 2_2,0_0} \qquad
+ \Abacus[styles={R={ball color=red, text=yellow}}]
+ {3}{*5^2_5, [R]4^3_4, 3, 2_2,*0^2_{oo}} \qquad
+ \Abacus{4}{8^2_-,7_+,5_a,4^2_b,1_\times^3,1_d}
+ \end{example}
+
+ The bead labels are arbitrary, however, anything wider than the bead
+ will spill into the abacus. Traditionally, abacus beads are not labelled,
+ but you can give labels to as many beads as you like.
+
+ You can remove beads that you have placed on the abacus using the \emph{no shade} style%
+ \footnote{\TikZ \emph{does not} provide a way to disable
+ a shading that is already in effect. The \emph{no shade} style, which is
+ based on a \href{https://tex.stackexchange.com/a/85750/234252}{stack exchange post},
+ is available whenever the \aTableau package is loaded.}.
+ The point of being able to remove beads in this way is that this
+ allows you to put something else in its place using the bead label.
+ In such cases, you probably want to change the text colour, which is white
+ by default.
+
+ \begin{example}[label=Ex:NoShade]
+ \Abacus[styles={C={no shade,text=red}}]
+ {5}{8^2_-,7_+,5_a,4^2_b,[C]1_\bullet^3,1_d}
+ \end{example}
+ \index{no shade}
+
+ As with tableau boxes, the bead labels are typeset in
+ mathematics~mode by default. This can changed using
+ \option{math entries} and \option{text entries}.
+ \index{math entries!abacus}
+ \index{text entries!abacus}
+
+ % --------------------------------------------------------------
+ \subsubsection{Abacus coordinates}\label{SS:abcoordinates}
+ \index{xy@$(x,y)$}
+ \index{Cartesian coordinates!abacus}
+
+ The $(x,y)$-coordinates are required if, and only if, the
+ \keyword{\Abacus}command is used inside a \keyword{tikzpicture}
+ environment, in which case $(x,y)$ gives the coordinates of the
+ ``outside corner'' of the box in row~$1$ and column~$1$ of the
+ tableau. The following example shows how tableaux are placed using
+ $(x,y)$-coordinates inside a \keyword{tikzpicture} environment. The
+ example also shows that, by default, the beads and runners in an
+ abacus are half a unit apart.
+
+ \begin{example}
+ \begin{tikzpicture}[add grid]
+ \aTabset{abacus ends=_|}
+ \Abacus(0,0.5) [south] {3}{2,1^2}
+ \Abacus(0,2) [east, bead=red] {3}{2,1^2}
+ \Abacus(2.5,0.5)[north, bead=orange] {3}{2,1^2}
+ \Abacus(3.5,-1) [west, bead=brown] {3}{2,1^2}
+ \end{tikzpicture}
+ \end{example}
+
+ % --------------------------------------------------------------
+ \subsection{Abacus keys}
+
+ The abacus keys, or options, control the general appearance of the
+ abacuses drawn by the \keyword{\Abacus} command. Many of the options,
+ or keys, for tableaux and diagrams can be applied to abacuses, and we
+ do not discuss all of these options here. For example, the
+ \keyword{\Abacus} command accepts the following keys:
+ \option{align}, \AddKeyLink{align-abacus}\AddKeyLink{halign-abacus}\AddKeyLink{valign-abacus}
+ \option{math entries}, \AddKeyLink{math entries-abacus}
+ \option{text entries}, \AddKeyLink{text entries-abacus}
+ \option{name}, \AddKeyLink{name-abacus}
+ \option{scale}, \AddKeyLink{scale-abacus}\AddKeyLink{xscale-abacus}\AddKeyLink{yscale-abacus}
+ \option{styles}, \AddKeyLink{styles-abacus}
+ \option{tikz after}, \AddKeyLink{tikz after-abacus}
+ \option{tikz before}, and \AddKeyLink{tikz before-abacus}
+ \option{tikzpicture}. \AddKeyLink{tikzpicture-abacus}
+ See \autoref{S:keys} for the complete list.
+
+ \option[-]{south}
+ \option*[]{east}
+ \option*[]{north}
+ \option*[]{west}
+
+ Just like tableaux, abacus have four different conventions. By
+ default, abacuses are drawn with the runners pointing to the south,
+ from top to bottom, and runners increasing from left to right. Similar
+ to tableaux, we number the rows $0,1,\dots$, and we number the
+ runners, or columns, $0,1,\dots,e-1$, from left to right (when using
+ \option{south}). If there are $e$ runners, then the bead in row~$r$
+ and column~$c$ is in position $er+c$. See \autoref{Ex:BeadPositions}
+ for an example.
+
+ Using the keys \option{east}, \option{north} and \option{west},
+ abacuses can be drawn so that the row index increases to the east,
+ north, and west, respectively.
+
+ \begin{Example}
+\Abacus[south,entries=betas]{2}{4^2,2,1}\qquad\Abacus[east,entries=betas]{2}{4^2,2,1}\qquad
+\Abacus[north,entries=betas]{2}{4^2,2,1}\qquad\Abacus[west,entries=betas]{2}{4^2,2,1}
+ \end{Example}
+
+ To make these conventions clearer, we have used
+ \option{entries=betas}<abacus> to label the beads in these abacuses by
+ their bead positions, or \emph{beta numbers}.
+
+ \option[$-|$]{abacus ends} [any pair of: $-$, \_\!\_, ., *, $|$, \textgreater]
+ \option*[very thick, draw=\aTableauColour{Inner}]{abacus ends style=style}[\TikZ-styling]
+
+ The \option{abacus ends} key sets the style used for the top and
+ bottom of the abacus. The meaning of these six symbols is the
+ following:
+
+ \begin{quote}
+ \begin{options}[labelwidth=1em, nosep]
+ \item[$-$] Adds a line that extends slightly past the first and last runners
+ \item[\_\!\_] Adds a line between the first and last runners
+ \item[.] Add dots to the end of each runner
+ \item[*] Add dots and an arrow to the end of each runner
+ \item[$|$] The runners do not have any additional decoration
+ \item[$>$] Add arrows to the end of each runner
+ \end{options}
+ \end{quote}
+
+ Exactly two of these styling characters must be given when setting
+ \option{abacus ends}. There are six options for the top of the abacus,
+ and six options for the bottom, so there are 36 possible
+ configurations (most of which will never be used...). We do not list
+ all of them, but here are some examples.
+
+ \begin{Example}
+ \aTabset{align=top}
+ \Abacus[abacus ends=-|]{3}{2,1^2,0^3}\qquad\Abacus[abacus ends=-_]{3}{2,1^2,0^3}\qquad
+ \Abacus[abacus ends=_.]{3}{2,1^2,0^3}\qquad\Abacus[abacus ends=>>]{3}{2,1^2,0^3}\qquad
+ \Abacus[abacus ends=>|]{3}{2,1^2,0^3}\qquad\Abacus[abacus ends=_-]{3}{2,1^2,0^3}\qquad
+ \Abacus[abacus ends=>-]{3}{2,1^2,0^3}\qquad\Abacus[abacus ends=-*]{3}{2,1^2,0^3}
+ \end{Example}
+
+ As one more example, \emph{beta numbers} can be displayed on a single
+ runner using:
+
+ \begin{example}
+ \Abacus[abacus ends=**, east, rows=7]{1}{2,1^2,*0^2}
+ \end{example}
+
+ The \option{abacus ends style} key changes the \TikZ-styling of the
+ ends of the abacus. By default, this styling is the same as the
+ styling for the abacus runners, which is set using
+ \option{runner style}. Changes to \option{runner style} also change
+ the style of the abacus ends, but their style is ultimately determined
+ by \option{abacus ends style}.
+
+ \begin{example}
+ \Abacus[abacus ends style={aTableauMain,
+ ultra thick}]{3}{2,1^2,0^3}\qquad
+ \Abacus[runner style=cyan]{3}{2,1^2,0^3}\qquad
+ \Abacus[abacus ends style=aTableauMain,
+ runner style=cyan] {3}{2,1^2,0^3}
+ \end{example}
+
+ \option[ball color=\aTableauColour{StarStyle}, text=\aTableauColour{Main}]{abacus star style=style}
+ [\TikZ-styling]
+
+ The \option{abacus star style} key appends \TikZ-style keys to the
+ abacus $*$-style:
+
+ \begin{example}
+ \Abacus{3}{5,*4_a,*1^2,0^4} \qquad
+ \Abacus[abacus star style={ball color=yellow,text=black}]
+ {3}{5,*4_a,*1^2,0^4}
+ \end{example}
+
+ \option[\aTableauColour{Main}]{bead=colour}[a \LaTeX colour]
+
+ The \option{bead} key sets the bead colour.
+
+ \begin{example}
+ \Abacus{2}{2^3,1} \qquad
+ \Abacus[bead=black]{3}{4^3,2,1} \qquad
+ \Abacus[bead=red]{4}{4^3,[ball color=blue]2,1}
+ \end{example}
+
+ The \option{bead} key changes the colour of every bead on the
+ abacus. As shown, the colour of individual beads can be changed by
+ applying the \TikZ-style \keyword{ball color} to the bead.
+
+ \option[\textbackslash small]{bead font=font command}[\LaTeX\ font command]
+
+ The \option{bead font} key sets the font used for the bead labels.
+ By default, these labels are typeset as mathematics, so
+ this is mainly useful for changing the font size (because, for example
+ \keyword{\bfseries $1$} does not make the $1$ bold). It is only when
+ you are using \option{text entries} that font commands like
+ \keyword{\itshape} and \keyword{\bfseries} will have any effect.
+
+ \begin{example}
+ \Abacus{3}{3_3,2^2,1^3} \qquad
+ \Abacus[bead font=\tiny]{3}{3_3,2^2,1^3} \qquad
+ \Abacus[text entries, bead font=\bfseries]{3}{3_3,2^2,1^3}
+ \end{example}
+
+ The \option{scale} key can also be used to resize abacuses.
+
+ \option[0.4]{bead size=number}[decimal number, distance in \unit{cm}]
+ \option*[0.42]{bead sep=number}[decimal number, distance in \unit{cm}]
+ \option*[0.42]{runner sep=number}[decimal number, distance in \unit{cm}]
+
+ These three keys control the size of the beads and the distance
+ between them, so they would normally be used together. By default, the
+ \emph{diameter} of the abacus beads is \qty{0.4}{cm}, the distance
+ between adjacent beads on the same runner is \qty{.42}{cm}, and the
+ distance between consecutive runners is \qty{0.42}{cm}.
+
+ \begin{example}
+ \Abacus[bead size=0.6,
+ bead sep=0.65,
+ runner sep=0.65]
+ {3}{3_3,2^2,1^3}
+ \end{example}
+
+ As with tableau, you can also change the size of the abacuses using
+ \option{scale}<abacus>, \option{xscale}<abacus> and
+ \option{yscale}<abacus>. Changing these keys globally affects both
+ abacuses and tableaux.
+
+ \option[]{bead style=style}[\TikZ-styling]
+
+ The keys above are usually sufficient for fine-tuning the style of the
+ abacus beads. Alternatively, the \option{bead style} key appends
+ \TikZ-styling to the default bead style, which has many moving parts.
+
+ \begin{example}
+ \Abacus[bead style={shading=axis}, bead text=red] {3}{3_3,2^2,1^3} \qquad
+ \Abacus[bead style={no shade, fill=aTableauMain}] {3}{3_3,2^2,1^3}
+ \end{example}
+
+ By default, the beads look like balls (they use the
+ \TikZ-styling \keyword{shading=ball, ball color=}\aTableauColour{Main}).
+ In contrast, the beads on the left look like go beads, and those
+ on the right are flat.
+
+ \option[white]{bead text=colour}[a \LaTeX~colour]
+
+ The \option{bead text} key sets the text colour of the abacus labels.
+
+ \begin{example}
+ \Abacus[bead=blue, bead text=yellow] {3}{3_3,2^2,1^3}
+ \end{example}
+
+ \option[false]{beta numbers}[false/true]
+
+ When \option{beta numbers} is set, the numbers in the bead
+ specifications are entered as \emph{beta numbers}. The beta numbers
+ give the bead positions, which are numbered $0,1,\dots$, starting from
+ the first row and then continuing in this way in subsequent rows. More
+ explicitly, if there are $e$ runners then the bead in row~$r$ and
+ column~$c$ is in position $er+c$. Up to shift, bead numbers are first
+ column hook lengths. In particular, beta numbers are pairwise
+ distinct.
+
+ \begin{example}
+ \Abacus{3}{3,2^2} \qquad
+ \Abacus[beta numbers]{3}{5,3,2} \qquad
+ \Abacus[beta numbers]{3}{6,4,3,[ball color=red]0}
+ \end{example}
+
+ There is no inverse key to \option{beta numbers}, however,
+ \option{beta numbers=false} will remove the requirement to use beta
+ numbers in the bead specifications.
+
+ \option[]{dotted cols=column indices}[list of runner indices]<abacus>
+ \option*[]{dotted rows=row indices}[list of row indices]<abacus>
+
+ The \option{dotted rows}<abacus> and \option{dotted cols}<abacus> keys
+ draw abacuses where the specified rows and columns are replaced with
+ dots. This makes it possible to draw \emph{generic} abacuses, where
+ the number of rows and columns is not fully specified. Note that for
+ abacuses, both the row and column indexing starts from~$0$.
+
+ \begin{example}
+ \Abacus[dotted rows={2,4}]{4}{8,5,4,3,2,1} \qquad
+ \Abacus[dotted cols={1,3},abacus ends=-*]{6}{9,8,5,4,3^3,2}
+ \end{example}
+
+ As with tableau, consecutive rows and columns are treated together.
+
+ \begin{example}
+ \Abacus[dotted rows={1,2,3}]{4}{8,5,4,3,2,1} \qquad
+ \Abacus[dotted cols={1,2,3},abacus ends=-*]{6}{9,8,5,4,3^3,2}
+ \end{example}
+
+ Comparing these two examples shows that the beads and runners in the
+ dotted rows and columns are removed by \option{dotted rows}<abacus>
+ and \option{dotted cols}<abacus>, respectively. Named coordinates,
+ for use with \option{name}<abacus>, are not created for the bead and
+ tick positions on the dotted rows and columns.
+
+ The \option{dotted cols}<abacus> ad \option{dotted rows}<abacus> keys
+ can be used together, in which case the \option{dotted rows}<abacus>
+ are removed first, after which the \option{dotted cols}<abacus> are
+ removed. The output may need to be adjusted if the dotted rows and
+ columns overlap. For example, consider the abacus:
+
+ \begin{example}
+ \Abacus[dotted cols={2,3},
+ dotted rows={2,3}
+ ]{6}{26,21^2,5^2,3,2^2,0^2}
+ \end{example}
+
+ The cross-hatched dots in the centre of the abacus are not ideal. The
+ following trick addresses this:
+
+ \begin{example}[lefthand width=0.16\textwidth, label=Ex:DottedAbacus]
+ \Abacus[dotted cols={2,3}, dotted rows={2,3},
+ tikz after = {
+ \draw[aTableau/clearBoxes](A-1-1.south east)rectangle(A-4-4.north west);
+ \draw[aTableau/dottedLine](A-1-1.south east)--(A-4-4.north west);
+ }
+ ]{6}{26,21^2,5^2,3,2^2,0^2}
+ \end{example}
+
+ \option[]{entries=value}[betas, residues, rows, shape]<abacus>
+
+ Like the \option{entries} key for tableaux, the
+ \option{entries}<abacus> key for abacuses provides a shortcut for
+ labelling the abacus beads by some common choices. The possible
+ choices are:
+
+ \begin{itemize}
+
+ \item\option{entries=betas}\index{entries!beta}\index{beta numbers!entries}
+ \label{beta numbers!abacuses}
+ Labels the beads by the corresponding \emph{beta numbers}.
+ \begin{example}
+ \Abacus[entries=betas]{3}{3,2^2,0^2} \qquad
+ \Abacus[entries=betas]{4}{3,2^2,1^3,0^2}
+ \end{example}
+
+ \item\option{entries=residues}\index{entries!residues}
+ Labels the beads by their residues. Unlike for tableaux, it is not
+ necessary to specify the quantum characteristic \option{e}<abacus>,
+ because this is determined by the number of runners and the
+ \option{cartan}<abacus> type. You can override this by setting
+ \option{e}<abacus> manually.
+ \begin{example}
+ \Abacus[entries=residues,]{3}{3,2^2,0^2} \qquad
+ \Abacus[entries=residues, cartan=C]
+ {4}{3,2^2,1^3,0^2}
+ \end{example}
+
+ \AddKeyLink{e-abacus}
+ \AddKeyLink{charge-abacus}
+ \AddKeyLink{cartan-abacus}
+ \noindent
+ As with (multi)tableau, use the \option{charge}<abacus> key to
+ add an offset to the residues, and the \option{cartan}<abacus> key for
+ residues of other Cartan types.
+
+ \item\option{entries=rows}\index{entries!rows}
+ Labels the beads by their rows index of the corresponding part in the
+ partition.
+ \begin{example}
+ \Abacus[entries=rows]{3}{3,2^2,0^2} \qquad
+ \Abacus[entries=rows]{4}{3,2^2,1^3,0^2}
+ \end{example}
+ \noindent
+ As shown, the beads corresponding to zero parts of the corresponding
+ partition are marked with a dash, since there is no corresponding row
+ in partition for such beads.
+
+ \item\option{entries=shape}\index{entries!partition}
+ Labels the beads by their shape. That is, each bead is labelled by the
+ corresponding by the corresponding part of the partition.
+ \begin{example}
+ \Abacus[entries=shape]{3}{3,2^2,0^2} \qquad
+ \Abacus[entries=shape]{4}{3,2^2,1^3,0^2}
+ \end{example}
+
+ \end{itemize}
+
+ \option[A]{name=text}{text}
+
+ Just like the tableaux commands, the \keyword{abacus} command defines
+ named coordinates for all of the \emph{beads} and \emph{ticks} on the
+ abacus. By default, the named coordinates take the form
+ $(\mathsf{A{-}r{-}c})$, for the bead or tick in row~$r$ and column~$c$ of the
+ abacus. Note that for abacuses, both the row and column indexing starts
+ from~$0$. The key \option{name} changes the prefix used for the names.
+ For example, after \option{name=X} the bead and tick names take the
+ form~$(\mathsf{X{-}r{-}c})$.
+
+ \begin{Example}[label=Ex:BeadPositions]
+ \Abacus[name=X,
+ tikz after={
+ \draw[orange,<-,thick] (X-0-0.west) -- ++(-1,0)
+ node[blue,align=left,anchor=east] {Empty bead\\ position};
+ \draw[red,<-,thick] (X-2-2.east) -- ++(2,0)
+ node[blue,align=left,anchor=west] {First part of\\the partition};
+ }]{3}{4^3,1^2}
+ \end{Example}
+
+ \option[]{no shade}[]
+
+ The abacus balls are drawn with the \TikZ style
+ \keyword{shading=ball}. As noted in \autoref{Ex:NoShade}, you can
+ disable the \TikZ-ball shading for individual beads using the \TikZ-style \keyword{no shade}. The
+ \option{no shade} key disables the ball shading for \emph{all} beads,
+ which allows you to fully customise how the abacus beads are
+ displayed.
+
+ \begin{example}
+ \Abacus[no shade, bead text=red]{3}{3_1,2_2,2_3} \qquad
+ \Abacus[bead style={no shade, shape=diamond,
+ fill=brown, text=yellow}]{3}{3_1,2_2,2_3,0^2}
+ \end{example}
+
+ As the first example shows, if you use the \option{no shade} key then
+ you need to define a new style for the abacus beads. As the second
+ example shows, rather than using \option{no shade} as an
+ \keyword{\Abacus} key, you can use it inside \option{bead style} as a
+ \TikZ-style. (We include the \option{no shade} option partly for
+ convenience and partly to advertise how to use it.)
+
+ \option[]{rows=row index}[non-negative integer]<abacus>
+
+ By default, the \keyword{\Abacus} command uses the smallest number of
+ rows necessary to display all of the beads on the abacus. Use the
+ \option{rows}<abacus> key to change the number of rows displayed. If you use
+ the \option{rows}<abacus> key, then it is your responsibility to ensure that
+ the abacus has enough rows to display all of the beads.
+
+ \begin{example}
+ \Abacus{3}{3,2^2,0^2} \qquad
+ \Abacus[rows=4]{3}{3,2^2,0^2} \qquad
+ \Abacus[rows=5]{3}{3,2^2,0^2}
+ \end{example}
+
+ \option[draw=\aTableauColour{Inner}]{runner=colour}[a \LaTeX colour]
+ \option*[very thick]{runner style=style}[\TikZ-styling]
+
+ Use \option{runner} to set the colour of abacus runners.
+
+ \begin{example}
+ \Abacus{3}{3,2^2} \qquad
+ \Abacus[runner=red]{3}{5,3,2,0^2} \qquad
+ \Abacus[runner=brown, bead=blue]
+ {3}{6,4,3,[ball color=red]0^2}
+ \end{example}
+
+ The \option{runner style} key appends \TikZ-styling to the abacus
+ runner style.
+
+ \begin{example}
+ \Abacus[runner style={dashed}]{3}{3,2^2} \quad
+ \end{example}
+
+ \option[]{runner labels=labels}{list of labels for the abacus runners}
+ \option*[font=\textbackslash scriptsize, text=\aTableauColour{Inner}]{runner label style=style}[\TikZ-styling]
+
+ The \option{runner labels} key adds labels to the each runner. An
+ error if given if the number of labels does not match the number of
+ runners. Use \option{runner label style} to change the style of the
+ label.
+
+ \begin{example}
+ \Abacus[runner labels={1,2,0},
+ entries=residues]{3}{3,2^2,0^2} \qquad
+ \Abacus[runner labels={2,3,0,1}, entries=residues,
+ runner label style={circle, draw=cyan, inner sep=0pt,
+ minimum size=2.5mm}] {4}{5,3,2^2,0^2}
+ \end{example}
+
+ As with the \option{label} key for tableau, the runner labels are
+ typeset as mathematics, by default.
+
+ \option[\aTableauColour{Inner}]{tick=colour}[a \LaTeX colour]
+ \option*[semithick]{tick style=style}[\TikZ-styling]
+ \option*[0.1]{tick length=number}[length in \unit{cm}]
+
+ These three keys control the ticks on the abacus runners, which mark
+ the empty bead positions. Use \option{tick} to the colour of the
+ ticks on the abacus runners. The other two key have the obvious meanings.
+
+ \begin{example}
+ \Abacus[tick=red]{3}{6,4,3,1,0} \qquad
+ \Abacus[tick style={ultra thick,orange}]{3}{6,4,3,1,0} \qquad
+ \Abacus[tick length=0.3]{3}{6,4,3,1,0} \qquad
+ \end{example}
+
+ % --------------------------------------------------------------
+ \section{Examples from the literature}
+
+ This section shows how to draw some tableaux that appear in the
+ literature. All of these diagrams predate this package. The aim of
+ this section is to show how these pictures can be drawn using this
+ package.
+
+ Diagrams like the following are common. Note the use of a ribbon to
+ add the $\alpha$ in row~$6$ and column~$8$.
+
+ \begin{example}
+ \Diagram[french, no boxes, ribbons={*68_\alpha}]
+ {15,13,12,9,8^2,5,3}
+ \end{example}
+
+ Mendes~ \cite{Mendes:hooks} uses tableaux like these to give a new
+ proof of the Murnaghan-Nakayama rule.
+
+ \begin{example}
+ \tikzset{C/.style={circle,draw=blue,
+ minimum size=3.5mm, fill=white,thick}}
+ \Diagram[paths={
+ [C]13_1cc_\bullet, [C]21_2r_\bullet,
+ [C]23_3c_\bullet, [C]14_4
+ }]{4,3,1} \qquad
+ \Diagram[path style={rounded corners},
+ paths={[C]12_1cr_\bullet, [C]14_2c_\bullet,
+ [C]23_3c_\bullet, [C]31_4}]{4,3,1}
+ \end{example}
+
+ The following ribbon tableau comes from a nice paper by
+ Fayers~\cite{Fayers:DyckTilings}, which is uses Dyck tilings to
+ understand homogeneous Garnir relations for KLR algebras of type~$A$.
+
+ \begin{example}
+ \RibbonTableau[skew={1^2}, ukrainian, scale=0.7,
+ ribbons={(draw=none)21_m}
+ ]{
+ 12,16c_\circ c_\circ c_\circ r_\circ r_\circ *r,
+ 18crcccrr*r,19,1{10},1{11},1{12},
+ 22,29crcccrr*rccrcrr,
+ 2{12}ccrcrcccrr*r_lccrcrrr,
+ 31,*32,41,42,51,52,53,
+ 62cr,81,91,{10}1,{10}2,{11}1,{11}2
+ }
+ \end{example}
+
+ The entries of a tableau are usually single characters, or numbers,
+ but they can be more complicated. The paper
+ \cite{bowman2023quiverpresentationsisomorphismshecke} contains
+ tableaux with entries that are \emph{symbols}, which are produced by
+ the \keyword{\Symb} command below.
+
+ \begin{example}
+ \newcommand\Symb[2]{\genfrac{}{}{0pt}{}{#1}{#2}}
+ \Tableau[ukrainian, box font=\scriptsize,
+ tikz after = {\draw[ultra thick, red]
+ (A-2-3.east)--(A-2-2.south)--(A-3-2.west)
+ --(A-3-3.north)--cycle;
+ }]{
+ {\Symb11}{\Symb11}{\Symb11}{\Symb0s},
+ {\Symb11}{\Symb11}{\Symb11}{\Symb0s},
+ {\Symb11}{\Symb11}{\Symb{s^*}s}{\Symb0f},
+ {\Symb11}{\Symb11}{\Symb11},
+ {\Symb11}{\Symb11}
+ }
+ \end{example}
+
+ The next example, also from
+ \cite{bowman2023quiverpresentationsisomorphismshecke}, is a little
+ more involved. Most of the diagram is drawn using \emph{pics} from
+ \TikZ, which are a good way to add repeating features to a
+ \keyword{tikzpicture}. In the code below, \emph{pics} are used to add
+ the up and down strings to this drawing, taking as input the string
+ colour, the starting box, the list of the boxes the strings goes
+ through, and the final box. At the risk of further obfuscation, this
+ could be done a little more efficiently. From the perspective of this
+ manual, the most interesting feature of this picture is that it is a
+ non-trivial example that uses the named nodes for
+ the tableaux boxes; see \autoref{E:NodeNames}.
+
+\begin{Example}[label=Ex:waves]
+\begin{tikzpicture}[
+ Cap/.style={out=45, in=135}, % caps are drawn with to[Cap]
+ Cup/.style={out=315,in=225}, % cups are drawn with to[Cup]
+ every node/.style={font=\scriptsize},
+ redribbon/.style={fill=red!40,opacity=0.4},
+ % define pics for drawing the curvy up and down strings
+ pics/ustring/.style n args = {4}{% {colour}{first coord}{wave coords}{last coord}
+ code = {
+ \def\last{#2} % should not be necessary
+ \draw[thick,#1](T-|#2.north west)node[above=-3.5]{$\vee$}--(#2.north west)
+ foreach [remember=\pt as \last (initially #2)] \pt in {#3}
+ {to[Cup](\last.north east) to[Cap] (\pt.north west)}
+ to[Cup] (#4.north east) -- (#4.north east|-T)node[below=-3.5]{$\wedge$};
+ }
+ },
+ pics/dstring/.style n args = {4}{% {colour}{first coord}{wave coords}{last coord}
+ code = {
+ \def\last{#2} % should not be necessary
+ \draw[thick,#1](O-|#2.south west)node[below=-3.5]{$\wedge$}--(#2.south west)
+ foreach [remember=\pt as \last (initially #2)] \pt in {#3}
+ {to[Cap](\last.south east) to[Cup] (\pt.south west)}
+ to[Cap] (#4.south east) -- (#4.south east|-O)node[above=-3.5]{$\vee$};
+ }
+ },
+ ]
+ \coordinate (O) at (0,0); \coordinate (T) at (0,3.2);
+ \draw(-2,0)--(2.5,0) (-2,3.2)--(2.5,3.2);
+ \Diagram(0,0)[ukrainian, inner style=dotted, ribbons={(redribbon)24rcrcrc}]{5,4^3,3}
+ \pic at (T) {ustring={gray}{A-1-5}{}{A-1-5}}; % up strings
+ \pic at (T) {ustring={gray}{A-4-4}{}{A-4-4}};
+ \pic at (T) {ustring={gray}{A-5-2}{A-4-3,A-3-4}{A-3-4}};
+ \pic at (T) {ustring={gray}{A-5-3}{}{A-5-3}};
+ \pic at (T) {ustring={red}{A-5-1}{A-4-2,A-3-3,A-2-4}{A-2-4}};
+ \pic at (O) {dstring={gray}{A-1-1}{}{A-1-1}}; % down strings
+ \pic at (O) {dstring={gray}{A-2-1}{A-1-2}{A-1-2}};
+ \pic at (O) {dstring={gray}{A-3-1}{A-2-2,A-1-3}{A-1-3}};
+ \pic at (O) {dstring={gray}{A-4-1}{A-3-2,A-2-3,A-1-4}{A-1-4}};
+ \pic at (O) {dstring={gray}{A-5-1}{A-4-2,A-3-3,A-2-4,A-1-5}{A-1-5}};
+\end{tikzpicture}
+\end{Example}
+
+ % --------------------------------------------------------------
+ \section{Summary of \aTableau commands and options}\label{S:keys}
+ \rowcolors{2}{LightSkyBlue!10}{}
+
+ For this impatient, this section compactly lists the \aTableau
+ commands and their options. The sections above show these commands and
+ options are used, with examples.
+
+ The \aTableau package provides the following commands:
+
+ \begin{center}
+ \begin{tabular}{Lll}\toprule
+ \large\sffamily\color{MidnightBlue}Command
+ & \large\sffamily\color{MidnightBlue} Picture
+ & \large\sffamily\color{MidnightBlue} Section \\\midrule
+ Abacus & An abacus for a partition & \autoref{S:Abacus}\\
+ Diagram & A Young diagram for a partition & \autoref{S:Diagram}\\
+ Multidiagram & An $\ell$-tuple of Young diagrams & \autoref{S:Multitableau} \\
+ Multitableau & An $\ell$-tuple of tableaux & \autoref{S:Multitableau} \\
+ RibbonTableau & A ribbon tableau & \autoref{S:RibbonTableaux} \\
+ ShiftedDiagram & A shifted Young diagram & \autoref{S:Shifted} \\
+ ShiftedTableau & A shifted tableau & \autoref{S:Shifted} \\
+ SkewDiagram & A skew Young diagram & \autoref{S:Skew} \\
+ SkewTableau & A skew tableau & \autoref{S:Skew} \\
+ Tableau & A tableau & \autoref{S:Tableau} \\
+ Tabloid & A tabloid & \autoref{S:Tabloid} \\
+ \bottomrule
+ \end{tabular}
+ \end{center}
+
+ In addition, the \keyword{\aTabset} command is provided for setting
+ can default \aTableau values for the \aTableau options.
+
+ For easier reference, here is the list of the \aTableau keys, together
+ with a quick explanation of what they do. The last two columns
+ indicate whether the options apply to tableau (and diagrams), or to
+ abacuses~--- or both! Options starting with \keyword{(no)} are a pair
+ of boolean options and their inverses. If not given a true or false
+ value then they are implicitly set to true. Although not explicitly
+ listed, spelling variations of keys from the American dialect
+ of English are tolerated.
+
+ Both the key names and the green ticks below are hyperlinks to the
+ relevant sections of the manual.
+
+ \newcommand\heading[1]{\textcolor{MidnightBlue}{\textsf{\large#1}}}
+ \rowcolors{2}{LightSkyBlue!10}{}
+ \begin{xltabular}{0.9\textwidth}{l>{\raggedright}Xcc}\toprule
+ \heading{Key} & \heading{Meaning} & \heading{Tableau} & \heading{Abacus} \\
+ \midrule
+ \endhead
+ \option{abacus ends} & Set the top and bottom of the abacus & \No & \Yes\\
+ \option{abacus ends style} & Set the style of the top and bottom of the abacus & \No & \Yes\\
+ \option{align} & Set baseline alignment of \aTableau diagram & \Yes & \Yes[abacus]\\
+ \option{australian} & Use the Australian convention for tableaux & \Yes & \No \\
+ \option{bead} & Set the colour of the abacus beads & \No & \Yes \\
+ \option{bead font} & Set the font used for the abacus bead labels & \No & \Yes \\
+ \option{bead sep} & The distance between adjacent beads on a runner & \No & \Yes \\
+ \option{bead size} & The diameter of the abacus beads & \No & \Yes \\
+ \option{bead style} & Set the style of the abacus beads & \No & \Yes \\
+ \option{bead text} & Set the colour of the abacus bead labels & \No & \Yes \\
+ \option{beta numbers} & Enter bead specification as beta numbers & \No & \Yes \\
+ \option*{border} & Draw the tableau border & \Yes & \No \\
+ \option{border colour} & Set tableau border colour & \Yes & \No \\
+ \option{border style} & Set tableau border style & \Yes & \No \\
+ \option{box height} & Set tableau box height & \Yes & \No \\
+ \option{box style} & Set tableau box style & \Yes & \No \\
+ \option{box width} & Set tableau box width & \Yes & \No \\
+ \option*{boxes} & Draw inner walls around boxes & \Yes & \No \\
+ \option{cartan} & Set Cartan type for residues & \Yes & \Yes[abacus] \\
+ \option{charge} & Set charge for contents and residues & \Yes & \Yes[abacus] \\
+ \option{conjugate} & Draw the conjugate tableau/diagram & \Yes & \No \\
+ \option{e} & Set the quantum characteristic for residues & \Yes & \Yes[abacus] \\
+ \option{east} & Make abacus grow in the easterly direction & \Yes & \No \\
+ \option{delimiters} & Set delimiters for multitableau and multidiagrams & \Yes & \No \\
+ \option{empty} & Symbol for empty tableau in multitableau & \Yes & \No \\
+ \option{dotted cols} & Specify columns to replace with dots & \Yes & \Yes[abacus] \\
+ \option{dotted rows} & Specify rows to replace with dots & \Yes & \Yes[abacus] \\
+ \option{english} & Use the English convention for tableaux & \Yes & \No \\
+ \option{entries} & Add entries to tableaux and abacuses & \Yes & \Yes[abacus] \\
+ \option{french} & Use the French convention for tableaux & \Yes & \No \\
+ \option{halign} & Horizontal alignment of box entries and bead labels & \Yes & \Yes[abacus] \\
+ \option{inner style} & Set style of inner tableau wall & \Yes & \No \\
+ \option{inner wall} & Set colour of inner tableau wall & \Yes & \No \\
+ \option{label} & Set tableau label & \Yes & \No \\
+ \option{label style} & Set style of tableau labels & \Yes & \No \\
+ \option{left delimiter} & Set left delimiter for multitableau & \Yes & \No \\
+ \option{math entries} & Typeset box and label entries in math-mode & \Yes & \Yes[abacus] \\
+ \option{name} & Prefix of named nodes & \Yes & \Yes[abacus] \\
+ \option{north} & Make abacus grow in the northerly direction & \No & \Yes\\
+ \option{paths} & Add paths to a diagram or tableau & \Yes & \No \\
+ \option{path box} & Adds default box entry for each path & \Yes & \No \\
+ \option{path box style} & Sets style of boxes on each path & \Yes & \No \\
+ \option{path style} & Sets style of a path & \Yes & \No \\
+ \option{ribbons} & Add ribbons to tableau & \Yes & \No \\
+ \option{ribbon box} & Adds default box entry for each ribbon & \Yes & \No \\
+ \option{ribbon style} & Set ribbon style & \Yes & \No \\
+ \option{ribbon box style} & Sets style of boxes on each ribbon & \Yes & \No \\
+ \option{right delimiter} & List of labels for the abacus runners & \No & Yes \\
+ \option{rows} & Set number of rows in multitableau or abacus & \Yes & \Yes[abacus] \\
+ \option{runner} & Set runner colour & \No & \Yes \\
+ \option{runner labels} & Set the colour of the abacus runners & \No & \Yes \\
+ \option{runner label style}& Set the style for e abacus labels & \No & \Yes \\
+ \option{runner sep} & Set distance between consecutive abacus runners & \No & \Yes \\
+ \option{runner style} & Set the colour of the abacus runners & \No & \Yes \\
+ \option{scale} & Sets the \aTableau scale & \Yes & \Yes[abacus] \\
+ \option{separation} & Set distance between components in multitableau & \Yes & \No \\
+ \option{separator colour} & Set separator colour for multitableau & \Yes & \No \\
+ \option{separator} & Set separator colour in multitableau & \Yes & \No \\
+ \option*{separators} & Enable separators in multitableau & \Yes & \No \\
+ \option{shifted} & True for a shifted tableau & \Yes & \No \\
+ \option{skew} & Set inner skew shape & \Yes & \No \\
+ \option*{skew border} & Set skew border colour & \Yes & \No \\
+ \option{skew border style} & Set \TikZ-style of the skew border & \Yes & \No \\
+ \option*{skew boxes} & Enable drawing of skew boxes & \Yes & \No \\
+ \option{skew box style} & Set \TikZ-style of the skew boxes & \Yes & \No \\
+ \option{snobs} & add snobs to tableau & \Yes & \No \\
+ \option{snob box} & Adds default box entry for each snob & \Yes & \No \\
+ \option{snob box style} & Sets style of boxes on each snob & \Yes & \No \\
+ \option{snob style} & Sets style of a snob & \Yes & \No \\
+ \option{south} & Make abacus grow in the southerly direction & \Yes & \No \\
+ \option{star style} & Set \TikZ-style of tableau $*$-nodes & \Yes & \No \\
+ \option{styles} & Short-hand for defining single use \TikZ-styles & \Yes & \Yes[abacus] \\
+ \option{tabloid} & True for a shifted tableau & \Yes & \No \\
+ \option{text entries} & Typeset box and label entries in text-mode & \Yes & \Yes[abacus] \\
+ \option{tick} & Set the colour of the ticks on the abacus runner & \No & \Yes \\
+ \option{tick length} & Set the length of the ticks on the abacus runners & \No & \Yes \\
+ \option{tick style} & Set the style of the ticks on the abacus runners & \No & \Yes \\
+ \option{tikz after} & \TikZ-code injected after \aTableau picture & \Yes & \Yes[abacus] \\
+ \option{tikz before} & \TikZ-code injected before \aTableau picture & \Yes & \Yes[abacus] \\
+ \option{tikzpicture} & Sets tikzpicture environment keys & \Yes & \No \\
+ \option{ukrainian} & Use the Ukrainian convention for tableaux & \Yes & \No \\
+ \option{valign} & Set vertical alignment & \Yes & \Yes[abacus] \\
+ \option{west} & Make abacus grow in the westerly direction & \Yes & \No \\
+ \option{xoffsets} & Set $x$-offsets for components in a multitableau & \Yes & \No \\
+ \option{xscale} & Set \aTableau $x$-scale & \Yes & \Yes[abacus] \\
+ \option{yoffsets} & Set $y$-offsets for components in a multitableau & \Yes & \No \\
+ \option{yscale} & Set \aTableau $y$-scale & \Yes & \Yes[abacus] \\
+ \bottomrule
+ \end{xltabular}
+
+ \emph{Most readers should ignore the following two subsections.}
+
+ % --------------------------------------------------------------
+ \subsection{\aTableau Colours}\label{S:Colours}
+
+ The \aTableau package defines and uses the following colours:
+
+ \rowcolors{2}{LightSkyBlue!10}{}
+ \begin{center}
+ \begin{tabular}{lll}\toprule
+ \heading{Colour} & \heading{Name} & \heading{HTML}\\
+ \midrule
+ \aTableauColour{Inner} & aTableauInner & 0073E6 \\
+ \aTableauColour{Main} & aTableauMain & 00008B \\
+ \aTableauColour{SkewFill} & aTableauSkewFill & F8F8F8 \\
+ \aTableauColour{Skew} & aTableauSkew & 818589 \\
+ \aTableauColour{StarStyle} & aTableauStarStyle & E6F7FF \\
+ \bottomrule
+ \end{tabular}
+ \end{center}
+
+ All of these colours are defined as HTML colours using the
+ \keyword{\definecolor} command provided by \ctan{xcolor}.
+
+ We recommend using the key-value interface to change the
+ colours used in the pictures created by \aTableau, rather than
+ changing these colours. It is sometimes useful to be able to use these
+ colour names directly in your own styles.
+
+ % --------------------------------------------------------------
+ \subsection{\aTableau styles}\label{S:TikZStyles}
+
+ This package is little than a glorified interface to some \TikZ
+ commands. Under the hood there are many custom \TikZ styles that control the
+ pictures drawn by the \aTableau package. It is possible, and sometimes
+ useful (see, for example, \autoref{Ex:DottedAbacus}), to use these
+ styles in your own drawings.
+ The key-value interface to the \aTableau commands is the recommended
+ way of changing these styles. You can, if you want, change these
+ styles directly using \keyword{\tikzset}, but there is a risk that you
+ may break some of the \aTableau commands if you do this. If you do
+ change these styles, we strongly recommend that you \emph{append} to
+ these styles rather than setting them directly.
+
+ \begin{center}
+ \begin{xltabular}{0.9\textwidth}{ll}\toprule
+ \heading{Names} & \heading{Adds \TikZ-styling to...}\\
+ \midrule
+ aTableau/innerWall & Inner tableau walls\\
+ aTableau/borderStyle & Tableau borders \\
+ aTableau/skewBorder & Skew tableau borders \\
+ aTableau/boxStyle & Tableau boxes\\
+ aTableau/skewBox & Skew tableau boxes \\
+ aTableau/pathBox & Boxes on paths \\
+ aTableau/ribbonBox & Boxes on ribbons \\
+ aTableau/snobBox & Boxes on snobs \\
+ aTableau/pathStyle & Paths \\
+ aTableau/ribbonStyle & Ribbons \\
+ aTableau/snobStyle & Snobs \\
+ aTableau/labelStyle & Tableau labels \\
+ aTableau/tableauStarStyle & Star style for tableaux \\
+ aTableau/clearBoxes & Erase material. Used by \option{dotted rows} and \option{dotted cols}\\
+ aTableau/dottedLine & Adds dotted lines. Used by \option{dotted rows} and \option{dotted cols}\\
+ aTableau/separatorSymbol & Separators in multitableau\\
+ aTableau/separatorLine & Separator lines in multitableau\\
+ aTableau/leftDelimiter & Left delimiter in multitableau\\
+ aTableau/rightDelimiter & Right delimiter in multitableau\\
+ aTableau/beadStyle & Abacus beads\\
+ aTableau/runnerStyle & Abacus runners\\
+ aTableau/runnerLabelStyle & Style of abacus runner labels\\
+ aTableau/abacusEnds & Tops and bottoms of abacuses\\
+ aTableau/abacusStarStyle & Abacus stars \\
+ aTableau/tickStyle & Abacus ticks \\
+ \bottomrule
+ \end{xltabular}
+ \end{center}
+
+ Most of these styles are quite basic, but some of them are more
+ involved, which is why we recommend not changing them directly. In
+ some cases, such as the tableau boxes, the \TikZ styling does not
+ fully control the rendering of these features. Most of these styles
+ can be augmented by styles supplied by the key-value interface, which
+ is another reason to avoid changing them directly.
+
+ % --------------------------------------------------------------
+ \section{Feature requests and bug reports}
+
+ Please make any feature requests and bug reports on the package github
+ page
+ \begin{center}
+ \href{https://github.com/AndrewMathas/aTableau/}{github.com/AndrewMathas/aTableau/}.
+ \end{center}
+ Please give as much detail as possible when making such requests.
+
+ Bug reports must be a accompanied by a \textit{minimal working
+ example}, which is the smallest possible amount of \LaTeX\ code that
+ demonstrates the problem and compiles, unless you are reporting a
+ problem that gives a compilation error in which case your example
+ should give the error. This is necessary because if I cannot reproduce
+ your problem, then it is unlikely that I will be able to fix it.
+
+
+% ----------------------------------------------------------------------
+% bibliography
+% \bibliography{papers}
+% \bibliographystyle{andrew}
+
+\begin{thebibliography}{10}
+
+\bibitem{bowman2023quiverpresentationsisomorphismshecke}
+\textsc{C.~Bowman, M.~D. Visscher, A.~Hazi, and C.~Stroppel},
+ \href{https://arxiv.org/abs/2309.13695}{\textit{Quiver presentations and
+ isomorphisms of Hecke categories and Khovanov arc algebras}}, 2023.
+\newblock \href{http://arxiv.org/abs/2309.13695}{arXiv:2309.13695}.
+
+\bibitem{DJM:cyc}
+\textsc{R.~Dipper, G.~James, and A.~Mathas},
+ \href{http://dx.doi.org/10.1007/PL00004665}{\textit{Cyclotomic {$q$}-{S}chur
+ algebras}}, Math. Z., \textbf{229} (1998), 385--416.
+
+\bibitem{EvseevMathas:DeformedKLR}
+\textsc{A.~Evseev and A.~Mathas},
+ \href{http://dx.doi.org/10.5802/art.8}{\textit{Content systems and
+ deformations of cyclotomic {KLR} algebras of type~$A$ and~$C$}}, Annals of
+ Representation Theory, \textbf{1} (2024), 193--297.
+\newblock \href{http://arxiv.org/abs/2209.00134}{arXiv:2209.00134}.
+
+\bibitem{Fayers:DyckTilings}
+\textsc{M.~Fayers}, \textit{Dyck tilings and the homogeneous Garnir relations
+ for graded Specht modules}, 2013, preprint.
+\newblock \href{http://arxiv.org/abs/1309.6467}{arXiv:1309.6467}.
+
+\bibitem{James:YoungD}
+\textsc{G.~James}, \textit{Some combinatorial results involving {Y}oung
+ diagrams}, Math. Proc. Cambridge Philos. Soc., \textbf{83} (1978), 1--10.
+
+\bibitem{KMR:UniversalSpecht}
+\textsc{A.~Kleshchev, A.~Mathas, and A.~Ram},
+ \href{http://dx.doi.org/10.1112/plms/pds019}{\textit{Universal graded
+ {S}pecht modules for cyclotomic {H}ecke algebras}}, Proc. Lond. Math. Soc.
+ (3), \textbf{105} (2012), 1245--1289.
+\newblock \href{http://arxiv.org/abs/1102.3519}{arXiv:1102.3519}.
+
+\bibitem{Konvalinka:ShiftedHookLengths}
+\textsc{M.~z. Konvalinka}, \href{http://dx.doi.org/10.37236/588}{\textit{The
+ weighted hook length formula {III}: {S}hifted tableaux}}, Electron. J.
+ Combin., \textbf{18} (2011), Paper 101, 29.
+
+\bibitem{Macdonald}
+\textsc{I.~G. Macdonald}, \textit{Symmetric functions and {H}all polynomials},
+ Oxford Mathematical Monographs, The Clarendon Press Oxford University Press,
+ New York, second~ed., 1995.
+\newblock With contributions by A. Zelevinsky, Oxford Science Publications.
+
+\bibitem{Mathas:ULect}
+\textsc{A.~Mathas},
+ \href{http://dx.doi.org/10.1090/ulect/015}{\textit{Iwahori-{H}ecke algebras
+ and {S}chur algebras of the symmetric group}}, University Lecture Series,
+ \textbf{15}, American Mathematical Society, Providence, RI, 1999.
+
+\bibitem{Mendes:hooks}
+\textsc{A.~Mendes}, \textit{The combinatorics of rim hook tableaux}, Australas.
+ J. Combin., \textbf{73} (2019), 132--148.
+
+\end{thebibliography}
+
+% ----------------------------------------------------------------------
+% indices
+\printindex
+
+\end{document}
diff --git a/macros/latex/contrib/keytheorems/CHANGELOG.md b/macros/latex/contrib/keytheorems/CHANGELOG.md
index 4050d96127..079b2bf542 100644
--- a/macros/latex/contrib/keytheorems/CHANGELOG.md
+++ b/macros/latex/contrib/keytheorems/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog for keytheorems package
+## [v0.2.4]
+- fixed issue with too much expansion in `manual-num`
+- fix [\#14](https://github.com/mbertucci47/keytheorems/issues/14)
+
## [v0.2.3]
- add many translations; some missing translation of "continuing from p."
- add `manual-num` key
@@ -58,6 +62,7 @@
## 0.1.0 - 2024-09-04
- First release
+[v0.2.4]: https://github.com/mbertucci47/keytheorems/compare/v0.2.3...v0.2.4
[v0.2.3]: https://github.com/mbertucci47/keytheorems/compare/v0.2.2...v0.2.3
[v0.2.2]: https://github.com/mbertucci47/keytheorems/compare/v0.2.1...v0.2.2
[v0.2.1]: https://github.com/mbertucci47/keytheorems/compare/v0.1.8...v0.2.1
diff --git a/macros/latex/contrib/keytheorems/README.md b/macros/latex/contrib/keytheorems/README.md
index 3e5d59a9c9..73b15c13da 100644
--- a/macros/latex/contrib/keytheorems/README.md
+++ b/macros/latex/contrib/keytheorems/README.md
@@ -640,10 +640,5 @@ blub
\end{document}
```
-## Things to do
-
-- Clean up the code. Things are out of order, poorly named, etc.
-- For a complete list, see [`keytheorems-ideas.md`](https://github.com/mbertucci47/keytheorems/blob/develop/keytheorems-ideas.md)
-
## License
Released under the LaTeX Project Public License v1.3c or later. See https://www.latex-project.org/lppl.txt. \ No newline at end of file
diff --git a/macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdf b/macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdf
index 5eb96e99bd..3b107f6a1e 100644
--- a/macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdf
+++ b/macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/keytheorems/doc/keytheorems-doc.tex b/macros/latex/contrib/keytheorems/doc/keytheorems-doc.tex
index 9008b4300c..8edfc37667 100644
--- a/macros/latex/contrib/keytheorems/doc/keytheorems-doc.tex
+++ b/macros/latex/contrib/keytheorems/doc/keytheorems-doc.tex
@@ -148,6 +148,7 @@
colbacklower=ExampleBackLower,
breakable,
parbox=false, % so examples match document with indent, etc.
+ minted options app={breaksymbolleft={}},
#1
}
\newtcolorbox{notebox}[1][]{enhanced,
@@ -305,7 +306,7 @@ All \meta{options} are described in subsections \ref{thm-thmtools-keys} and \ref
\begin{keythmscode}[withpreamble]
\begin{theorem}
-Some text
+There are infinitely many prime numbers.
\end{theorem}
\end{keythmscode}
@@ -327,8 +328,8 @@ Sometimes a package or class defines theorems that need to be overwritten by the
As in \pkg{amsthm}, theorems can take an optional argument that contains a note or heading.
\begin{keythmscode}[]
-\begin{theorem}[some heading]
-Some text
+\begin{theorem}[Bertrand's postulate]
+For every $n\geq 1$, there is a prime number $p$ with $n<p\leq 2n$.
\end{theorem}
\end{keythmscode}
@@ -342,8 +343,10 @@ This is the key-value equivalent of the optional argument described above.
This syntax, however, allows the argument to contain other keys.
\begin{keythmscode}[]
-\begin{theorem}[note=another heading]
-Some more text
+\begin{theorem}[note=Legendre's formula]
+The number $n!$ contains the prime factor $p$ exactly
+ \[ \sum_{k\geq 1} \Bigl\lfloor\frac{n}{p^k}\Bigr\rfloor \]
+times.
\end{theorem}
\end{keythmscode}
@@ -362,10 +365,10 @@ This replaces the value of \refKey{note} when displayed in the list of theorems
This is the key-value equivalent of |\begin{theorem}| \cs{label}\marg{label name}.
\begin{keythmscode}[]
-\begin{theorem}[label=foo]
-Some text
+\begin{theorem}[label=bezout]
+Let $a$ and $b$ be integers. Then there exist integers $x$ and $y$ such that $ax+by=\gcd(a,b)$.
\end{theorem}
-\ref{foo}
+See \zcref{bezout}.
\end{keythmscode}
\end{docKey}
@@ -377,8 +380,8 @@ Use this to override the printed number of a theorem.
It is useful for making ``starred'' versions of other theorems, perhaps to represent a reformulated or more difficult version.
\begin{keythmscode}[]
-\begin{theorem}[manual-num=\ref*{foo}*]
-A reformulated version of \zcref[S]{foo}.
+\begin{theorem}[manual-num=\ref*{bezout}*]
+Let $a_1,\dots,a_n$ be integers. Then there exist integers $x_1,\dots,x_n$ such that $a_1x_1+\dots+a_nx_n=\gcd(a_1,\dots,a_n)$.
\end{theorem}
\begin{theorem}[manual-num=\faRocket] % requires fontawesome5
Don't confuse your readers by changing the numbering without good reason.
@@ -395,8 +398,8 @@ The printed text can be customized with the \refKey{continues-code} option.
The starred version also copies the theorem note, if it exists.
\begin{keythmscode}[]
-\begin{theorem}[continues=foo]
-\dots and some more text.
+\begin{theorem}[continues=bezout]
+Moreover, the integers of the form $az+bt$ are exactly the multiples of $\gcd(a,b)$.
\end{theorem}
\end{keythmscode}
@@ -428,15 +431,16 @@ The latter issue can be averted with the \texttt{ampersand-replacement} key.
\end{codepreamble}
\begin{keythmscode}[withpreamble]
-\begin{lemma}[store=diagram]
-Some commutative diagram:
+\begin{lemma}[store=fiberprod]
+For any $S$-schemes $X$ and $Y$, there exists a scheme $X\times_S Y$ with morphisms to $X$ and $Y$ such that the diagram
\[\begin{tikzcd}[ampersand replacement=\&]
X\times_S Y \ar[r] \ar[d] \& X \ar[d] \\
Y \ar[r] \& S
-\end{tikzcd}\]
+ \end{tikzcd}\]
+commutes and is universal with respect to this property.
\end{lemma}
\dots
-\getkeytheorem{diagram}
+\getkeytheorem{fiberprod}
\end{keythmscode}
\end{docKey}
@@ -451,7 +455,8 @@ At the moment this is only useful with the \refKey{note} key.
\begin{theorem}[
store=rktest,
note=ORIGINAL,
- restate-keys={note=RESTATED}]
+ restate-keys={note=RESTATED}
+ ]
Wow, yet another theorem.
\end{theorem}
\getkeytheorem{rktest}
@@ -474,12 +479,14 @@ Compare:
\begin{observation}
\begin{enumerate}
\item First item
+\item Second item
\end{enumerate}
\end{observation}
\begin{observation}[listhack=true]
\begin{enumerate}
\item First item
+\item Second item
\end{enumerate}
\end{observation}
\end{keythmscode}
@@ -577,7 +584,7 @@ Accepts any \meta{style name} defined by \refCom{newkeytheoremstyle}, as well as
\begin{keythmscode}[withpreamble]
\begin{remark}
-Some text
+It's nice to distinguish remarks from definitions and theorems.
\end{remark}
\end{keythmscode}
@@ -601,7 +608,7 @@ Details in \autoref{keythms-hooks}.
postheadhook=POSTHEAD,
prefoothook=PREFOOT,
postfoothook=POSTFOOT
-]
+ ]
\end{codepreamble}
\begin{keythmscode}[withpreamble]
@@ -625,10 +632,10 @@ If no value is given, the symbol \qedsymbol{} is used.
\begin{keythmscode}[withpreamble]
\begin{example}
-Some text
+Some text.
\end{example}
\begin{solution}
-Some more text
+Some more text.
\end{solution}
\end{keythmscode}
@@ -658,14 +665,12 @@ As with \cs{autoref}, there is also a starred version \docAuxCommand{Autoref*} t
\begin{keythmscode}[withpreamble]
\begin{prop}[label=abc]
-Some text
+Some text.
\end{prop}
\begin{prop}[label=def]
-Some more text
+Some more text.
\end{prop}
-\begin{theorem}
Consider \zcref{abc,def}. \Autoref{abc} \dots
-\end{theorem}
\end{keythmscode}
\end{docKey}
@@ -736,10 +741,10 @@ The theorem head is typeset as a tcolorbox title; to avoid this see \refKey{tcol
\begin{keythmscode}[withpreamble]
\begin{corollary}
-Some text
+Some text.
\end{corollary}
\begin{definition}[A nice definition]
-Some more text
+Some more text.
\end{definition}
\end{keythmscode}
@@ -759,7 +764,7 @@ Same usage as \refKey{tcolorbox} but the theorem head is typeset as usual, not a
\begin{keythmscode}[withpreamble]
\begin{boxcor}
-Some text
+Some text.
\end{boxcor}
\end{keythmscode}
@@ -783,12 +788,13 @@ Some text
}
\newkeytheorem{mytheo}[
name=My Theorem,
- style=tcb-standard]
+ style=tcb-standard
+ ]
\end{codepreamble}
\begin{keythmscode}[withpreamble]
\begin{mytheo}[This is my title]
-Some theorem text
+Some theorem text.
\end{mytheo}
\end{keythmscode}
@@ -952,9 +958,7 @@ Executes \meta{true code} if being retrieved with \refCom{getkeytheorem} and \me
\begin{keythmscode}[]
\begin{example}[store=hmm]
-I am the
-\IfRestatingTF{restated}{original}
-example!
+I am the \IfRestatingTF{restated}{original} example!
\end{example}
\getkeytheorem{hmm}
@@ -1263,7 +1267,6 @@ An example invocation might look like
\end{dispListing}
At a minimum, the |testphase| modules |phase-III| and |firstaid| are required.
-The GitHub tests folder contains an example of a tagged PDF using \pkg{keytheorems}: \href{https://github.com/mbertucci47/keytheorems/blob/develop/tests/tagged-keytheorems-amsthmtest.tex}{\texttt{tagged-keytheorems-amsthmtest.tex}}.
\subsection{Public coding interfaces}
@@ -1289,7 +1292,7 @@ They can be useful with \cs{AddToHookNext} or the kernel's label mechanism for h
\section{Further examples}
More examples will be added soon -- rather, eventually\dots{}
-For now, you can find a \pkg{keytheorems} adaptation of \pkg{amsthm}'s classic file \href{https://mirrors.ctan.org/macros/latex/required/amscls/doc/thmtest.tex}{\texttt{thmtest.tex}} in the Github \texttt{tests} folder: \href{https://github.com/mbertucci47/keytheorems/blob/develop/tests/keytheorems-amsthmtest.tex}{\texttt{keytheorems-amsthmtest.tex}}.
+For now, you can find a \pkg{keytheorems} adaptation of \pkg{amsthm}'s classic \href{https://mirrors.ctan.org/macros/latex/required/amscls/doc/thmtest.tex}{\texttt{thmtest.tex}} in the Github \texttt{tests} folder: \href{https://github.com/mbertucci47/keytheorems/blob/develop/tests/keytheorems-amsthmtest.tex}{\texttt{keytheorems-amsthmtest.tex}}. There is also a version for tagged PDF: \href{https://github.com/mbertucci47/keytheorems/blob/develop/tests/tagged-keytheorems-amsthmtest.tex}{\texttt{tagged-keytheorems-amsthmtest.tex}}.
%\section{Implementation}
%\inputminted[linenos,style=bw]{latex}{../keytheorems.sty}
diff --git a/macros/latex/contrib/keytheorems/tex/class-support/keythms-beamer-support.tex b/macros/latex/contrib/keytheorems/tex/class-support/keythms-beamer-support.tex
index a767068565..8aef1cab3f 100644
--- a/macros/latex/contrib/keytheorems/tex/class-support/keythms-beamer-support.tex
+++ b/macros/latex/contrib/keytheorems/tex/class-support/keythms-beamer-support.tex
@@ -253,10 +253,10 @@
\cs_new:cpe
{ __keythms_getthm_ \l__keythms_thmuse_store_tl _body }
{
- \exp_not:N \__keythms_getthm_body:nn
+ \exp_not:N \__keythms_getthm_body:nnn
\exp_args:No \exp_not:o
{
- \exp_after:wN \__keythms_use_iii_v_braced:nnnnn
+ \exp_after:wN \__keythms_use_i_iii_v_braced:nnnnn
\g__keythms_thmuse_temprestatedata_tl
}
}
diff --git a/macros/latex/contrib/keytheorems/tex/keytheorems.sty b/macros/latex/contrib/keytheorems/tex/keytheorems.sty
index efc25150be..4f1d145935 100644
--- a/macros/latex/contrib/keytheorems/tex/keytheorems.sty
+++ b/macros/latex/contrib/keytheorems/tex/keytheorems.sty
@@ -2,8 +2,8 @@
% Please report all issues and feature requests at https://github.com/mbertucci47/keytheorems
% This work is licensed under the LPPL version 1.3c or later: https://www.latex-project.org/lppl.txt
\NeedsTeXFormat{LaTeX2e}[2023-06-01]
-\def\@keythms@date{2025-01-07}
-\def\@keythms@version{0.2.3}
+\def\@keythms@date{2025-01-21}
+\def\@keythms@version{0.2.4}
\ProvidesExplPackage{keytheorems}{\@keythms@date}{\@keythms@version}
{l3keys interface to amsthm}
@@ -1212,10 +1212,10 @@
\cs_new:cpe
{ __keythms_getthm_ \l__keythms_thmuse_store_tl _body }
{
- \exp_not:N \__keythms_getthm_body:nn
+ \exp_not:N \__keythms_getthm_body:nnn
\exp_args:No \exp_not:o
{
- \exp_after:wN \__keythms_use_iii_v_braced:nnnnn
+ \exp_after:wN \__keythms_use_i_iii_v_braced:nnnnn
\g__keythms_thmuse_temprestatedata_tl
}
}
@@ -1243,7 +1243,7 @@
}
}
}
-\cs_new:Npn \__keythms_use_iii_v_braced:nnnnn #1#2#3#4#5 { {#3}{#5} }
+\cs_new:Npn \__keythms_use_i_iii_v_braced:nnnnn #1#2#3#4#5 { {#1}{#3}{#5} }
% withhooks_begin does not include prehead hook because we want to be able to access note
\cs_new_protected:Npn \__keythms_withhooks_begin:nnn #1#2#3
@@ -1300,7 +1300,10 @@
}
\tl_if_empty:NF \l__keythms_thmuse_manualnum_tl
{
- \cs_set:cpn { the #1 } { \l__keythms_thmuse_manualnum_tl }
+ \cs_set:cpn { the #1 }
+ { % prevent expansion for unexpandable tokens in \the<counter>
+ \exp_not:N \exp_not:n { \l__keythms_thmuse_manualnum_tl }
+ }
\cs_set_eq:cN { c@ #1 } \c@keythms_manualnum_dummyctr
\cs_set_eq:cN { theH #1 } \theHkeythms_manualnum_dummyctr
}
@@ -1398,11 +1401,11 @@
\keys_define:nn { keytheorems/storeatbegin }
{
- restate .meta:n = { store = {#1} },
- restate* .meta:n = { store* = {#1} },
- store .tl_set:N = \l__keythms_storeatbegin_store_tl,
- store* .tl_set:N = \l__keythms_storeatbegin_storereversed_tl,
- unknown .code:n = { } % do nothing with unknown keys
+ restate .meta:n = { store = {#1} },
+ restate* .meta:n = { store* = {#1} },
+ store .tl_set:N = \l__keythms_storeatbegin_store_tl,
+ store* .tl_set:N = \l__keythms_storeatbegin_storereversed_tl,
+ unknown .code:n = { } % do nothing with unknown keys
}
\cs_new_protected:Npn \KeyThmsContentsLine #1 { }
@@ -1444,7 +1447,7 @@
\cs_new_protected:cpn
{ __keythms_getthm_ \l__keythms_storeatbegin_store_tl _body }
{
- \__keythms_getthm_body:nn {#5}{#7}
+ \__keythms_getthm_body:nnn {#1}{#5}{#7}
}
}
\tl_if_empty:NF \l__keythms_storeatbegin_storereversed_tl
@@ -1458,7 +1461,7 @@
\cs_new_protected:cpn
{ __keythms_getthm_ \l__keythms_storeatbegin_storereversed_tl _body }
{
- \__keythms_getthm_body:nn {#5}{#7}
+ \__keythms_getthm_body:nnn {#1}{#5}{#7}
}
}
\group_end:
@@ -1549,11 +1552,11 @@
\group_end:
}
-\cs_new_protected:Npn \__keythms_getthm_body:nn #1#2
- { % #1 = restate counters, #2 = theorem body
+\cs_new_protected:Npn \__keythms_getthm_body:nnn #1#2#3
+ { % #1 = name, #2 = restate counters, #3 = theorem body
\group_begin:
\bool_set_true:N \l__keythms_thmuse_restating_bool
- \prop_set_from_keyval:Nn \l__keythms_restate_counters_prop { #1 }
+ \prop_set_from_keyval:Nn \l__keythms_restate_counters_prop { #2 }
\prop_map_inline:Nn \l__keythms_restate_counters_prop
{
\tl_set:ce { l_keythms_restate_current_##1_tl } { \the\value{##1} }
@@ -1565,9 +1568,9 @@
{ \use:c { the ##1 } . \theHkeythms_restate_dummyctr }
}
\refstepcounter{keythms_restate_dummyctr}
- % \hook_use:n { keytheorems/#1/restated } % FIX!
+ \hook_use:n { keytheorems/#1/restated }
\hook_use:n { keytheorems/allthms/restated }
- #2
+ #3
\prop_map_inline:Nn \l__keythms_restate_counters_prop
{
\exp_args:Nnc \setcounter { ##1 }
@@ -1606,10 +1609,10 @@
\cs_new:cpe
{ __keythms_getthm_ \l__keythms_thmuse_storereversed_tl _body }
{
- \exp_not:N \__keythms_getthm_body:nn
+ \exp_not:N \__keythms_getthm_body:nnn
\exp_args:No \exp_not:o
{
- \exp_after:wN \__keythms_use_iii_v_braced:nnnnn
+ \exp_after:wN \__keythms_use_i_iii_v_braced:nnnnn
\g__keythms_thmuse_temprestatedata_tl
}
}