diff options
Diffstat (limited to 'macros/latex')
-rw-r--r-- | macros/latex/contrib/atableau/LICENSE | 401 | ||||
-rw-r--r-- | macros/latex/contrib/atableau/README.md | 45 | ||||
-rw-r--r-- | macros/latex/contrib/atableau/atableau.ini | 13 | ||||
-rw-r--r-- | macros/latex/contrib/atableau/atableau.pdf | bin | 0 -> 840926 bytes | |||
-rw-r--r-- | macros/latex/contrib/atableau/atableau.sty | 3335 | ||||
-rw-r--r-- | macros/latex/contrib/atableau/atableau.tex | 4359 | ||||
-rw-r--r-- | macros/latex/contrib/keytheorems/CHANGELOG.md | 5 | ||||
-rw-r--r-- | macros/latex/contrib/keytheorems/README.md | 5 | ||||
-rw-r--r-- | macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdf | bin | 169165 -> 175459 bytes | |||
-rw-r--r-- | macros/latex/contrib/keytheorems/doc/keytheorems-doc.tex | 73 | ||||
-rw-r--r-- | macros/latex/contrib/keytheorems/tex/class-support/keythms-beamer-support.tex | 4 | ||||
-rw-r--r-- | macros/latex/contrib/keytheorems/tex/keytheorems.sty | 43 |
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 Binary files differnew file mode 100644 index 0000000000..d819e18d33 --- /dev/null +++ b/macros/latex/contrib/atableau/atableau.pdf 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 Binary files differindex 5eb96e99bd..3b107f6a1e 100644 --- a/macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdf +++ b/macros/latex/contrib/keytheorems/doc/keytheorems-doc.pdf 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 } } |