summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/keyvaltable/keyvaltable.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/keyvaltable/keyvaltable.dtx')
-rw-r--r--macros/latex/contrib/keyvaltable/keyvaltable.dtx1074
1 files changed, 730 insertions, 344 deletions
diff --git a/macros/latex/contrib/keyvaltable/keyvaltable.dtx b/macros/latex/contrib/keyvaltable/keyvaltable.dtx
index 813904fb23..f68b0bf67c 100644
--- a/macros/latex/contrib/keyvaltable/keyvaltable.dtx
+++ b/macros/latex/contrib/keyvaltable/keyvaltable.dtx
@@ -22,7 +22,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{keyvaltable}
%<*package>
- [2020/02/19 v2.1 Package for filling tables using key-value lists]
+ [2020/04/05 v2.2 Package for filling tables using key-value lists]
%</package>
%
%<*driver>
@@ -47,7 +47,7 @@
showhead=false,headformat={\bfseries\footnotesize},
rowbg=black!7!white..black!3!white,
showrules=false,
- shape=tabu]{GoalApproach}{
+ backend=tabu]{GoalApproach}{
id: align=r, default=(\alph{kvtRow}), head=\#;
goal: align=X[l];
approach: align={X[2,l]};
@@ -223,7 +223,10 @@ cherries,50g,cherries,heat up and add to bowl
% \NiceDescribeKey{align}{vals={l,c,r,p,X,\ldots}, init=l}
% This property specifies the alignment of content in the
% column. The \meta{value} can be set to any column alignment
-% understood by table environments.
+% understood by table environments.\footnote{More complex values, for
+% instance using the notation of the \pkgname{array} package for
+% inserting material before or after a column, are permitted but not
+% further tested. Use at your own risk.}
%
% \NiceDescribeKey{default}{vals=\vmeta{content}, init=\vmeta{empty}}
% This property specifies the default \meta{content} of a cell in this
@@ -497,6 +500,14 @@ cherries,50g,cherries,heat up and add to bowl
% \end{KeyValTable}
% \end{LTXexample}
%
+% By default, all counters start at value $1$. Through the following
+% possibilities, this behavior can be changed.
+%
+% \NiceDescribeKey{resume}{vals={true,false}, init=false, def=true}\label{opt:resume}
+% This option is available in |KeyValTable| environments. When this
+% option is set to |true|, the value of the |kvtRow| counter is resumed
+% from the previous |KeyValTable| environment. The other two counters
+% are not affected by this option.
%
% \subsection{Row Labeling}
%
@@ -608,27 +619,33 @@ cherries,50g,cherries,heat up and add to bowl
% list of \meta{property}|=|\meta{value} pairs.
% The following \meta{property} keys can be configured.
%
-% \NiceDescribeKey{shape}
-% {vals={multipage,onepage,tabular,tabularx,longtable,xltabular,tabu,longtabu},
-% init=multipage}
-% This property specifies the table's shape. For \meta{value}, the
-% package currently supports |multipage| and |onepage| as well as
-% |tabular|, |tabularx|, |longtable|, |xltabular|, |tabu|, and
-% |longtabu|. In case of |multipage|, the table may span multiple pages
-% and on each page, the column header is repeated. In case of |onepage|,
-% the table does not split into multiple pages. The remaining values
-% use the respective environment for producing the table (see
-% \cref{sec:AltTabEnv} for the effect).
+% \NiceDescribeKeys{2}
+% {backend}{vals={tabular,tabularx,longtable,xltabular,tabu,longtabu}}
+% {shape}{vals={multipage,onepage}, init=multipage}
+% The |backend| property specifies the table environment to be used for
+% producing the table. A set of six environments is currently supported,
+% including environments that can span multiple pages and environments
+% whose columns can stretch/shrink to fill the available space ("|X|"
+% columns).
+% The |shape| property abstracts from the concrete environments.
+% In case of |multipage|, the table may span multiple pages and
+% depending on whether |X|-columns are used or not, an appropriate
+% environment is selected. In case of |onepage|, the table does not
+% split into multiple pages.
+% See \cref{sec:AltTabEnv} for more details on the available shapes and
+% backends.
+% Only one of |shape| and |backend| can be specified. If both are
+% specified, the property that is specified last wins.
%
% \NiceDescribeKey{width}{vals=\vmeta{dimension}, init=\cmd\linewidth}
% This property specifies the width of the table, if the selected
-% |shape| supports it (see \cref{sec:AltTabEnv}).
+% |shape|/|backend| supports it (see \cref{sec:AltTabEnv}).
%
% \NiceDescribeKeys{2}
% {valign}{vals={t,c,b}, init=\vmeta{empty}}
% {halign}{vals={l,c,r}, init=\vmeta{empty}}
% These two properties specify the vertical and, respectively, horizontal
-% alignment of the table, if the selected |shape| supports it (see
+% alignment of the table, if the selected |shape|/|backend| supports it (see
% \cref{sec:AltTabEnv}).
%
% \NiceDescribeKey{showhead}{vals={true,false}, init=true}
@@ -733,6 +750,58 @@ cherries,50g,cherries,heat up and add to bowl
% \label{fig:TableOptionExamples}
% \end{figure}
%
+% \subsubsection{Table Styles and Resumable Options}
+%
+% Rather than specifying properties for individual tables or table
+% types, \thispackage also supports named \emph{table styles}.
+%
+% \NiceDescribeKey{style}{vals=\vmeta{list of style names}, init=\vmeta{empty}}
+% Through this property of tables or table types, a list of styles can
+% be applied to a single table or, respectively, a table type. Each
+% style must have been defined with |\kvtNewTableStyle| before.
+%
+% \NiceDescribeMacro{\kvtNewTableStyle}{\marg{name}\marg{options}}
+% This macro declares a new table style with the given \meta{name} and
+% defines it to be equivalent to using the given \meta{options}.
+% The \meta{name} must not already be defined.
+%
+% \NiceDescribeMacro{\kvtRenewTableStyle}{\marg{name}\marg{options}}
+% This macro re-defines an existing table style \meta{name} with new
+% \meta{options}.
+%
+% The following example demonstrates table styles for an individual
+% table.
+%
+% \begin{LTXexample}[morepreset=\RecipePreset,morekeywords={style,kvtNewTableStyle}]
+% \kvtNewTableStyle{plain}{
+% norules,nobg,headformat=\textbf}
+% \begin{KeyValTable}[style=plain]{Recipe}
+% \Row{amount=150g, ingredient=ice cream,
+% step=put into bowl}
+% \Row{amount= 50g, ingredient=cherries,
+% step=heat up and add to bowl}
+% \end{KeyValTable}
+% \end{LTXexample}
+%
+% \NiceNote{The \meta{options} in |\kvtNewTableStyle| can be left empty.
+% In this case, the table style does not have any effect on the appearance
+% of tables. However, the style can already be used for "tagging" tables
+% and table types, while the final options for the style can be
+% configured at a later point in time.}
+%
+% Even without table styles, the appearance of the previous
+% |KeyValTable| can be used again through the following option.
+% \NiceDescribeKey{resume*}{vals={true,false}, init=false, def=true}
+% When set to |true|, this option makes the table use the options from
+% the previous |KeyValTable| environment. This option also implies the
+% |resume| option (see \vref{opt:resume}).
+
+% If the previous environment also used |resume*|, then the options of
+% its predecessor environment are used, and so forth.
+% Note that this means that table options are not accumulated over
+% subsequent uses of |resume*|.
+% This behavior is the same as in the \pkgname{enumitem} package.
+%
%
% \subsection{Column Appearance}
%
@@ -1116,11 +1185,11 @@ cherries,50g,cherries,heat up and add to bowl
%
% \subsection{Captions}
%
-% There are two ways to add captions to (\pkgname{keyvaltable}-) tables:
+% There are two ways to add captions to \pkgname{keyvaltable} tables:
% The first way is to enclose the table in a |table| environment. This
% is particularly suit for tables that do not span multiple pages, such
-% as those produced through the |onepage| shape (or |tabular|,
-% |tabularx|, and |tabu| -- see \cref{sec:AltTabEnv}).
+% as those produced through the |onepage| shape or the backends
+% |tabular|, |tabularx|, and |tabu| (see \cref{sec:AltTabEnv}).
%
% \begin{LTXexample}[morepreset=\RecipePreset,morekeywords={caption,label,ref}]
% \begin{table}
@@ -1137,20 +1206,37 @@ cherries,50g,cherries,heat up and add to bowl
% \end{LTXexample}
%
% The second way to add captions is through the |caption| option of
-% \pkgname{keyvaltable} tables. This is particularly suit for tables
-% that can span multiple pages, such as those produced through the
-% |multipage| shape (or |longtable|, |xltabular|, and |longtabu| -- see
-% \cref{sec:AltTabEnv}).
+% \pkgname{keyvaltable} tables. This option is available for the
+% "multipage" shape and, respectively, the table backends |longtable|,
+% |xltabular|, and |longtabu| (see \cref{sec:AltTabEnv}).
%
-% \NiceDescribeKeys{2}
+% \NiceDescribeKeys{4}
% {caption}{vals=\vmeta{text}, init=\vmeta{none}}
+% {caption/lot}{vals=\vmeta{text}, init=\vmeta{none}}
+% {caption/alt}{vals=\vmeta{text}, init=\vmeta{none}}
% {label}{vals=\vmeta{name}, init=\vmeta{none}}
% These options set the caption and, respectively, label of a table.
-% The caption is added to the end of the table.
+% Through the option |caption/lot|, the caption to be put into the list
+% of tables can be specified; if omitted, |caption| is used.
+% Through the option |caption/alt|, the alternative caption to be
+% displayed on those pages of multipage tables where the main caption is
+% not shown; if omitted, no caption is displayed on these pages.
+%
+% The position of the caption is determined by the following option.
+%
+% \NiceDescribeKey{captionpos}{vals={t,b}, init=b}
+% This option specifies the position of table captions. Value "|t|"
+% specifies that captions are at the top of (above) their tables; value
+% "|b|" specifies that captions are at the bottom of (below) their
+% tables.
+% Moreover, in case of "|t|" the main caption is on top of the
+% \emph{first} page of a table while in case of "|b|" the main caption
+% is at the bottom of the \emph{last} page of a table.
+%
% The following example shows the options in action.
%
-% \begin{LTXexample}[morepreset=\RecipePreset,morekeywords={caption,label,ref}]
-% \begin{KeyValTable}[shape=multipage,
+% \begin{LTXexample}[morepreset=\RecipePreset\setcounter{table}{0},morekeywords={caption,label,ref}]
+% \begin{KeyValTable}[captionpos=t,
% caption=Cherries++, label=Cherries2]{Recipe}
% \Row{amount=150g, ingredient=ice cream,
% step=put into bowl}
@@ -1163,28 +1249,33 @@ cherries,50g,cherries,heat up and add to bowl
%
% \subsection{Alternative Table Environments}
% \label{sec:AltTabEnv}
-%
-% Originally, the \thispackage package uses the \pkgname{tabu} package
-% and |tabu|, resp. |longtabu| environments for typesetting the actual
-% tables. Through the |shape| option of tables, the table environment
-% used by \thispackage tables can be changed.
-% \Vref{tab:TabEnv} compares
-% the possible shapes/environments with regards to
+% The \thispackage package internally uses traditional table
+% environments, such as |tabular|, for typesetting the actual tables.
+% Through the |shape| and |backend| properties of a table or table type,
+% the table environment used by for the table or, respectively, table
+% type can be changed.
+% \Vref{tab:TabEnv} compares the possible shapes/environments with
+% regards to
% \begin{itemize}[nosep]
% \item whether they support tables that span multiple pages,
% \item whether they support |caption| and |label| options,
% \item whether they support |X|-type (variable-width) columns,
-% \item and whether their width can be specified (through the |width| option).
+% \item whether their width can be specified (through the |width|
+% option), and
+% \item whether they support a vertical or horizontal alignment of the
+% table to be specified.
% \end{itemize}
-% Finally, the table also displays the
-% package(s) that must be loaded manually when the respective shapes are
+% Finally, the table also lists the names of the packages that provide
+% the respective environments. The packages for the shapes |onepage| and
+% |multipage| are loaded automatically. All other packages must be
+% loaded via |\usepackage| when the respective shape or backend shall be
% used.
% \begin{table}\centering
% \newcommand\RHead[1]{\rotatebox{90}{\small\varwidth{\linewidth}#1\endvarwidth}}%
% \newcommand\YesNo[1]{\ifstrequal{#1}{yes}{\checkmark}{}}%
-% \NewKeyValTable[shape=tabular,headformat=\sffamily\textbf]{ShapeProps}{
+% \NewKeyValTable[backend=tabular,headformat=\sffamily\textbf]{ShapeProps}{
% shape: format=\small\texttt;
-% env: format=\small\texttt, head=environment;
+% env: format=\small\texttt, head=backend;
% multipage: align=c, head=\RHead{multipage}, format=\YesNo;
% caption: align=c, head=\RHead{caption}, format=\YesNo;
% Xcols: align=c, head=\RHead{\texttt{X} columns}, format=\YesNo;
@@ -1199,14 +1290,14 @@ cherries,50g,cherries,heat up and add to bowl
% \Row{shape=onepage, env=tabu, multipage=no, caption=no, Xcols=yes, width=yes, align=v, packages=tabu}
% \Row{shape=multipage, env=longtabu, multipage=yes, caption=yes, Xcols=yes, width=yes, align=h, packages={tabu, longtable}}
% \midrule
-% \Row{shape=tabular, env=tabular, multipage=no, caption=no, Xcols=no, width=no, align=v}
-% \Row{shape=tabularx, env=tabularx, multipage=no, caption=no, Xcols=yes, width=yes, align=v, packages={tabularx}}
-% \Row{shape=longtable, env=longtable, multipage=yes, caption=yes, Xcols=no, width=no, align=h, packages={longtable}}
-% \Row{shape=xltabular, env=xltabular, multipage=yes, caption=yes, Xcols=yes, width=yes, align=h, packages={xltabular}}
-% \Row{shape=tabu, env=tabu, multipage=no, caption=no, Xcols=yes, width=yes, align=v, packages={tabu}}
-% \Row{shape=longtabu, env=longtabu, multipage=yes, caption=yes, Xcols=yes, width=yes, align=h, packages={tabu,longtable}}
+% \Row{ env=tabular, multipage=no, caption=no, Xcols=no, width=no, align=v}
+% \Row{ env=tabularx, multipage=no, caption=no, Xcols=yes, width=yes, align=v, packages={tabularx}}
+% \Row{ env=longtable, multipage=yes, caption=yes, Xcols=no, width=no, align=h, packages={longtable}}
+% \Row{ env=xltabular, multipage=yes, caption=yes, Xcols=yes, width=yes, align=h, packages={xltabular}}
+% \Row{ env=tabu, multipage=no, caption=no, Xcols=yes, width=yes, align=v, packages={tabu}}
+% \Row{ env=longtabu, multipage=yes, caption=yes, Xcols=yes, width=yes, align=h, packages={tabu,longtable}}
% \end{KeyValTable}
-% \caption{Comparison of table shapes / environments}
+% \caption{Comparison of table shapes and backends}
% \label{tab:TabEnv}
% \end{table}
%
@@ -1219,11 +1310,11 @@ cherries,50g,cherries,heat up and add to bowl
% l: align=l; c: align=c; r: align=r;}[headers={
% l+c+r: head=\textbf{\kvtTableOpt{shape} shape}\\ ::}]
%
-% \begin{KeyValTable}[shape=tabular]{ShapeNoX}
+% \begin{KeyValTable}[backend=tabular]{ShapeNoX}
% \Row{l=left, c=center, r=right}
% \Row{l=left-2, c=2-center-2, r=2-right}
% \end{KeyValTable}\\
-% \begin{KeyValTable}[shape=longtable]{ShapeNoX}
+% \begin{KeyValTable}[backend=longtable]{ShapeNoX}
% \Row{l=left, c=center, r=right}
% \Row{l=left-2, c=2-center-2, r=2-right}
% \end{KeyValTable}
@@ -1236,24 +1327,24 @@ cherries,50g,cherries,heat up and add to bowl
% l: align=l; X: align=X; r: align=r;}[headers={
% l+X+r: head=\textbf{\kvtTableOpt{shape} shape}\\ ::}]
%
-% \begin{KeyValTable}[shape=tabularx]{ShapeWithX}
+% \begin{KeyValTable}[backend=tabularx]{ShapeWithX}
% \Row{l=left, X=expandable, r=right}
% \Row{l=left-2, X=expandable-2, r=2-right}
% \end{KeyValTable}\medskip\\
-% \begin{KeyValTable}[shape=xltabular]{ShapeWithX}
+% \begin{KeyValTable}[backend=xltabular]{ShapeWithX}
% \Row{l=left, X=expandable, r=right}
% \Row{l=left-2, X=expandable-2, r=2-right}
% \end{KeyValTable}
-% \begin{KeyValTable}[shape=tabu]{ShapeWithX}
+% \begin{KeyValTable}[backend=tabu]{ShapeWithX}
% \Row{l=left, X=expandable, r=right}
% \Row{l=left-2, X=expandable-2, r=2-right}
% \end{KeyValTable}
-% \begin{KeyValTable}[shape=longtabu]{ShapeWithX}
+% \begin{KeyValTable}[backend=longtabu]{ShapeWithX}
% \Row{l=left, X=expandable, r=right}
% \Row{l=left-2, X=expandable-2, r=2-right}
% \end{KeyValTable}
% \end{LTXexample}
-% \caption{Examples for the shape option}
+% \caption{Examples for the backend option}
% \label{fig:TableTypes}
% \end{figure}
%
@@ -1492,6 +1583,44 @@ cherries,50g,cherries,heat up and add to bowl
%
% \subsection{Auxiliary Code}
%
+% \subsubsection{List Parsing}
+%
+% \begin{macro}{\kvt@DeclareTrimListParser}
+% The |\kvt@DeclareTrimListParser|(|*|)\marg{command}\marg{separator}
+% macro is equivalent to \pkgname{etoolbox}'s |\DeclareListParser|,
+% except that the \meta{command} is defined such that it will remove
+% trailing spaces from list elements before passing the list elements to
+% the processing macro (i.e., to |\do| or the user-provided macro).
+% Note: With |\DeclareListParser|, \meta{command} is defined to only
+% remove leading spaces but not trailing ones.
+% This implementation relies on the internals of
+% \pkgname{etoolbox} and works with v2.4 of the package, at least.
+% \begin{macrocode}
+\newcommand\kvt@DeclareTrimListParser{%
+ \@ifstar{\kvt@DeclareTrimListParser@i{*}}
+ {\kvt@DeclareTrimListParser@i{}}}
+\newcommand\kvt@DeclareTrimListParser@i[3]{%
+ \DeclareListParser#1{#2}{#3}\expandafter
+ \patchcmd\csname etb@lst@\expandafter\@gobble\string#2\endcsname
+ {\etb@listitem}{\kvt@etb@listitem}{}
+ {\kvt@warn{Failed to patch a command defined by the etoolbox
+ package, possibly because etoolbox internals have changed.
+ You might encounter superfluous spaces.}}}
+% \end{macrocode}
+% The cascade of |\expandafter| below ensures that first the trimming
+% macro is expanded and afterwards the outer |\unexpanded| of the
+% timming macro's expansion is expanded, which by definition of the
+% "noexp" trimming macro fully expands the macro's logic.
+% The auxiliary macro below is only for switching the two arguments such
+% that the expansion control can be applied to the second argument.
+% \begin{macrocode}
+\newcommand\kvt@etb@listitem[2]{%
+ \expandafter\expandafter\expandafter\kvt@etb@listitem@i
+ \expandafter\expandafter\expandafter{\trim@post@space@noexp{#2}}{#1}}
+\newcommand\kvt@etb@listitem@i[2]{\etb@listitem{#2}{#1}}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\kvt@dossvlist}
% The |\kvt@dossvlist|\marg{list} macro parses a semicolon-separated
% list and runs |\do|\meta{item} for every element of the list.
@@ -1503,17 +1632,19 @@ cherries,50g,cherries,heat up and add to bowl
% \begin{macro}{\kvt@forpsvlist}
% The |\kvt@forpsvlist|\marg{handler}\marg{list} parses a `+'-separated list.
% \begin{macrocode}
-\DeclareListParser*{\kvt@forpsvlist}{+}
+\kvt@DeclareTrimListParser*{\kvt@forpsvlist}{+}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\kvt@dobrklist}
% The |\kvt@dobrklist|\marg{list} parses a `|\\|'-separated list.
% \begin{macrocode}
-\DeclareListParser{\kvt@dobrklist}{\\}
+\kvt@DeclareTrimListParser{\kvt@dobrklist}{\\}
% \end{macrocode}
% \end{macro}
%
+% \subsubsection{Errors and Warnings}
+%
% \begin{macro}{\kvt@error}
% \begin{macro}{\kvt@warn}
% These macros produce error and warning messages.
@@ -1524,6 +1655,8 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macro}
% \end{macro}
%
+% \subsubsection{Setting Keys}
+%
% \begin{macro}{\kvt@setkeys}
% \begin{macro}{\kvt@setcmdkeys}
% \begin{macro}{\kvt@setcskeys}
@@ -1648,8 +1781,11 @@ cherries,50g,cherries,heat up and add to bowl
% The following code defines the possible table options.
%
% \changes{v0.2}{2016/05/21}{Added ``shape'' table option}
-% \changes{v2.0}{2019/05/11}{added table options "caption" and "label"}
+% \changes{v2.0}{2019/05/11}{Added table options "caption" and "label"}
% \changes{v2.1}{2020/01/18}{Added ``valign'' and ``halign'' table options}
+% \changes{v2.2}{2020/02/24}{Added ``style'' table option}
+% \changes{v2.2}{2020/02/27}{added option "backend"}
+% \changes{v2.2}{2020/03/08}{added option "captionpos"}
% \begin{macrocode}
\define@cmdkey[kvt]{Table}{rowbg}{}
\define@cmdkey[kvt]{Table}{headbg}{}
@@ -1658,12 +1794,13 @@ cherries,50g,cherries,heat up and add to bowl
\define@cmdkey[kvt]{Table}{width}{}
\define@boolkey[kvt]{Table}{showhead}{}
\define@boolkey[kvt]{Table}{showrules}{}
-\define@cmdkey[kvt]{Table}{caption}{}
-\define@cmdkey[kvt]{Table}{label}{}
+\define@choicekey[kvt]{Table}{captionpos}{t,b}
+ {\csdef{cmdkvt@Table@captionpos}{#1}}
\define@choicekey[kvt]{Table}{valign}{t,c,b}
{\csdef{cmdkvt@Table@valign}{#1}}
\define@choicekey[kvt]{Table}{halign}{l,c,r}
{\csdef{cmdkvt@Table@halign}{#1}}
+\define@key[kvt]{Table}{style}{\kvt@UseTableStyles{#1}}
% \end{macrocode}
% The following options only abbreviate options defined above.
% \changes{v2.1}{2020/01/14}{added abbreviation option "norules"}
@@ -1676,14 +1813,48 @@ cherries,50g,cherries,heat up and add to bowl
\ifbool{#1}
{\kvt@setkeys{showrules=false}{Table}}
{\kvt@setkeys{showrules=true}{Table}}}
+\define@key[kvt]{Table}{backend}{\ifinlist{#1}{\kvt@@tablebackends}
+ {\csdef{cmdkvt@Table@shape}{#1}}
+ {\kvt@error{Table backend '#1' not known}
+ {Check for misspellings in '#1'}}}
+\define@key[kvt]{Table}{shape}{\ifinlist{#1}{\kvt@@tableshapes}
+ {\csdef{cmdkvt@Table@shape}{#1}}
+ {\ifinlist{#1}{\kvt@@tablebackends}
+ {\kvt@warn{Using a backend ('#1') as shape is deprecated.
+ Use the 'backend' option instead.}%
+ \csdef{cmdkvt@Table@shape}{#1}}
+ {\kvt@error{Table shape '#1' not known}
+ {Check for misspellings in '#1'}}}}
+% \end{macrocode}
+%
+% The following table options only apply to individual |KeyValTable|
+% environments and cannot be set with |\NewKeyValTable| or |\kvtSet|.
+% \changes{v2.2}{2020/02/23}{added table options "resume" and "resume*"}
+% \changes{v2.2}{2020/03/12}{added options "caption/lot" and "caption/alt"}
+% \begin{macrocode}
+\define@cmdkey[kvt]{TableEnv}{caption}{}
+\define@cmdkey[kvt]{TableEnv}{caption/lot}{}
+\define@cmdkey[kvt]{TableEnv}{caption/alt}{}
+\define@cmdkey[kvt]{TableEnv}{label}{}
+\define@boolkey[kvt]{TableEnv}{resume}[true]{%
+ \ifbool{#1}{\ifundef\kvt@@rowcountlast
+ {\kvt@error{No previous table whose counter could be resumed.}
+ {Check whether the "resume" is intentional and whether a
+ previously existing predecessor table has disappeared.}}{}}{}}
+\define@boolkey[kvt]{TableEnv}{resume*}[true]{%
+ \ifbool{#1}
% \end{macrocode}
-% When adding further |shape| options below, ensure to also add a
-% corresponding |\kvt@DefineStdTabEnv| counterpart further below in the
-% code.
+% The |\kvt@@lastenvopt| macro holds the previous |KeyValTable|'s
+% options. Beyond these options, |resume*| automatically also sets
+% |resume|.
% \begin{macrocode}
-\define@choicekey[kvt]{Table}{shape}
- {multipage,onepage,tabular,longtable,tabularx,xltabular,tabu,longtabu}
- {\csdef{cmdkvt@Table@shape}{#1}}
+ {\ifundef\kvt@@lastenvopt
+ {\kvt@error{No previous table whose options could be resume*'d.}
+ {Check whether the "resume*" is intentional and whether a
+ previously existing predecessor table has disappeared.}}{}%
+ \kvt@setcmdkeys\kvt@@lastenvopt{Table}%
+ \kvt@setkeys{resume}{TableEnv}}
+ {}}
% \end{macrocode}
%
%
@@ -1808,9 +1979,11 @@ cherries,50g,cherries,heat up and add to bowl
%
% \subsubsection{Option Defaults}
%
-% The following sets the default values for the options.
+% The following sets the default values for the options. This is done
+% only after the package is otherwise completely processed, to ensure
+% that all features are already defined/registered at that point.
% \begin{macrocode}
-\kvtSet{%
+\AtEndOfPackage{\kvtSet{%
rowbg=white..black!10,
headbg=black!14,
showhead=true,
@@ -1819,7 +1992,7 @@ cherries,50g,cherries,heat up and add to bowl
headalign=,
shape=multipage,
width=\linewidth,
- caption={}, label={},
+ captionpos=b,
% \end{macrocode}
% Column options
% \begin{macrocode}
@@ -1838,7 +2011,7 @@ cherries,50g,cherries,heat up and add to bowl
ColGroup/align=c,
ColGroup/format=\kvtStrutted,
HeadCell/align=c,
-}
+}}
% \end{macrocode}
%
%
@@ -1928,6 +2101,10 @@ cherries,50g,cherries,heat up and add to bowl
% \meta{tname} and adds the column with the configuration to the table.
% \begin{macrocode}
\def\kvt@parsecolspec#1#2:#3:#4\@undefined{%
+% \end{macrocode}
+% Catch syntax errors first.
+% \begin{macrocode}
+ \kvt@checkcolspecempty{#4}{column}{#2}%
\def\kvt@@column{#2}%
\trim@spaces@in\kvt@@column
\expandafter\kvt@parsecolspec@i\expandafter{\kvt@@column}{#1}{#3}}
@@ -2066,6 +2243,13 @@ cherries,50g,cherries,heat up and add to bowl
% \meta{cgopts}.
% \begin{macrocode}
\def\kvt@parsecolgroup#1#2:#3:#4\@undefined{%
+% \end{macrocode}
+% Catch syntax errors first.
+% \begin{macrocode}
+ \kvt@checkcolspecempty{#4}{column group}{#2}%
+% \end{macrocode}
+% Next, check for a valid \meta{cgname}.
+% \begin{macrocode}
\ifinlistcs{#2}{kvt@allcolumns@#1}{\kvt@error
{Name `#2' cannot be used for a column group in table type `#1',
as it is already used for a column}
@@ -2116,6 +2300,23 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\kvt@checkcolspecempty}
+% The |\kvt@checkcolspecempty|\marg{empty}\marg{type}\marg{name}
+% macro checks the \meta{empty} parameter of a parsing macro for a
+% colon-separated key-value pair.
+% If \meta{empty} is empty, this corresponds to the valid case that only
+% the name of a column group was provided and no properties. If
+% \meta{empty} equals ":", then a name and properties were provided. In
+% all other cases, superfluous colons were found.
+% \begin{macrocode}
+\newcommand\kvt@checkcolspecempty[3]{%
+ \ifstrempty{#1}{}{\ifstrequal{#1}{:}{}{\kvt@error
+ {Too many ':' in definition of #2 '#3'}
+ {Check whether there is an accidental ':' that should actually be
+ a ',' or ';'.}}}}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\kvt@checkcolgroup}
% The |\kvt@checkcolgroup|\marg{span-psv}\marg{tname}\marg{cgname} macro
% performs some checks on \meta{span-psv} as a specification of which
@@ -2245,8 +2446,7 @@ cherries,50g,cherries,heat up and add to bowl
% header for the columns is added as header row.
% \begin{macrocode}
\def\do##1{%
- \def\kvt@@tmp{##1}\trim@post@space@in\kvt@@tmp%
- \expandafter\ifstrequal\expandafter{\kvt@@tmp}{::}
+ \ifstrequal{##1}{::}
{\appto\kvt@@parseheadrows{%
\cseappto{kvt@@custheadrows@#2}{%
\csexpandonce{kvt@headings@#2}}}}
@@ -2315,7 +2515,7 @@ cherries,50g,cherries,heat up and add to bowl
% for the column in |\kvt@@curhd|) and set |\kvt@@lasthd| to the
% current one.
% \begin{macrocode}
- {\ifnum\kvt@@span>\z@ \expandafter\kvt@concludecolumn\fi
+ {\ifnum\kvt@@span>\z@ \expandafter\kvt@concludehdcolumn\fi
\ifdefvoid\kvt@@curhd{}{\ifcsdef{kvt@@hdcelldone@\kvt@@curhd}{%
\kvt@error{Header cell `\kvt@@curhd' must consist of only
consecutive columns, but it is not}%
@@ -2323,7 +2523,7 @@ cherries,50g,cherries,heat up and add to bowl
specified in `\string\NewKeyValTable{#1}'}}{}}%
\kvt@@span\@ne \let\kvt@@lasthd\kvt@@curhd}%
}\dolistcsloop{kvt@displaycols@#1}%
- \kvt@concludecolumn
+ \kvt@concludehdcolumn
% \end{macrocode}
% Finally, conclude the whole header row and append the row to the
% overall list of rows, stored in \cs{kvt@@custheadrows@\meta{tname}},
@@ -2341,8 +2541,31 @@ cherries,50g,cherries,heat up and add to bowl
% The |\kvt@rowcolorornot|\marg{color} expands to
% |\rowcolor|\marg{color} if \meta{color} is nonempty and does have no
% effect if \meta{color} is empty.
+% \begin{macro}{\kvt@rowcolorcmdornot}
+% The |\kvt@rowcolorcmdornot|\marg{cmd} expands to
+% |\rowcolor|\marg{color}, where \meta{color} is the (one-time)
+% expansion of \meta{cmd}, if \meta{cmd} is a defined macro whose
+% expansion is nonempty; its expansion is empty otherwise.
% \begin{macrocode}
\newcommand\kvt@rowcolorornot[1]{\ifstrempty{#1}{}{\rowcolor{#1}}}
+\newcommand\kvt@rowcolorcmdornot[1]{\ifdefvoid{#1}{}{%
+ \expandafter\rowcolor\expandafter{#1}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\kvt@@bodyrow}
+% The counter |\kvt@@bodyrow| is used internally in |KeyValTable|
+% environments for keeping track of rows for the background-coloring.
+% The difference between this counter and |\kvtRow| is that the former
+% also counts |uncounted| rows and is unaffected by the |resume| option.
+% The counter only counts rows produced by |\Row| and its corresponding
+% collecting counterparts. Header rows as well as manually inserted
+% rows, including those produced by macros like |\midrule| in a
+% |longtable| environment, are not counted (as opposed by the internal
+% counter of |\rowcolors|.
+% \begin{macrocode}
+\newcount\kvt@@bodyrow
% \end{macrocode}
% \end{macro}
%
@@ -2354,18 +2577,19 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\kvt@concludecolumn}
-% The |\kvt@concludecolumn| macro appends a cell, potentially spanning
+% \begin{macro}{\kvt@concludehdcolumn}
+% The |\kvt@concludehdcolumn| macro appends a cell, potentially spanning
% multiple columns, to the row under construction (which is in
% |\kvt@@tmpgrphd|).
% \begin{macrocode}
-\newcommand\kvt@concludecolumn{%
+\newcommand\kvt@concludehdcolumn{%
\kvt@@switchcol
\ifdefvoid\kvt@@lasthd{}{%
\eappto\kvt@@tmpgrphd{\noexpand\multicolumn
{\the\kvt@@span}
{\csexpandonce{kvt@@hdcell@align@\kvt@@lasthd}}
- {\csexpandonce{kvt@@hdcell@head@\kvt@@lasthd}}}%
+ {\noexpand\cmdkvt@Table@headformat
+ {\csexpandonce{kvt@@hdcell@head@\kvt@@lasthd}}}}%
% \end{macrocode}
% Mark the header cell as already used and concluded, such that another
% use of the same header cell can be detected and raise an error.
@@ -2382,7 +2606,11 @@ cherries,50g,cherries,heat up and add to bowl
% \begin{macrocode}
\def\kvt@parsehdcolspec#1#2:#3:#4\@undefined{%
% \end{macrocode}
-% First link the individual columns of a header cell to the cell.
+% Catch syntax errors first.
+% \begin{macrocode}
+ \kvt@checkcolspecempty{#4}{header cell}{#2}%
+% \end{macrocode}
+% Next, link the individual columns of a header cell to the cell.
% In this, ensure that no column is contained in more than one header
% cell.
% \begin{macrocode}
@@ -2492,6 +2720,15 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macro}
% \begin{macrocode}
\kvt@SetOptions{#2}{#1}%
+% \end{macrocode}
+% Save \meta{options} globally for a potential "|resume*|" option in the
+% immediately following |KeyValTable| environment.
+% If |resume*| is specified for the current environment, then the
+% previous options are not replaced. That is, |resume*| resumes the
+% options from the previous non-resuming environment.
+% \begin{macrocode}
+ \ifbool{kvt@TableEnv@resume*}{}
+ {\gdef\kvt@@lastenvopt{#1}}%
\csuse{kvt@StartTable@\cmdkvt@Table@shape}{#2}%
}{%
\csuse{kvt@EndTable@\cmdkvt@Table@shape}}
@@ -2503,224 +2740,18 @@ cherries,50g,cherries,heat up and add to bowl
% specific table options in the current environment, based on the
% options for table type \meta{tname} and the specific \meta{options}.
% \begin{macrocode}
-\newcommand\kvt@SetOptions[2]{%
- \begingroup\edef\kvt@@do{\endgroup\noexpand%
- \kvt@setkeys{\csexpandonce{kvt@options@#1},\unexpanded{#2}}{Table}%
- }\kvt@@do}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Table Environment Code}
-%
-% \begin{macro}{\kvt@StartTabularlike}
-% The
-% |\kvt@StartTabularlike|\marg{env}\marg{tname}
-% macro begins a table environment for the given table type \meta{tname}.
-% The \meta{env} parameter specifies the concrete environment name.
-% \begin{macrocode}
-\newcommand\kvt@StartTabularlike[2]{%
-% \end{macrocode}
-% The |\kvt@@recenttable| allows the |\AfterEndEnvironment| hook for
-% |KeyValTable| to access the most recent table type.
-% \changes{v1.0}{2019/02/18}{Implemented \texttt{showrules} option}
-% \begin{macrocode}
- \gdef\kvt@@recenttable{#2}%
- \metatblAtEnd{#1}{\kvt@@endhook}\let\kvt@@endhook\relax%
- \ifbool{kvt@Table@showrules}
- {\def\kvt@@rule##1{\csuse{##1rule}}}
- {\def\kvt@@rule##1{}}%
- \appto\kvt@@endhook{\kvt@@rule{bottom}}
-% \end{macrocode}
-% The following saves the row counter value for the table type globally,
-% such that subsequent tables of the same \meta{tname} can start counting
-% from there.
-% \begin{macrocode}
- \appto\kvt@@endhook{%
- \noalign{\csxdef{kvt@rowcount@#2}{\thekvtTypeRow}}}%
-% \end{macrocode}
-% Adding caption and label, if given, to the end hook. This displays the
-% caption solely at the very end of the table.
-% \begin{macrocode}
- \ifdefempty\cmdkvt@Table@caption{}{%
- \metatblHasCaption{#1}
- {\appto\kvt@@endhook{\rowcolor{white}%
- \caption{\cmdkvt@Table@caption}}%
- \ifdefempty\cmdkvt@Table@label{}{%
- \appto\kvt@@endhook{\expandafter%
- \label\expandafter{\cmdkvt@Table@label}}}}
- {\kvt@warn{Caption lost, table environment '#1'
- does not support captions.}}}%
-% \end{macrocode}
-% The following lines perform some checks before the table environment
-% is started.
-% \begin{macrocode}
- \ifdefvoid{\cmdkvt@Table@valign}{}{\metatblCanVAlign{#1}{}
- {\undef{\cmdkvt@Table@valign}%
- \kvt@warn{Table environment '#1' of table '#2'
- does not support the vertical alignment option (valign).
- Ignoring the option}}}%
- \ifdefvoid{\cmdkvt@Table@halign}{}{\metatblCanHAlign{#1}{}
- {\undef{\cmdkvt@Table@halign}%
- \kvt@warn{Table environment '#1' of table '#2'
- does not support the horizontal alignment option (halign).
- Ignoring the option}}}%
+\newcommand\kvt@SetOptions[2]{\expandafter
+ \kvt@SetOptions@i\expandafter{\csname kvt@options@#1\endcsname}{#2}}
% \end{macrocode}
-% Initializing the row counters. The global counter |kvtTotalRow| needs
-% no local initialization.
+% The auxiliary macro |\kvt@SetOptions@i|\marg{optcmd}\marg{options}
+% first sets the options in the expansion of \meta{optcmd} and then the
+% \meta{options}.
% \begin{macrocode}
- \setcounter{kvtRow}{0}%
- \setcounter{kvtTypeRow}{\csuse{kvt@rowcount@#2}}%
-% \end{macrocode}
-% In |\kvt@@do|, the start code for the environment, including the
-% header rows, is gathered, with expansion to fill in all the table
-% settings and options.
-% \changes{v0.3}{2016/06/05}{Added \texttt{showhead} option}
-% \changes{v1.0}{2019/03/09}{Added \texttt{width} option}
-% \changes{v2.1}{2020/01/19}{Added \texttt{valign} and \texttt{halign} options}
-% \begin{macrocode}
- \begingroup\edef\kvt@@do{\endgroup
- \metatblIsTabu{#1}{}{\noexpand\kvt@dottedrowcolors
- {\ifbool{kvt@Table@showhead}
- {\the\numexpr\csuse{kvt@headrowcount@#2}+1\relax}
- {1}}%
- {\expandonce\cmdkvt@Table@rowbg}}%
- \expandafter\noexpand\csname #1\endcsname
-% \end{macrocode}
-% As background on the positions of the parameters below, here is the
-% syntax for beginning the supported environments:
-% \begin{itemize}[nosep]
-% \item|\begin{tabular}|\oarg{valign}\marg{preamble}
-% \item|\begin{tabularx}|\marg{width}\oarg{valign}\marg{preamble}
-% \item|\begin{longtable}|\oarg{halign}\marg{preamble}
-% \item|\begin{xltabular}|\oarg{halign}\marg{width}\marg{preamble}
-% \item|\begin{tabu}| to \meta{width}\oarg{valign}\marg{preamble}
-% \item|\begin{longtabu}| to \meta{width}\oarg{halign}\marg{preamble}
-% \end{itemize}
-% The above cases are covered in the following lines.
-% \begin{macrocode}
- \ifdefvoid{\cmdkvt@Table@halign}{}
- {\metatblIsTabu{#1}{}{[\cmdkvt@Table@halign]}}%
- \metatblHasWidth{#1}
- {\metatblIsTabu{#1}
- {to \expandonce\cmdkvt@Table@width}
- {{\expandonce\cmdkvt@Table@width}}}
- {}%
- \ifdefvoid{\cmdkvt@Table@valign}{}{[\cmdkvt@Table@valign]}%
- \ifdefvoid{\cmdkvt@Table@halign}{}
- {\metatblIsTabu{#1}{[\cmdkvt@Table@halign]}{}}%
- {\csexpandonce{kvt@alignments@#2}}%
-% \end{macrocode}
-% The remainder below already starts the content of the table
-% environment.
-% \begin{macrocode}
- \noexpand\kvt@@rule{top}%
- \ifbool{kvt@Table@showhead}
- {\csuse{kvt@headings@#2}\noexpand\kvt@@rule{mid}}
- {}%
- \metatblIsTabu{#1}
- {\noexpand\kvt@taburowcolors{\expandonce\cmdkvt@Table@rowbg}}{}%
- \metatblIsLong{#1}{\noexpand\endhead}{}%
- }\kvt@@do}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\kvt@dottedrowcolors}
-% The |\kvt@dottedrowcolors|\marg{start-row}\marg{colors} sets up row
-% colors using the |\rowcolors| macro of \pkgname{xcolor}.
-% The \marg{colors} parameter expects arguments of the form
-% "\meta{color1}|..|\meta{color2}" (the syntax used for the |rowbg|
-% option. The row colors then alternate between \meta{color1} and
-% \meta{color2}, starting with \meta{color1} in \meta{start-row}.
-% This macro substitutes |\taburowcolors| for non-\pkgname{tabu}
-% environments.
-% If \meta{colors} is empty, then no row colors are setup.
-% \begin{macrocode}
-\newcommand\kvt@dottedrowcolors[2]{%
- \ifstrempty{#2}{}{\kvt@dottedrowcolors@i{#1}#2\@nil}}
-\def\kvt@dottedrowcolors@i#1#2..#3\@nil{%
-% \end{macrocode}
-% Since |\rowcolors| expects its color arguments to specify the odd and
-% even color, we swap arguments depending on the parity of
-% \meta{start-row} to ensure \meta{color1} is applied to
-% \meta{start-row}.
-% \begin{macrocode}
- \ifnumodd{#1}
- {\rowcolors{#1}{#2}{#3}}
- {\rowcolors{#1}{#3}{#2}}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\kvt@taburowcolors}
-% The |\kvt@taburowcolors|\marg{colors} expands to
-% |\taburowcolors|\marg{colors} if \meta{colors} is nonempty and does
-% have no effect if \meta{color} is empty.
-% \begin{macrocode}
-\newcommand\kvt@taburowcolors[1]{%
- \ifstrempty{#1}{}{\taburowcolors{#1}}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\kvt@DefineStdTabEnv}
-% The |\kvt@DefineStdTabEnv|\oarg{shape}\marg{env}
-% macro defines the macros needed for the given \meta{shape} value.
-% If \meta{shape} is omitted, \meta{env} (the name of the environment to
-% use for the shape) is used as \meta{shape} value.
-%
-% Note: In the future, the macro could automatically add \meta{option}
-% to the list of possible values for the |shape| option.
-% \begin{macrocode}
-\newcommand\kvt@DefineStdTabEnv{\@dblarg\kvt@DefineStdTabEnv@i}
-\newcommand\kvt@DefineStdTabEnv@i[2][]{%
- \expandafter\newcommand\csname kvt@StartTable@#1\endcsname[1]{%
- \kvt@StartTabularlike{#2}{##1}}%
- \csedef{kvt@EndTable@#1}{%
- \expandafter\noexpand\csname end#2\endcsname}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\kvt@DefineDualTabEnv}
-% The |\kvt@DefineDualTabEnv|\marg{shape}\marg{nonX-env}\marg{X-env}
-% macro defines the macros for the given \meta{shape} name.
-% The macros are defined in a way such that the table environment
-% \meta{nonX-env} is used for typesetting tables that do not use |X|
-% columns and that table environment \meta{X-env} is used for
-% typesetting tables that do use |X| columns.
-% \begin{macrocode}
-\newcommand\kvt@DefineDualTabEnv[3]{%
- \expandafter\newcommand\csname kvt@StartTable@#1\endcsname[1]{%
- \kvt@ifhasXcolumns{##1}
- {\csedef{kvt@EndTable@#1}{%
- \expandafter\noexpand\csname end#3\endcsname}%
- \kvt@StartTabularlike{#3}{##1}%
- }{\csedef{kvt@EndTable@#1}{%
- \expandafter\noexpand\csname end#2\endcsname}%
- \kvt@StartTabularlike{#2}{##1}}}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\kvt@ifhasXcolumns}
-% The |\kvt@ifhasXcolumns|\marg{tname}\marg{iftrue}\marg{iffalse}
-% takes a table type \meta{tname} and checks whether the table type
-% contains an "|X|" column. If such a column is contained, the macro
-% expands to \meta{iftrue}. Otherwise, it expands to \meta{iffalse}.
-% \begin{macrocode}
-\newcommand\kvt@ifhasXcolumns[1]{%
- \expandafter\expandafter\expandafter\metatbl@ifhasXcolumns
- \expandafter\expandafter\expandafter{%
- \csname kvt@alignments@#1\endcsname}}
+\newcommand\kvt@SetOptions@i[2]{\expandafter
+ \kvt@setkeys\expandafter{#1,#2}{Table,TableEnv}}
% \end{macrocode}
% \end{macro}
%
-% The following lines define the macros for the various table shapes /
-% environments.
-% \begin{macrocode}
-\kvt@DefineStdTabEnv{tabular}
-\kvt@DefineStdTabEnv{longtable}
-\kvt@DefineStdTabEnv{tabularx}
-\kvt@DefineStdTabEnv{xltabular}
-\kvt@DefineStdTabEnv{tabu}
-\kvt@DefineStdTabEnv{longtabu}
-% \end{macrocode}
%
% \subsubsection{Table Environment Properties}
%
@@ -2759,6 +2790,7 @@ cherries,50g,cherries,heat up and add to bowl
% \begin{macrocode}
\newrobustcmd\metatblRegisterEnv[2]{%
\edef\metatbl@@envname{#1}%
+ \csdef{metatbl@@registered@#1}{true}%
\setkeys[metatbl]{EnvProp}{#2}}
% \end{macrocode}
% \end{macro}
@@ -2786,29 +2818,24 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\metatblRegistered}
% \begin{macro}{\metatblIsLong}
% \begin{macro}{\metatblIsTabu}
% \begin{macro}{\metatblHasWidth}
% \begin{macro}{\metatblHasCaption}
% \begin{macro}{\metatblCanVAlign}
% \begin{macro}{\metatblCanHAlign}
+% All macros in the following block expect three arguments,
+% \marg{env-name}\marg{iftrue}\marg{iffalse}.
% The macro
-% |\metatblIsLong|\marg{env-name}\marg{iftrue}\marg{iffalse}
-% expands to \meta{iftrue} if \meta{env-name} is a "long" table
-% environment, i.e., one that can span multiple pages. Otherwise, the
-% macro expands to \meta{iffalse}.
-% The macro
-% |\metatblIsTabu|\marg{env-name}\marg{iftrue}\marg{iffalse}
-% expands to \meta{iftrue} if \meta{env-name} is a table environment
-% that inherits from |tabu| and expands to \meta{iffalse} otherwise.
-% The macro
-% |\metatblHasWidth|\marg{env-name}\marg{iftrue}\marg{iffalse}
-% expands to \meta{iftrue} if \meta{env-name} is a table environment
-% that expects a width argument and expands to \meta{iffalse} otherwise.
-% |\metatblHasCaption|\marg{env-name}\marg{iftrue}\marg{iffalse}
-% expands to \meta{iftrue} if \meta{env-name} is a table environment
-% that supports a caption and expands to \meta{iffalse} otherwise.
-% \begin{macrocode}
+% |\metatblRegistered|
+% expands to \meta{iftrue} if \meta{env-name} has been registered via
+% |\metatblRegisterEnv| and expands to \meta{iffalse} otherwise.
+% The remaining macros expand to \meta{iftrue}, if the respective
+% property has been set to |true| in when \meta{env-name} was registered
+% via |\metatblRegisterEnv|, and expand to \meta{iffalse} otherwise.
+% \begin{macrocode}
+\newcommand\metatblRegistered[1]{\ifcsdef{metatbl@@registered@#1}}
\newcommand\metatblIsLong[1]{\ifbool{metatbl@EnvProp@isLong@#1}}
\newcommand\metatblIsTabu[1]{\ifbool{metatbl@EnvProp@isTabu@#1}}
\newcommand\metatblHasWidth[1]{\ifbool{metatbl@EnvProp@hasWidth@#1}}
@@ -2822,6 +2849,7 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\metatblUsePackage}
% \begin{macro}{\metatblRequire}
@@ -2849,7 +2877,7 @@ cherries,50g,cherries,heat up and add to bowl
% \meta{code} for addition at the end of tables based on the
% \meta{env-name} environment.
% \begin{macrocode}
-\newcommand\metatblAtEnd[2]{% #1=env-name, #2=code
+\newcommand\metatblAtEnd[2]{%
\csname metatbl@EnvProp@atEnd@#1\endcsname{#2}}
% \end{macrocode}
% \end{macro}
@@ -2956,6 +2984,305 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macro}
%
%
+% \subsubsection{Table Environment Code}
+%
+% \begin{macro}{\kvt@StartTabularlike}
+% The
+% |\kvt@StartTabularlike|\marg{env}\marg{tname}
+% macro begins a table environment for the given table type \meta{tname}.
+% The \meta{env} parameter specifies the concrete environment name.
+% \begin{macrocode}
+\newcommand\kvt@StartTabularlike[2]{%
+% \end{macrocode}
+% \changes{v1.0}{2019/02/18}{Implemented \texttt{showrules} option}
+% \begin{macrocode}
+ \metatblAtEnd{#1}{\kvt@@endhook}%
+ \let\kvt@@endhook\@empty
+ \let\kvt@@prehook\@empty
+ \ifbool{kvt@Table@showrules}
+ {\def\kvt@@rule##1{\csuse{##1rule}}}
+ {\def\kvt@@rule##1{}}%
+ \appto\kvt@@prehook{\kvt@@rule{top}}%
+ \appto\kvt@@endhook{\kvt@@rule{bottom}}%
+% \end{macrocode}
+% The following saves the row counter value for the table type globally,
+% such that subsequent tables of the same \meta{tname} can start counting
+% from there. Moreover, it save the local row counter for the case that
+% the next table uses the "|resume|" option.
+% \begin{macrocode}
+ \appto\kvt@@endhook{\noalign{%
+ \csxdef{kvt@rowcount@#2}{\thekvtTypeRow}%
+ \csxdef{kvt@@rowcountlast}{\thekvtRow}}}%
+% \end{macrocode}
+% Adding caption and label.
+% \begin{macrocode}
+ \ifdefvoid\cmdkvt@TableEnv@caption
+ {\let\kvt@@caption@main\@empty
+ \let\kvt@@caption@alt\@empty}
+ {\metatblHasCaption{#1}
+ {\edef\kvt@@caption@main{%
+ \csexpandonce{kvt@caption@\cmdkvt@Table@captionpos}%
+ \ifcsvoid{cmdkvt@TableEnv@caption/lot}{}
+ {[{\csexpandonce{cmdkvt@TableEnv@caption/lot}}]}%
+ {\expandonce\cmdkvt@TableEnv@caption
+ \ifdefvoid\cmdkvt@TableEnv@label{}{%
+ \noexpand\label{\expandonce\cmdkvt@TableEnv@label}}}%
+ \noexpand\\}%
+ \ifcsvoid{cmdkvt@TableEnv@caption/alt}
+ {\def\kvt@@caption@alt{}}
+ {\edef\kvt@@caption@alt{%
+ \csexpandonce{kvt@caption@\cmdkvt@Table@captionpos}[]%
+ {\csexpandonce{cmdkvt@TableEnv@caption/alt}}%
+ \noexpand\\}}%
+ }{\kvt@error
+ {Caption lost, table backend '#1' does not support captions}
+ {Consider placing the KeyValTable environment inside a 'table'
+ environment and use the \string\caption\space macro inside.}}}%
+ \ifdefstring{\cmdkvt@Table@captionpos}{t}
+ {\let\kvt@@caption@headmain\kvt@@caption@main\let\kvt@@caption@footmain\@empty
+ \let\kvt@@caption@headalt\kvt@@caption@alt \let\kvt@@caption@footalt\@empty}
+ {\let\kvt@@caption@footmain\kvt@@caption@main\let\kvt@@caption@headmain\@empty
+ \let\kvt@@caption@footalt\kvt@@caption@alt \let\kvt@@caption@headalt\@empty}%
+ \ifbool{kvt@Table@showhead}
+ {\eappto\kvt@@prehook{\csuse{kvt@headings@#2}\noexpand\kvt@@rule{mid}}}
+ {}%
+% \end{macrocode}
+% The following lines perform some checks before the table environment
+% is started.
+% \begin{macrocode}
+ \ifdefvoid{\cmdkvt@Table@valign}{}{\metatblCanVAlign{#1}{}
+ {\undef{\cmdkvt@Table@valign}%
+ \kvt@warn{Table environment '#1' of table '#2'
+ does not support the vertical alignment option (valign).
+ Ignoring the option}}}%
+ \ifdefvoid{\cmdkvt@Table@halign}{}{\metatblCanHAlign{#1}{}
+ {\undef{\cmdkvt@Table@halign}%
+ \kvt@warn{Table environment '#1' of table '#2'
+ does not support the horizontal alignment option (halign).
+ Ignoring the option}}}%
+% \end{macrocode}
+% Initializing the row counters. The global counter |kvtTotalRow| needs
+% no local initialization.
+% \begin{macrocode}
+ \global\kvt@@bodyrow=0\relax
+ \ifbool{kvt@TableEnv@resume}
+ {\setcounter{kvtRow}{\csuse{kvt@@rowcountlast}}}
+ {\setcounter{kvtRow}{0}}%
+ \setcounter{kvtTypeRow}{\csuse{kvt@rowcount@#2}}%
+% \end{macrocode}
+% Initialize the background colors for the body rows.
+% \begin{macrocode}
+ \expandafter\kvt@setrowcolors\expandafter{\cmdkvt@Table@rowbg}%
+% \end{macrocode}
+% In |\kvt@@do|, the start code for the environment, including the
+% header rows, is gathered, with expansion to fill in all the table
+% settings and options.
+% \changes{v0.3}{2016/06/05}{Added \texttt{showhead} option}
+% \changes{v1.0}{2019/03/09}{Added \texttt{width} option}
+% \changes{v2.1}{2020/01/19}{Added \texttt{valign} and \texttt{halign} options}
+% \begin{macrocode}
+ \begingroup\edef\kvt@@do{\endgroup
+ \expandafter\noexpand\csname #1\endcsname
+% \end{macrocode}
+% As background on the positions of the parameters below, here is the
+% syntax for beginning the supported environments:
+% \begin{itemize}[nosep]
+% \item|\begin{tabular}|\oarg{valign}\marg{preamble}
+% \item|\begin{tabularx}|\marg{width}\oarg{valign}\marg{preamble}
+% \item|\begin{longtable}|\oarg{halign}\marg{preamble}
+% \item|\begin{xltabular}|\oarg{halign}\marg{width}\marg{preamble}
+% \item|\begin{tabu}| to \meta{width}\oarg{valign}\marg{preamble}
+% \item|\begin{longtabu}| to \meta{width}\oarg{halign}\marg{preamble}
+% \end{itemize}
+% The above cases are covered in the following lines.
+% \begin{macrocode}
+ \ifdefvoid{\cmdkvt@Table@halign}{}
+ {\metatblIsTabu{#1}{}{[\cmdkvt@Table@halign]}}%
+ \metatblHasWidth{#1}
+ {\metatblIsTabu{#1}
+ {to \expandonce\cmdkvt@Table@width}
+ {{\expandonce\cmdkvt@Table@width}}}
+ {}%
+ \ifdefvoid{\cmdkvt@Table@valign}{}{[\cmdkvt@Table@valign]}%
+ \ifdefvoid{\cmdkvt@Table@halign}{}
+ {\metatblIsTabu{#1}{[\cmdkvt@Table@halign]}{}}%
+ {\csexpandonce{kvt@alignments@#2}}%
+% \end{macrocode}
+% The remainder below already starts the content of the table
+% environment. It also sets the header and footer for multipage tables.
+% \begin{macrocode}
+ \expandonce\kvt@@caption@headmain
+ \expandonce\kvt@@prehook
+ \metatblIsLong{#1}{%
+ \noexpand\endfirsthead
+ \expandonce\kvt@@caption@headalt
+ \expandonce\kvt@@prehook
+ \noexpand\endhead}{}%
+ \expandonce\kvt@@caption@footmain
+ \metatblIsLong{#1}{%
+ \noexpand\endlastfoot
+ \expandonce\kvt@@caption@footalt
+ \noexpand\endfoot}{}%
+ }\kvt@@do}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\kvt@caption@b}
+% \begin{macro}{\kvt@caption@t}
+% The |\kvt@caption@b| and |\kvt@caption@t| macros behave like
+% |\caption| but add extra behavior depending on whether the caption is
+% displayed above (|\kvt@caption@t|) or below (|\kvt@caption@b|) the
+% table. Currently, |\kvt@caption@b| only fixes the spacing between the
+% table and the caption.
+% \begin{macrocode}
+\newcommand\kvt@caption@t{\caption}
+\newcommand\kvt@caption@b{%
+% \end{macrocode}
+% Fixme: The following |\baselineskip| before the caption compensates
+% that \pkgname{longtable} adds a |\baselineskip| below the caption (in
+% its macro |\LT@makecaption|) but not above. The \pkgname{ltcaption}
+% package replaces the hard-coded |\baselineskip| by |\LTcapskip| but
+% also only puts it below the caption. The code below could at least be
+% improved to use |\LTcapskip| if it is available.
+% \begin{macrocode}
+ \noalign{\parbox{0pt}{\vskip\baselineskip}}%
+ \caption}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\kvt@setrowcolors}
+% The |\kvt@setrowcolors|\marg{colors} sets up row
+% colors using the |\rowcolors| macro of \pkgname{xcolor}.
+% The \marg{colors} parameter expects arguments of the form
+% "\meta{color1}|..|\meta{color2}" (the syntax used for the |rowbg|
+% option. The row colors then alternate between \meta{color1} and
+% \meta{color2}, starting with \meta{color1} in the first row.
+% If \meta{colors} is empty, then no row colors are setup.
+% \begin{macrocode}
+\newcommand\kvt@setrowcolors[1]{%
+ \ifstrempty{#1}{}{\kvt@setrowcolors@i#1\@nil}}
+\def\kvt@setrowcolors@i#1..#2\@nil{%
+ \def\kvt@@bgcolor@odd{#1}%
+ \def\kvt@@bgcolor@even{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\kvt@userowcolors}
+% The |\kvt@userowcolors| macro macro expands to
+% |\rowcolor|\marg{color}, where \meta{color} is the background color
+% set via |\kvt@setrowcolors| for odd, respectively even rows, based on
+% |\kvt@@bodyrow|.
+% \begin{macrocode}
+\newcommand\kvt@userowcolors{\ifnumodd{\the\kvt@@bodyrow}
+ {\kvt@rowcolorcmdornot{\kvt@@bgcolor@odd}}
+ {\kvt@rowcolorcmdornot{\kvt@@bgcolor@even}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\kvt@RegisterBackend}
+% \begin{macro}{\kvt@RegisterShape}
+% The |\kvt@RegisterBackend|\marg{env} macro registers the table
+% environment \meta{env} as a table backend for use by \thispackage.
+% The |\kvt@RegisterShape|\marg{name}\marg{nonX-env}\marg{X-env}
+% registers a shape with the given \meta{name} and associates it with
+% the environment \meta{nonX-env} when the shape is used for a table
+% without |X| columns and with environment \meta{X-env} otherwise.
+% \begin{macrocode}
+\newcommand\kvt@RegisterBackend[1]{%
+ \ifinlist{#1}{\kvt@@tablebackends}
+ {\kvt@error{Backend '#1' already registered}
+ {Internal error. Check use of \string\kvt@RegisterBackend.}}
+ {\kvt@CheckMetatblEnv{#1}%
+ \listadd{\kvt@@tablebackends}{#1}%
+ \kvt@DefineStdTabEnv{#1}{#1}}}
+\newcommand\kvt@RegisterShape[3]{%
+ \ifinlist{#1}{\kvt@@tableshapes}
+ {\kvt@error{Shape '#1' already registered}
+ {Internal error. Check use of \string\kvt@RegisterShape.}}
+ {\kvt@CheckMetatblEnv{#2}\kvt@CheckMetatblEnv{#3}%
+ \listadd{\kvt@@tableshapes}{#1}%
+ \ifstrequal{#2}{#3}
+ {\kvt@DefineStdTabEnv{#1}{#2}}
+ {\kvt@DefineDualTabEnv{#1}{#2}{#3}}}}
+\newcommand\kvt@CheckMetatblEnv[1]{\metatblRegistered{#1}{}
+ {\kvt@error{Environment '#1' not supported by keyvaltable}
+ {Check \string\metatblRegisterEnv\space for how to make it
+ supported.}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\kvt@RegisterBackend}
+% \begin{macro}{\kvt@RegisterShape}
+% The macros |\kvt@@tablebackends| and |\kvt@@tableshapes| hold
+% \pkgname{etoolbox} lists of registered names of table backends and
+% table shapes.
+% \begin{macrocode}
+\newcommand\kvt@@tablebackends{}
+\newcommand\kvt@@tableshapes{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\kvt@DefineStdTabEnv}
+% The |\kvt@DefineStdTabEnv|\marg{shape}\marg{env}
+% macro defines the macros needed for the given \meta{shape} value.
+% If \meta{shape} is omitted, \meta{env} (the name of the environment to
+% use for the shape) is used as \meta{shape} value.
+% \begin{macrocode}
+\newcommand\kvt@DefineStdTabEnv[2]{%
+ \csdef{kvt@StartTable@#1}##1{%
+ \kvt@StartTabularlike{#2}{##1}}%
+ \csedef{kvt@EndTable@#1}{%
+ \expandafter\noexpand\csname end#2\endcsname}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\kvt@DefineDualTabEnv}
+% The |\kvt@DefineDualTabEnv|\marg{shape}\marg{nonX-env}\marg{X-env}
+% macro defines the macros for the given \meta{shape} name.
+% The macros are defined in a way such that the table environment
+% \meta{nonX-env} is used for typesetting tables that do not use |X|
+% columns and that table environment \meta{X-env} is used for
+% typesetting tables that do use |X| columns.
+% \begin{macrocode}
+\newcommand\kvt@DefineDualTabEnv[3]{%
+ \expandafter\newcommand\csname kvt@StartTable@#1\endcsname[1]{%
+ \kvt@ifhasXcolumns{##1}
+ {\csedef{kvt@EndTable@#1}{%
+ \expandafter\noexpand\csname end#3\endcsname}%
+ \kvt@StartTabularlike{#3}{##1}%
+ }{\csedef{kvt@EndTable@#1}{%
+ \expandafter\noexpand\csname end#2\endcsname}%
+ \kvt@StartTabularlike{#2}{##1}}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\kvt@ifhasXcolumns}
+% The |\kvt@ifhasXcolumns|\marg{tname}\marg{iftrue}\marg{iffalse}
+% takes a table type \meta{tname} and checks whether the table type
+% contains an "|X|" column. If such a column is contained, the macro
+% expands to \meta{iftrue}. Otherwise, it expands to \meta{iffalse}.
+% \begin{macrocode}
+\newcommand\kvt@ifhasXcolumns[1]{%
+ \expandafter\expandafter\expandafter\metatbl@ifhasXcolumns
+ \expandafter\expandafter\expandafter{%
+ \csname kvt@alignments@#1\endcsname}}
+% \end{macrocode}
+% \end{macro}
+%
+% The following lines define the macros for the various table
+% environments.
+% \begin{macrocode}
+\kvt@RegisterBackend{tabular}
+\kvt@RegisterBackend{longtable}
+\kvt@RegisterBackend{tabularx}
+\kvt@RegisterBackend{xltabular}
+\kvt@RegisterBackend{tabu}
+\kvt@RegisterBackend{longtabu}
+% \end{macrocode}
+%
+%
% \subsubsection{Environment-Independent Parts}
%
% \begin{macro}{\kvt@AddKeyValRow}
@@ -3012,10 +3339,12 @@ cherries,50g,cherries,heat up and add to bowl
\ifdefvoid\cmdkvt@Row@above{}{%
\eappto\kvt@@row{\noexpand\noalign{\noexpand\vspace{%
\expandonce\cmdkvt@Row@above}}}}%
- \ifdefvoid\cmdkvt@Row@bg{}{%
- \eappto\kvt@@row{\noexpand\rowcolor{\expandonce\cmdkvt@Row@bg}}}%
+ \appto\kvt@@row{\noalign{\global\advance\kvt@@bodyrow\@ne}}%
\ifbool{kvt@Row@uncounted}{}{%
\appto\kvt@@row{\noalign{\kvt@stepcounters}}}%
+ \ifdefvoid\cmdkvt@Row@bg
+ {\appto\kvt@@row{\kvt@userowcolors}}
+ {\eappto\kvt@@row{\noexpand\rowcolor{\expandonce\cmdkvt@Row@bg}}}%
% \end{macrocode}
% If a row alignment is specified, a default |\multicolumn| display is
% enabled for the row's cells.
@@ -3272,54 +3601,111 @@ cherries,50g,cherries,heat up and add to bowl
% \end{macrocode}
% \end{macro}
%
-% \subsubsection{Row Styles}
+% \subsubsection{Table and Row Styles}
+%
+% The following are the user macros.
%
% \begin{macro}{\kvtNewRowStyle}
+% \changes{v2.0}{2019/03/25}{Added the macro}
+% \begin{macro}{\kvtRenewRowStyle}
+% \changes{v2.0}{2019/03/25}{Added the macro}
% The |\kvtNewRowStyle|\marg{name}\marg{row-options} macro declares
% \meta{name} as a row style and defines it to be equivalent to
% specifying \meta{row-options} directly in the optional argument of
% |\Row|. The macro fails if \meta{name} is already declared as a row
% style.
-% \changes{v2.0}{2019/03/25}{Added the macro}
+% The |\kvtRenewRowStyle|\marg{name}\marg{row-options} macro re-defines
+% an already existing row style with new \meta{row-options}.
% \begin{macrocode}
-\newcommand\kvtNewRowStyle[2]{%
- \ifcsundef{kvt@@rowstyle@#1}
- {\csdef{kvt@@rowstyle@#1}{#2}}
- {\kvt@error{Row style '#1' is already defined}{Use
- \string\kvtRenewRowStyle\space to change an existing style.}}}
+\newcommand\kvtNewRowStyle{\kvt@NewStyle{row}{\kvtRenewRowStyle}}
+\newcommand\kvtRenewRowStyle{\kvt@RenewStyle{row}{\kvtNewRowStyle}}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\kvtRenewRowStyle}
-% The |\kvtRenewRowStyle|\marg{name}\marg{row-options} macro re-defines
-% an already existing row style with new \meta{row-options}.
-% \changes{v2.0}{2019/03/25}{Added the macro}
-% \begin{macrocode}
-\newcommand\kvtRenewRowStyle[2]{%
- \ifcsundef{kvt@@rowstyle@#1}
- {\kvt@error{Row style '#1' is not defined}
- {Use \string\kvtNewRowStyle\space to define a new row style.}}
- {\csdef{kvt@@rowstyle@#1}{#2}}}
+% \begin{macro}{\kvtNewTableStyle}
+% \changes{v2.2}{2020/02/24}{Added the macro}
+% \begin{macro}{\kvtRenewTableStyle}
+% \changes{v2.2}{2020/02/24}{Added the macro}
+% The |\kvtNewTableStyle|\marg{name}\marg{options} macro declares
+% \meta{name} as a table style and defines it to be equivalent to
+% specifying \meta{options} directly in the optional argument of
+% a |KeyValTable| environment or of a |\NewKeyValTable|. The macro fails
+% if \meta{name} is already declared as a table style.
+% The |\kvtRenewTableStyle|\marg{name}\marg{options} macro re-defines
+% an already existing table style with new \meta{options}.
+% \begin{macrocode}
+\newcommand\kvtNewTableStyle{\kvt@NewStyle{table}{\kvtRenewTableStyle}}
+\newcommand\kvtRenewTableStyle{\kvt@RenewStyle{table}{\kvtNewTableStyle}}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\kvt@UseRowStyle}
-% The |\kvt@UseRowStyle|\marg{style} macro sets the row keys based on
-% the \meta{row-options} stored for the given \meta{style}.
-% \begin{macrocode}
-\newcommand\kvt@UseRowStyle[1]{%
- \ifcsundef{kvt@@rowstyle@#1}
- {\kvt@error{Row style '#1' is not defined}
- {Use \string\kvtNewRowStyle\space to define a new row style.}}
- {\kvt@setcskeys{kvt@@rowstyle@#1}{Row}}}
+% The following are the internal macros that the style code shares.
+%
+% \begin{macro}{\kvt@NewStyle}
+% \begin{macro}{\kvt@RenewStyle}
+% The |\kvt@NewStyle|\marg{type}\marg{renewcmd}\marg{name}\marg{options}
+% macro defines a new style, \meta{name}, for \meta{type} (|table| or
+% |row|) to correspond to \meta{options}.
+% Analogously,
+% |\kvt@RenewStyle|\marg{type}\marg{newcmd}\marg{name}\marg{options}
+% macro re-defines a style.
+% \begin{macrocode}
+\newcommand\kvt@NewStyle[4]{%
+ \ifcsundef{kvt@@#1style@#3}
+ {\csdef{kvt@@#1style@#3}{#4}}
+ {\kvt@error{The #1 style '#3' is already defined}{Use
+ \string#2\space to change an existing style.}}}
+\newcommand\kvt@RenewStyle[4]{%
+ \ifcsundef{kvt@@#1style@#3}
+ {\kvt@error{A #1 style '#3' is not defined}
+ {Use \string#2\space to define a new #1 style.}}
+ {\csdef{kvt@@#1style@#3}{#4}}}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\kvt@UseRowStyles}
-% The |\kvt@UseRowStyle|\marg{styles} macro sets the row keys based on
-% the \meta{row-options} for all styles in the comma-separated list
-% \meta{styles}.
+% \begin{macro}{\kvt@UseTableStyles}
+% \changes{v2.2}{2020/02/24}{Added the macro}
+% The |\kvt@UseRowStyles|\marg{styles} and
+% |\kvt@UseTableStyles|\marg{styles} macros set the keys for the given,
+% comma-separated list of \meta{styles}.
% \begin{macrocode}
\newcommand\kvt@UseRowStyles[1]{%
+ \kvt@UseStyles{row}{Row}{\kvt@NewRowStyle}{#1}}
+\newcommand\kvt@UseTableStyles[1]{%
+ \kvt@UseStyles{table}{Table}{\kvt@NewTableStyle}{#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\kvt@UseStyle}
+% The |\kvt@UseStyle|\marg{type}\marg{fam}\marg{newcmd}\marg{style}
+% macro sets the keys for type \meta{type} based on the \meta{options}
+% stored for the given \meta{style}.
+% The \meta{fam} identifies the
+% \pkgname{xkeyval} family for \meta{type} and \meta{newcmd} is the
+% macro for defining new \meta{type} styles.
+% \begin{macrocode}
+\newcommand\kvt@UseStyle[4]{%
+ \ifcsundef{kvt@@#1style@#4}
+ {\kvt@error{A #1 style '#4' is not defined}
+ {Use \string#3\space to define a new #1 style.}}
+ {\kvt@setcskeys{kvt@@#1style@#4}{#2}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\kvt@UseStyles}
+% The |\kvt@UseStyles|\marg{type}\marg{fam}\marg{newcmd}\marg{styles}
+% macro sets the \meta{type} keys based on the \meta{options} for all
+% styles in the comma-separated list \meta{styles}.
+% The \meta{fam} identifies the
+% \pkgname{xkeyval} family for \meta{type} and \meta{newcmd} is the
+% macro for defining new \meta{type} styles.
+% \begin{macrocode}
+\newcommand\kvt@UseStyles[4]{%
% \end{macrocode}
% We use |\kvt@xkv@disablepreset| to eliminate undesired effects that
% would otherwise be caused by preset values for keys.
@@ -3334,8 +3720,8 @@ cherries,50g,cherries,heat up and add to bowl
% |\setkeys| would then again employ the presets for |Row| (e.g., from a
% |\kvtSet{Row/bg=blue}|) and undesirably overwrite the |bg=red|.
% \begin{macrocode}
- \kvt@xkv@disablepreset[kvt]{Row}{%
- \forcsvlist\kvt@UseRowStyle{#1}}}
+ \kvt@xkv@disablepreset[kvt]{#2}{%
+ \forcsvlist{\kvt@UseStyle{#1}{#2}{#3}}{#4}}}
% \end{macrocode}
% \end{macro}
%
@@ -3737,12 +4123,12 @@ cherries,50g,cherries,heat up and add to bowl
% \begin{macrocode}
\kvt@IfVersion{<}{2.0}{%
\metatblRequire{tabu,longtabu}
- \kvt@DefineStdTabEnv[onepage]{tabu}
- \kvt@DefineStdTabEnv[multipage]{longtabu}
+ \kvt@RegisterShape{onepage}{tabu}{tabu}
+ \kvt@RegisterShape{multipage}{longtabu}{longtabu}
}{%
\metatblRequire{tabularx,longtable,xltabular}
- \kvt@DefineDualTabEnv{onepage}{tabular}{tabularx}
- \kvt@DefineDualTabEnv{multipage}{longtable}{xltabular}
+ \kvt@RegisterShape{onepage}{tabular}{tabularx}
+ \kvt@RegisterShape{multipage}{longtable}{xltabular}
}
% \end{macrocode}
%