% \iffalse meta-comment % % Copyright (C) 2016-2019 by Richard Grewe % ------------------------------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.2 % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.2 or later is part of all distributions of LaTeX % version 1999/12/01 or later. % % \fi % % \iffalse %<*driver> \ProvidesFile{keyvaltable.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{keyvaltable} %<*package> [2019/03/17 v1.0 Package for filling tables using key-value lists] % % %<*driver> \documentclass{ltxdoc} \usepackage{rgltxdoc} \usepackage{etoc} \setcounter{tocdepth}{2} \EnableCrossrefs \CodelineIndex \RecordChanges % the following packages are additional for the examples \usepackage{xintexpr} \usepackage{makecell} \usepackage{gensymb}% for \degree \usepackage{tabularx} \usepackage{longtable} \usepackage{xspace} \newcommand\thispackage{\pkgname{keyvaltable}\xspace} \usepackage{keyvaltable} \NewKeyValTable[ showhead=false,headfmt={\bfseries\footnotesize}, rowbg=black!7!white..black!3!white, showrules=false, shape=onepage]{GoalApproach}{ id: align=r, default=(\alph{kvtRow}), head=\#; goal: align=X[l]; approach: align={X[2,l]}; } \begin{document} \DocInput{keyvaltable.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{0} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \changes{v0.1}{2016/03/13}{Initial version} % \changes{v0.3b}{2018/11/01}{Package author's name change} % % \GetFileInfo{keyvaltable.dtx} % % \DoNotIndex{\newcommand,\newenvironment,\def,\gdef,\edef} % % % \title{The \thispackage package\thanks{This document % corresponds to \thispackage~\fileversion, dated \filedate. % The package is available online at % \url{http://www.ctan.org/pkg/keyvaltable} and % \url{https://github.com/Ri-Ga/keyvaltable}.}} % \author{Richard Grewe \\ \texttt{r-g+tex@posteo.net}} % % \maketitle % % \begin{abstract}\noindent % The \thispackage package's main goal is to facilitate % typesetting tables\ldots\medskip\\ % \begin{KeyValTable}{GoalApproach} % \Row{ % goal={\ldots easily and yet still looking rather nicely}, % approach={through horizontal rules and alternating row background % colors by default;}} % \Row{ % goal={\ldots in a way that separates content from presentation}, % approach={by table rows that are specified as lists of key-value % pairs, where the keys are column names and the corresponding % values are the content of the cell in this row in the respective % column;}} % \Row{ % goal={\ldots with re-usable layout for tables of the same type}, % approach={through named table types, of which each has a list of % columns as well as further properties such as the background % colors of rows; each column, in turn, has a name as well as % further properties such as the heading of the column and the % alignment of the column's content.}} % \end{KeyValTable} % \end{abstract} % % \etocmulticolstyle[2]{\section*{Contents}} % \tableofcontents % \clearpage % % \section{Usage} % % We start with a basic usage example. An explanation of the involved % macros follows afterwards.\medskip % % \begin{LTXexample}[morekeywords={NewKeyValTable,Row,KeyValTable}] % \NewKeyValTable{Recipe}{ % amount: align=r; % ingredient: align=l; % step: align=X[l]; % } % \begin{KeyValTable}{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} % The example code first defines a new table type, |Recipe|, along with % the columns that belong to this type. There are three columns % (|amount|, |ingredient|, and |step|), whose specifications are separated % with semicolons. After the separating |:|, for each column, the macro % configures the column alignment using the |align| key. The alignments % |r| (right) and |l| (left) are the standard |tabular| alignments; the % |X[l]| alignment is provided by the \pkgname{tabu} package (see the % documentation there), which is used by default for creating the % tables. % % After the definition of the table type, the example creates a table of % the newly defined type. For this, the example uses the |KeyValTable| % environment and the |\Row| macro, once for each row. The parameter % |Recipe| of the |KeyValTable| identifies the type of the table. % Most notably, each row can now produced by a single macro in which the % content of the individual cells can be specified by pairs such as % |amount=150g|, which puts ``150g'' into the |amount| column of the % respective row. % % The example above already shows that producing a rather nice-looking % table -- including alternating row colors as well as horizontal rules % -- without further ado. How the \thispackage package can be % used in the general case and how its visual appearance can be % customized is subject of the remainder of this section. % % \subsection{Table Type Definition} % % \NiceDescribeMacro{\NewKeyValTable}{\oarg{options}\marg{tname}\marg{colspecs}\oarg{headers}} % Table types are defined via the |\NewKeyValTable| macro, where % \begin{itemize}[noitemsep] % \item \meta{tname} is the name of the table type, % \item \meta{colspecs} is a semicolon-separated list of individual % column specifications, % and % \item \meta{options}, if provided, specify table type options that % override the default table options; they must then be a % comma-separated list of \meta{property}|=|\meta{value} pairs; % the list of table options can be found at the introduction of the % |KeyValTable| environment on page~\pageref{page:table-options}. % \item \meta{headers}, if provided, specifies custom table header rows. % This argument is further described in \cref{sec:colspan}. % If this argument is omitted, a single header row is produced % (unless |showhead=false| is provided as an option) and the % individual headers in this row are determined by \meta{colspec}. % \end{itemize} % Each column specification is of the form % \begin{center} % \meta{colname}|:| \meta{property}|=|\meta{value}|,| % \meta{property}|=|\meta{value}|,|\ldots % \end{center} % In such a specification, \meta{colname} represents the name of the % column. The \meta{property}|=|\meta{value} pairs configure certain % properties of the column. The \meta{property} can be one of the % following: % \begin{KeyValTable}{KeyDesc} % \Row{key=align, % desc={This property specifies the alignment of content in the % column. The \meta{value} can be set to any column alignment % understood by the |tabu| environment of the \pkgname{tabu} package. % This particularly includes |l|, |c|, |r|, |p|, and |X|.}, % default=l} % \Row{key=default, % desc={This property specifies the default value of a cell in this % column, i.e., in case that a \cmd{\Row} does not provide content % for the cell. By default (i.e., if unset for a column), this is % an empty string.}, % default={\normalfont\itshape(empty)}} % \Row{key=format, % desc={This property specifies a formatting macro for content of the % cell. The macro can take one argument and is provided with the % content of the cell as its argument. % By default, the formatting macro takes the content as is % but puts a \cmd{\strut} before and after the content (to yield a % better vertical spacing).}, % default=\cmd{\kvtStrutted}} % \Row{key=head, % desc={This property specifies the content of the column's header % row. The default value for this property is the name of the % column.}, % default={\normalfont\meta{colname}}} % \Row{key=hidden, % desc={This property specifies whether a table column shall be % displayed or not. The \meta{value} for this property can be |true| % (to hide the cell; the default) or |false| (to display the % cell).}, % default=false} % \end{KeyValTable} % % \subsection{Typesetting Tables}\label{sec:typesetting-tables} % % The first possibility for typesetting a table using the % \thispackage package, is via the |KeyValTable| environment, % which the example at the beginning of this section shows. % The second possibility is described in % Section~\ref{sec:collected-tables}. % % \NiceDescribeEnv{KeyValTable}{\oarg{options}\marg{tname}} % The |KeyValTable| environment creates a table of type \meta{tname}. % The type \meta{tname} must have been created using |\NewKeyValTable| % before. The environment itself already produces a table with the % columns specified for the table type, produces a header row and some % horizontal lines, and sets up background colors of rows. % % The \meta{options} override default configurations, if provided, and % must then be a comma-separated list of \meta{property}|=|\meta{value} % pairs. The following \meta{property} names are available: % \begin{KeyValTable}{KeyDesc} % \Row{key=shape\label{page:table-options}, % desc={This property specifies the table's shape. For \meta{value}, % the package currently supports |multipage| and |onepage| as well % as |tabular|, |tabularx|, and |longtable|. % 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 three values use the respective environment for % producing the table (see \cref{sec:AltTabEnv} for the effect).}, % default=multipage} % \Row{key=width, % desc={This property specifies the width of the table, if the % selected |shape| supports it (see \cref{sec:AltTabEnv}).}, % default={\string\linewidth}} % \Row{key=showhead, % desc={This property specifies whether the head row shall be shown. % The \meta{value} must be a Boolean (i.e., |true| or |false|), % where |true| specifies that the head row is shown and |false| % specifies that the head row is not shown.}, % default=true} % \Row{key=showrules, % desc={This property specifies whether top and bottom rules as well % as a rule below the head row are drawn (|true|) or not (|false|).}, % default=true} % \Row{key=headalign, % desc={This property specifies the alignment for header cells. % If left empty, each header cell receives the same alignment as the % respective column.}, % default={\normalfont\itshape(empty)}} % \Row{key=headfmt, % desc={This property specifies a format to be applied to all header % cells. By default, the property is empty, meaning that header % cells are formatted. Otherwise, the code provided as value to this % key is prepended to the text of the header cells.}, % default={\normalfont\itshape(empty)}} % \Row{key=headbg, % desc={This property specifies the background color of the head row. % The \meta{value} must be a single color specification that is % understood by the \pkgname{xcolor} package. The \meta{value} is % passed directly to the \cs{rowcolor} macro.}, % default={black!14}} % \Row{key=rowbg, % desc={This property specifies the background colors of content rows. % The format of the \meta{value} for this property must be % \meta{oddcolor}|..|\meta{evencolor}. The first row after the % header is colored with \meta{oddcolor}, the second row with % \meta{evencolor}, and so forth. Both colors must be understood by % the \pkgname{xcolor} package.}, % default={white..black!10}} % \end{KeyValTable} % \vref{fig:TableOptionExamples} demonstrates the \meta{options} in % examples. % \begin{figure} % \begin{LTXexample}[morekeywords={shape,showhead,rowbg}] % \NewKeyValTable[shape=onepage, % showhead=false, % rowbg=blue!10..blue!15, % ]{TabOptions}{ % opt: align=l, format=\texttt; % val: align=l, format=\texttt;} % \begin{table}\centering % \begin{KeyValTable}{TabOptions} % \Row{opt=shape, val=onepage} % \Row{opt=showhead, val=false} % \Row{opt=rowbg, val=blue!10..blue!15} % \end{KeyValTable} % \caption{table options demo} % \end{table} % \end{LTXexample} % \begin{LTXexample}[morekeywords={showrules,headbg,headalign,headfmt}] % \NewKeyValTable[showrules=false,headbg=blue!25, % headalign=c,headfmt=\bfseries, % ]{TabOptions2}{ % opt: align=l, format=\texttt; % val: align=l, format=\texttt;} % \begin{KeyValTable}{TabOptions2} % \Row{opt=showrules, val=false} % \Row{opt=headbg, val=blue!25} % \Row{opt=headalign, val=c} % \Row{opt=headfmt, val=\string\bfseries} % \end{KeyValTable} % \end{LTXexample} % \caption{Examples for table options} % \label{fig:TableOptionExamples} % \end{figure} % % % \NiceDescribeMacro{\Row}{\oarg{options}\marg{content}} % A table row is produced by the |\Row| macro. The % \meta{content} must be a comma-separated list of % \meta{cname}|=|\meta{text} pairs. The \meta{cname} identifies a column % that was registered for the table type \meta{tname}. The \meta{text} % specifies the content of the cell in the respective column. Each % column for which no \meta{text} is provided in \meta{content}, will % result in a cell that is filled with the column's default value. % % The \meta{options} argument customizes row properties and is further % explained in \cref{sec:RowOptions}. % % \subsection{Tables of Collected Rows}\label{sec:collected-tables} % % As an alternative to producing a table within a single environment, % the \thispackage package offers a way to scatter individual % rows throughout a document and display the full table later. This % method can be useful when table rows are strongly connected to % portions of text outside of the table. The method then allows % specifying the rows together with the connected text rather than % separately in the table environment. % Table types for this method are defined via |\NewKeyValTable| as % previously described. % % \NiceDescribeMacro{\AddKeyValRow}{\marg{tname}\marg{content}} % A table row is produced by the % |\AddKeyValRow| macro. The \meta{tname} % identifies the table type and the \meta{content} provides the content % of the cells in the row. The format of the \meta{content} is the same % as for the |\Row| macro described in % Section~\ref{sec:typesetting-tables}. % % \NiceDescribeMacro{\ShowKeyValTable}{\oarg{options}\marg{tname}} % A table of all the rows defined via |\AddKeyValRow| can be displayed % by the |\ShowKeyValTable| macro. The % parameters have the same meaning as for the |KeyValTable| environment. % This macro resets the list of rows for the specified table type. % % \NiceDescribeEnv{KeyValTableContent}{\marg{tname}} % For simplifying the addition of rows, the % |KeyValTableContent| environment can be used. In this % environment, the |\Row| macro can be used just like in the % |KeyValTable| environment. The only difference is that the % |KeyValTableContent| environment does not cause the table to be % displayed. For displaying the content collected in % |KeyValTableContent| environments, the |\ShowKeyValTable| macro can be % used. % % The following example demonstrates the use, based on the previously % defined |Recipe| table type. % \begin{LTXexample}[morepreset=\NewKeyValTable{Recipe}{amount:align=r;ingredient:align=l;step:align=X[l]},morekeywords={AddKeyValRow,KeyValTableContent,ShowKeyValTable}] % \AddKeyValRow{Recipe}{amount=3, % ingredient=balls of snow, % step=staple all 3 balls} % \begin{KeyValTableContent}{Recipe} % \Row{amount=1, ingredient=carrot, % step=stick into top ball} % \Row{amount=2, ingredient=coffee beans, % step=put diagonally above carrot} % \end{KeyValTableContent} % \ShowKeyValTable{Recipe} % \end{LTXexample} % % \subsection{Setting Global Defaults} % % \NiceDescribeMacro{\kvtSet}{\marg{options}} % The \thispackage package allows changing the default values % globally for the parameters of tables and columns. This can be done by % using the |\kvtSet| macro. % % \begin{LTXexample}[morekeywords={kvtSet}] % \kvtSet{headbg=red,default=?,align=r} % \NewKeyValTable{Defaults}{x; y} % \begin{KeyValTable}{Defaults} % \Row{x=1} % \Row{y=4} % \end{KeyValTable} % \end{LTXexample} % % Notice the use of the |\NewKeyValTable| in the example. Column % properties, including the separating |:| can be omitted completely, % making the definition of a table type very simple. % % \subsection{Row Numbering and Labeling} % % The mechanism of default column values enables a simple means for % automatic row numbering. For this, one can use one of three row % counters provided by the \thispackage package: |kvtRow|, % |kvtTypeRow|, and |kvtTotalRow|. The counters are explained after the % following example, which demonstrates the use for the case of the % |kvtRow| counter. % % \begin{LTXexample}[morekeywords={thekvtRow,thekvtTypeRow}] % \NewKeyValTable{Numbered1}{ % line: align=r, head=\#, % default=\thekvtRow; % text: align=l, head=\textbf{Text}} % \begin{KeyValTable}{Numbered1} % \Row{text=First row} % \Row{text=Second row} % \end{KeyValTable} % \end{LTXexample} % % \NiceDescribeCounter{kvtRow}{} % The |kvtRow| counter counts the row in the \emph{current} table. The % row number excludes the header row of the table. If the table spans % multiple pages, the row number also excludes the repeated headings on % subsequent pages. % % \NiceDescribeCounter{kvtTypeRow}{} % The |kvtTypeRow| counter counts the rows in the current table and % includes the number of rows of all previous tables of the same type. % % \NiceDescribeCounter{kvtTotalRow}{} % The |kvtTotalRow| counter counts the rows in the current table and % includes the number of rows of all previous tables produced using the % \thispackage package. % % Row numbering can easily be combined with row labeling. % The following example shows how the |format| column property can be % used for this purpose. % \begin{LTXexample}[morekeywords={kvtLabel}] % \NewKeyValTable{Labeled}{ % label: align=r, head=\textbf{\#}, % format=\kvtLabel{kvtRow}; % text: align=l, head=\textbf{Text}} % \begin{KeyValTable}{Labeled} % \Row{text=First row, label=first} % \Row{text=After row \ref{first}} % \end{KeyValTable} % \end{LTXexample} % % \NiceDescribeMacro{\kvtLabel}{\oarg{labelopts}\marg{counter}\marg{label}} % The |\kvtLabel| macro shows the current value of the \meta{counter} -- % in particular |kvtRow|, |kvtTypeRow|, and |kvtTotalRow| -- and sets % the \meta{label} to the value of \meta{counter}. When using the macro % with the |format| property, only the first argument (\meta{counter}) % must be provided, as the above example shows. The second argument % (\meta{label}) is provided by the respective cell content. % % The |\kvtLabel| macro should work well with packages that change the % referencing, like \pkgname{cleveref} or \pkgname{varioref}. When using a % package that adds an optional argument to the |\label| command (like % \pkgname{cleveref} does), the \meta{labelopts} can be used to pass an % optional argument to |\label|. This feature is demonstrated in % \cref{sec:package-cleveref}. % % % \subsection{Column Spanning} % \label{sec:colspan} % % Combining multiple consecutive cells in a row to a single cell (aka % column spanning) can serve several purposes. % The \thispackage package supports the following purposes: % % \begin{enumerate}[noitemsep] % \item grouping of columns through cells in the table's header that % span all cells in the group and assign a joint title to the group; % \item individual combinations of cells in the table data. % \end{enumerate} % % The remainder of this section describes how each of the purposes can % be addressed in |KeyValTable| environments. % % \paragraph{Column groups in table headers} % % Column groups in table headers can be specified by the \meta{headers} % parameter of |\NewKeyValTable|. % The following two examples illustrate how this parameter can be used % for specifying column groups. % The first example produces a single header row in which two columns % are grouped with a single header, one column has a normal header, and % in which one column is not provided with a header. % \begin{LTXexample} % \NewKeyValTable{ColGroup}{ % id: align=r, default=\thekvtRow.; % amount: align=r; ingredient: align=l; % step: align=X[l]; % }[ % amount+ingredient: head=\textbf{ingredient}; % step: head=\textbf{step}, align=l; % ] % \begin{KeyValTable}{ColGroup} % \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} % % The second example shows how multiple header rows can be specified % and, particularly, how the normal column headers can be displayed % through the use of "|::|". % \begin{LTXexample}[width=0.475\hsize] % \NewKeyValTable{ColGroup2}{ % date: align=r, head=\textbf{date}; % min/Berlin: align=r, head=min; % max/Berlin: align=r, head=max; % min/Paris: align=r, head=min; % max/Paris: align=r, head=max; % }[ % min/Berlin+max/Berlin+min/Paris+max/Paris: % head=\textbf{temperature}\\ % min/Paris+max/Paris: head=\textbf{Paris}; % min/Berlin+max/Berlin: head=\textbf{Berlin}\\ % :: % ] % \begin{KeyValTable}{ColGroup2} % \Row{date=01.01.1970, % min/Berlin=0\degree C, max/Berlin=...} % \end{KeyValTable} % \end{LTXexample} % % % The syntax for \meta{headers} is as % follows: % \begin{itemize}[noitemsep] % \item \meta{headers} is a list, separated by "|\\|", where each % element in the list specifies the columns of a single header % \meta{row}. % \item Each \meta{row}, in turn, is also a % list. The elements of this list are separated by "|;|" (as in the % columns specification of |\NewKeyValTable|) and each element % specifies a header \meta{cell}. % \item Each \meta{cell} is of the form % \begin{center} % \meta{col}|+|\ldots|+|\meta{col}|:| \meta{property}|=|\meta{value}|,| % \meta{property}|=|\meta{value}|,|\ldots % \end{center} % where each \meta{col} is the name of a column. % The specified header cell then spans each of the listed columns. % The columns must be displayed consecutively, though not necessarily % in the same order in which they are specified in \meta{cell}. % \item The \meta{property}|=|\meta{value} pairs configure certain % properties of the header cell. The \meta{property} can be one of the % following: % \begin{KeyValTable}{KeyDesc} % \Row{key=align, % desc={This property specifies the alignment of content in the % column. The \meta{value} can be set to any column alignment % understood by the |tabu| environment of the \pkgname{tabu} package. % This particularly includes |l|, |c|, |r|, |p|, and |X|.}, % default=c} % \Row{key=head, % desc={This property specifies the content of the column's header % row. The default value for this property is the name of the % column.}} % \end{KeyValTable} % \end{itemize} % % \paragraph{Manual column spanning with \cmd{\multicolumn}} % The |\multicolumn| macro can be used for the content of a cell. % The effect of this is that a number of subsequent cells are spanned % over with the content of the cell. The following example demonstrates % the use. % \begin{LTXexample}[width=0.475\hsize,morekeywords={multicolumn}] % \NewKeyValTable{MultiCol}{ % col1: align=l; % col2: align=l; % col3: align=l;} % \begin{KeyValTable}{MultiCol} % \Row{col1=1, col2=\multicolumn{1}{r}{2}, col3=3} % \Row{col1=1, col2=\multicolumn{2}{c}{2+3}} % \Row{col1=\multicolumn{2}{c}{1+2}, col3=3} % \Row{col1=\multicolumn{3}{c}{1+2+3}} % \end{KeyValTable} % \end{LTXexample} % A word of warning: % The |\multicolumn| macro implicitly constrains the ordering of % columns. For instance, in the above example, switching columns 2 and 3 % would lead to an error in the second row (because |col2| is the % rightmost column and therefore cannot span two columns) and also in % the third row (because |col1| spans two columns but the second, |col3| % is not empty). Thus, column spanning via |\multicolumn| should be used % with care. % % \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 whether they support % tables that span multiple pages, whether they support |X|-type % (variable-width) columns, and whether their width can be specified % (through the |width| option). Finally, the table also displays the % package(s) that must be loaded manually when the respective shapes are % used. % Examples can be found in \vref{fig:TableTypes}. % \begin{table}[p]\centering % \NewKeyValTable[shape=tabular,headfmt=\bfseries]{ShapeProps}{ % shape: format=\texttt; env: format=\texttt, head=environment; % multipage: align=c; % Xcols: align=c, head=\texttt{X}-cols; % width: align=c; % packages: align=l;} % \begin{KeyValTable}{ShapeProps} % \Row{shape=onepage, env=tabu, multipage=no, Xcols=yes, width=yes, packages={tabu}*} % \Row{shape=multipage, env=longtabu, multipage=yes, Xcols=yes, width=yes, packages={tabu*, longtable*}} % \Row{shape=tabular, env=tabular, multipage=no, Xcols=no, width=no} % \Row{shape=tabularx, env=tabularx, multipage=no, Xcols=yes, width=yes, packages={tabularx}} % \Row{shape=longtable, env=longtable, multipage=yes, Xcols=no, width=no, packages={longtable}} % \end{KeyValTable} % \smallskip\par\raggedright\footnotesize % Packages marked with "*" only need to be loaded if automatic loading % is not disabled via the |NoTabuPkg| option to the \thispackage % package. % \caption{Comparison of table shapes / environments} % \label{tab:TabEnv} % \end{table} % % \begin{figure}[p] % \begin{LTXexample}[width=0.475\hsize, % morekeywords={tabular,longtable}] % \NewKeyValTable[showrules=false]{ShapeNoX}{ % id: align=l, default=\thekvtTypeRow; % l: align=l; c: align=c; r: align=r;}[ % l+c+r: head=\textbf{\kvtTableOpt{shape} shape}\\ ::] % \begin{KeyValTable}[shape=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} % \Row{l=left, c=center, r=right} % \Row{l=left-2, c=2-center-2, r=2-right} % \end{KeyValTable} % \end{LTXexample} % \begin{LTXexample}[width=0.475\hsize, % morekeywords={tabularx,onepage,multipage}] % \NewKeyValTable[showrules=false]{ShapeWithX}{ % id: align=l, default=\thekvtTypeRow; % l: align=l; X: align=X; r: align=r;}[ % l+X+r: head=\textbf{\kvtTableOpt{shape} shape}\\ ::] % \begin{KeyValTable}[shape=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=onepage]{ShapeWithX} % \Row{l=left, X=expandable, r=right} % \Row{l=left-2, X=expandable-2, r=2-right} % \end{KeyValTable} % \begin{KeyValTable}[shape=multipage]{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} % \label{fig:TableTypes} % \end{figure} % % % \subsection{Special Row Formatting}\label{sec:RowOptions} % % Through the \meta{options} argument of the % |\Row|\oarg{options}\marg{content} % and the % |\KeyValRow|\marg{tname}\oarg{options}\marg{content} % macros, special options of the row can be configured. % As with other option arguments of the \thispackage package, the % options must be a comma-separated list of key-value pairs. % The following table lists the supported option keys and their meaning. % % \begin{KeyValTable}{KeyDesc} % \Row{key=hidden, % desc={This property specifies whether the row shall be hidden % (|true|) or not (|false|). If only |hidden| is used without a % value, this is equivalent to |hidden=true|.}, % default=false} % \Row{key=bg, % desc={This property specifies the background color for the % particular row. If left empty, the default color as determined by % the |rowbg| option of the table applies.}, % default={\normalfont\itshape(empty)}} % \Row{key=above, % desc={This property specifies extra vertical space above the row. % Note that this space is currently not colored with the row's % background color but with the page's background color. % The argument, if provided, is directly passed to \cmd{\vspace}.}, % default={\normalfont\itshape(empty)}} % \Row{key=below, % desc={Analogously to |above|, this property specifies extra vertical % space below the row.}, % default={\normalfont\itshape(empty)}} % \Row{key=around, % desc={This property is a short-hand for setting both, |above| and % |below|, to the same value.}, % default={\normalfont\itshape(empty)}} % \end{KeyValTable} % % The following example demonstrates the options. % \begin{LTXexample}[morepreset=\NewKeyValTable{Recipe}{amount:align=r;ingredient:align=l;step:align=X[l]},morekeywords={hidden,above,bg}] % \begin{KeyValTable}{Recipe} % \Row{amount=150g, ingredient=ice cream, % step=put into bowl} % \Row{amount= 50g, ingredient=cherries, % step=heat up and add to bowl} % \Row[hidden]{amount=25g, ingredient=cream, % step=decorate on top} % \Row[above=1ex,bg=red!10!white]{ % step=serve with a smile} % \end{KeyValTable} % \end{LTXexample} % % \subsection{Rules Between Rows} % % Additional horizontal rules between rows can simply be added by % placing the respective rule command between |\Row| commands. % The following example demonstrates this possibility. % \begin{LTXexample}[morepreset=\NewKeyValTable{Recipe}{amount:align=r;ingredient:align=l;step:align=X[l]},morekeywords={midrule}] % \begin{KeyValTable}{Recipe} % \Row{amount=150g, ingredient=ice cream, % step=put into bowl} % \Row{amount= 50g, ingredient=cherries, % step=heat up and add to bowl} % \midrule % \Row{step=serve with a smile} % \end{KeyValTable} % \end{LTXexample} % % % \section{Use with Other Packages} % % \subsection{Named References}\label{sec:package-cleveref} % % The |\kvtLabel| feature of the \thispackage package can be % used together with named references, as provided by the % \pkgname{cleveref} package. A name to a row label can be given by using % the optional first argument to the |\kvtLabel| formatting macro and % specifying the name to use using |\crefname|. The following example % uses ``row'' for the optional argument and ``line'' for the displayed % name of the reference. % \begin{LTXexample} % \usepackage{cleveref} % \crefname{row}{line}{lines} % \NewKeyValTable[headfmt=\bfseries]{NamedRef}{ % label: align=r, head=Line, % format=\kvtLabel[row]{kvtRow}; % text: align=l, head=Text} % \begin{KeyValTable}{NamedRef} % \Row{text=First row, label=one} % \Row{text=After \cref{one}} % \end{KeyValTable} % \end{LTXexample} % % \subsection{Computational Cells} % % The mechanism of cell formatting macros enables a simple means for % automatically computing formulas contained in a column. This can be % done, for instance using the \pkgname{xint} package and defining a % custom format macro (here |\Math|) that takes over the computation. % \begin{LTXexample} % \usepackage{xintexpr} % \newcommand\Math[1]{% % \xinttheexpr trunc(#1, 1)\relax} % \NewKeyValTable{Calculating}{ % type; value: align=r,format=\Math} % \begin{KeyValTable}{Calculating} % \Row{type=simple, value=10+5.5} % \Row{type=advanced, value=0.2*(9+2^8)} % \end{KeyValTable} % \end{LTXexample} % % \subsection{Cell Formatting} % % The \thispackage package can be used together with the % \pkgname{makecell} package in at least two ways: % \begin{enumerate}[noitemsep] % \item formatting header cells using the |head| property of columns; % \item formatting content cells using the |format| property of columns. % \end{enumerate} % The following example gives an impression. % \begin{LTXexample} % \usepackage{makecell} % \renewcommand\theadfont{\bfseries} % \renewcommand\theadalign{lt} % \NewKeyValTable{Header}{ % first: head=\thead{short}; % second: head=\thead{two\\ lines};} % \begin{KeyValTable}{Header} % \Row{first=just a, second=test} % \end{KeyValTable} % \end{LTXexample} % % \section{Related Packages} % % I'm not aware of any \LaTeX{} packages that pursue similar goals or % provide similar functionality. The following \LaTeX{} packages provide % loosely related functionalities to the \thispackage package. % % \begin{description} % \item[\pkgname{ctable}:] % This package focuses on typesetting tables with captions and notes. % With this package, the specification of table content is quite % close to normal |tabular| environments, except that the package's % table creation is done via a macro, |\ctable|. % \item[\pkgname{easytable}:] % This package provides an environment |TAB| which simplifies the % creation of tables with particular horizontal and vertical cell % alignments, rules around cells, and cell width distributions. In % that sense, the package aims at simpler table creation, like % \thispackage. However, the package does not pursue % separation of content from presentation or re-use of table layouts. % \item[\pkgname{tabularkv}:] % Despite the similarity in the name, this package pursues a different % purpose. Namely, this package provides means for specifying table % options such as width and height through an optional key-value % argument to the |tabularkv| environment. This package does not use % a key-value like specification for the content of tables. % \end{description} % % \section{Future Work} % % \begin{itemize} % \item support for further table environments, such as % \pkgname{xltabular}: The existing code structure should make this % not too complicated. Particularly for \pkgname{xltabular}, % a spurious "\verb!missing } inserted!" error occurs. % \item improved row coloring that makes sure that the alternation % re-starts on continued pages of a table that spans several pages % \end{itemize} % % \clearpage % % \StopEventually{} %\iffalse %<*package> %\fi % % \section{Implementation} % \addtocontents{toc}{\protect\setcounter{tocdepth}{0}} % % We use \pkgname{etoolbox} for some convenience macros that make the % code more easily maintainable and use \pkgname{xkeyval} for options % in key--value form. The \pkgname{trimspaces} package is used once for % trimming spaces before a string comparison. % \begin{macrocode} \RequirePackage{etoolbox} \RequirePackage{xkeyval} \RequirePackage{trimspaces} % \end{macrocode} % We use \pkgname{booktabs} for nice horizontal lines and % \pkgname{xcolor} for row coloring. % \begin{macrocode} \PassOptionsToPackage{table}{xcolor} \RequirePackage{xcolor} \RequirePackage{booktabs} % \end{macrocode} % % \subsection{Setting Defaults} % % \begin{macro}{\kvtSet} % The |\kvtSet|\marg{options} set the default options, which apply % to all tables typeset with the package. % \begin{macrocode} \newcommand\kvtSet[1]{\bgroup \def\kvt@@presetqueue{\egroup} \setkeys[kvt]{defaults}{#1}{}% \kvt@@presetqueue} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@lazypreset} % The |\kvt@@lazypreset|\marg{family}\marg{head keys} macro collects a % request collects a request for pre-setting \meta{head keys} in family % key \meta{family}. Using this macro, one can avoid causing problems % with using \pkgname{xkeyval}'s |\presetkeys| inside the \meta{function} % defined for a key (e.g., via |\define@key|). The collected requests % can be performed by expanding the |\kvt@@presetqueue| macro. % \begin{macrocode} \newcommand\kvt@lazypreset[2]{% \appto\kvt@@presetqueue{\presetkeys[kvt]{#1}{#2}{}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@addtableprop} % The |\kvt@addtableprop|\marg{name}\marg{default} macro adds a new % table option, named \meta{name} and with default value \meta{default}. % \begin{macrocode} \newcommand\kvt@addtableprop[2]{% \define@key[kvt]{defaults}{#1}{% \kvt@lazypreset{Table}{#1=##1}}% \presetkeys[kvt]{defaults}{#1=#2}{}% \define@cmdkey[kvt]{Table}{#1}{}% \presetkeys[kvt]{Table}{#1=#2}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@addchoicetableprop} % The |\kvt@addchoicetableprop|\marg{name}\marg{default}\marg{choice} % macro adds a new table option, named \meta{name} and with default % value \meta{default} and possible values from the comma-separated % list provided by \meta{choice}. % \begin{macrocode} \newcommand\kvt@addchoicetableprop[3]{% \define@choicekey[kvt]{defaults}{#1}{#3}{% \kvt@lazypreset{Table}{#1=##1}}% \presetkeys[kvt]{defaults}{#1=#2}{}% \define@choicekey[kvt]{Table}{#1}{#3}% {\csdef{cmdkvt@Table@#1}{##1}}% \presetkeys[kvt]{Table}{#1=#2}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@addbooltableprop} % The |\kvt@addbooltableprop|\marg{name}\marg{default} % macro adds a new table option, named \meta{name} and with default % value \meta{default} and possible values being booleans (|true|, % |false|). % \begin{macrocode} \newcommand\kvt@addbooltableprop[2]{% \define@boolkey[kvt]{defaults}{#1}{% \kvt@lazypreset{Table}{#1=##1}}% \presetkeys[kvt]{defaults}{#1=#2}{}% \define@boolkey[kvt]{Table}{#1}% {\csdef{cmdkvt@Table@#1}{##1}}% \presetkeys[kvt]{Table}{#1=#2}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@addcolumnprop} % The |\kvt@addcolumnprop|\marg{name}\marg{default} macro adds a new % column option, named \meta{name} and with default value % \meta{default}. % \begin{macrocode} \newcommand\kvt@addcolumnprop[2]{% % \end{macrocode} % The following makes the \meta{name} available as an option for % |\kvtSet| for setting a global default value to this column option. % \begin{macrocode} \define@key[kvt]{defaults}{#1}{% \kvt@lazypreset{Column}{#1=##1}}% \presetkeys[kvt]{defaults}{#1=#2}{}% % \end{macrocode} % The following makes the \meta{name} available as an option for % the \meta{colspecs} of |\NewKeyValTable| for setting a default value % to the particular column. % \begin{macrocode} \define@key[kvt]{Column}{#1}{% \csdef{kvt@col@#1@\kvt@@column}{##1}}% \presetkeys[kvt]{Column}{#1=#2}{}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@addchoicecolumnprop} % The |\kvt@addchoicecolumnprop|\marg{name}\marg{initial}\marg{default}\marg{choice} % macro adds a new column option, named \meta{name}, with initial value % \meta{initial}, with default argument value \meta{default}, and % possible values from the comma-separated list provided by % \meta{choice}. % \begin{macrocode} \newcommand\kvt@addchoicecolumnprop[4]{% % \end{macrocode} % The following makes the \meta{name} available as an option for % |\kvtSet| for setting a global default value to this column option. % \begin{macrocode} \define@choicekey[kvt]{defaults}{#1}{#4}[#3]{% \kvt@lazypreset{Column}{#1=##1}}% \presetkeys[kvt]{defaults}{#1=#2}{}% % \end{macrocode} % The following makes the \meta{name} available as an option for % the \meta{colspecs} of |\NewKeyValTable| for setting a default value % to the particular column. % \begin{macrocode} \define@choicekey[kvt]{Column}{#1}{#4}[#3]% {\csdef{kvt@col@#1@\kvt@@column}{##1}}% \presetkeys[kvt]{Column}{#1=#2}{}% } % \end{macrocode} % \end{macro} % % The following are the known column properties and their defaults as % well as the known table properties and their defaults. % \changes{v0.2}{2016/05/21}{Added ``shape'' table option} % \changes{v1.0}{2018/12/30}{Enabled default ``true'' for ``hidden''} % \begin{macrocode} \kvt@addtableprop{rowbg}{white..black!10} \kvt@addtableprop{headbg}{black!14} \kvt@addbooltableprop{showhead}{true} \kvt@addbooltableprop{showrules}{true} \kvt@addtableprop{headfmt}{} \kvt@addtableprop{headalign}{} \kvt@addtableprop{width}{\linewidth} % \end{macrocode} % When adding further |shape| options below, ensure to also add a % corresponding |\kvt@DefineStdTabEnv| counterpart further below in the % code. % \begin{macrocode} \kvt@addchoicetableprop{shape}{multipage}{% multipage,onepage,tabular,longtable,tabularx} \kvt@addcolumnprop{default}{} \kvt@addcolumnprop{format}{\kvtStrutted} \kvt@addcolumnprop{align}{l} \kvt@addcolumnprop{head}{} \kvt@addchoicecolumnprop{hidden}{false}{true}{false,true} \kvtSet{} % \end{macrocode} % % \begin{macro}{\kvtTableOpt} % The |\kvtTableOpt|\marg{optname} macro, inside a |KeyValTable| % environment, expands to the value of the table option \meta{optname}. % \begin{macrocode} \newcommand\kvtTableOpt[1]{\csname cmdkvt@Table@#1\endcsname} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvtStrutted} % The |\kvtStrutted|\marg{arg} macro prefixes and suffixes % the argument \meta{arg} with a |\strut|. When used for formatting % cell content, this makes sure that there is some vertical space % between the content of a cell and the top and bottom of the row. % \changes{v0.3}{2016/06/06}{Fix for cells with vertical material} % \begin{macrocode} \newcommand\kvtStrutted[1]{\strut #1\ifhmode\expandafter\strut\fi} % \end{macrocode} % \end{macro} % % % \subsection{Declaring Key-Value Tables} % % \begin{macro}{\NewKeyValTable} % The % |\NewKeyValTable|\oarg{options}\marg{tname}\marg{colspecs}\oarg{headers} % declares a new key-value table type, identified by the given % \meta{tname}. The columns of the table type are specified by % \meta{colspecs}. The optional \meta{options}, if given, override the % default table options for tables of type \meta{tname}. % \changes{v0.2}{2016/05/21}{Added table-type options} % \changes{v1.0}{2019/02/03}{Added optional headers argument} % \begin{macrocode} \newcommand\NewKeyValTable[3][]{% \@ifnextchar[%] {\kvt@NewKeyValTable{#1}{#2}{#3}}% {\kvt@NewKeyValTable{#1}{#2}{#3}[]}} % \end{macrocode} % The % |\kvt@NewKeyValTable|\marg{options}\marg{tname}\marg{colspecs}\oarg{headers} % macro is an auxiliary macro used for parsing the fourth, optional % argument of |\NewKeyValTable|. % \begin{macrocode} \def\kvt@NewKeyValTable#1#2#3[#4]{% % \end{macrocode} % First initialize the ``variables''. % \begin{macrocode} \csdef{kvt@options@#2}{#1}% \csdef{kvt@headings@#2}{}% % \end{macrocode} % The following adds a zero-width column to the left of every table. % This column serves the purpose of "holding" the code that % \thispackage uses for formatting a row (e.g., parsing |\Row| % arguments). This code is partly not expandable. % The reason for not putting this code into the first actual colum of % tables is that this code would prevent |\multicolumn| to be used in % the first column. % \changes{v1.0}{2019/02/03}{Added zero-width column for \cs{multicolumn}} % Fixme: Ideally, the whole extra column should be removed through % sufficient use of |\noalign| in headers and rows, such that even the % presence of |\multicolumn| does not produce errors. % \begin{macrocode} \csedef{kvt@alignments@#2}{p{0pt}\expandonce\kvt@HackIntercolSpace}% \csdef{kvt@colkeys@#2}{}% \csdef{kvt@rowcount@#2}{0}% \csdef{kvt@rows@#2}{}% \csdef{kvt@headings@#2}{\kvt@defaultheader} \listadd\kvt@alltables{#2}% % \end{macrocode} % Now parse \meta{colspecs}, a semicolon-separated list of individual % column specifications, and add the columns to the table. Each % |\do|\marg{colspec} takes the specification for a single column. % \begin{macrocode} \def\do##1{% \kvt@parsecolspec{#2}##1::\@undefined}% \kvt@dossvlist{#3}% % \end{macrocode} % The following terminates the argument list of |\kvt@defaultheader|. % \begin{macrocode} \csappto{kvt@headings@#2}{{\@nil}}% % \end{macrocode} % Finally, parse \meta{headers}, also a semicolon-separated list of % individual column groups, where |\\| marks a new row of column groups. % If \meta{headers} is omitted (or empty), then simply take the result % of |\kvt@parsecolspec| as the header row. % \begin{macrocode} \ifstrempty{#4} {\csdef{kvt@headrowcount@#2}{1}} {\kvt@parseheadrows{#2}{#4}}% } % \end{macrocode} % The % |\kvt@parsecolspec|\marg{tname}\meta{cname}|:|\meta{config}|:|\meta{empty}|\@undefined| % takes a configuration \meta{config} for a column \meta{cname} in table % \meta{tname} and adds the column with the configuration to the table. % \begin{macrocode} \def\kvt@parsecolspec#1#2:#3:#4\@undefined{% \def\kvt@@column{#1@#2}% \setkeys[kvt]{Column}{#3}% % \end{macrocode} % The following stores the column's properties. The column is only added % if the |hidden| option is not set to |true|. % \begin{macrocode} \ifcsstring{kvt@col@hidden@#1@#2}{true}{}{% \cseappto{kvt@alignments@#1}{\csexpandonce{kvt@col@align@#1@#2}}% % \end{macrocode} % Append the column heading to \cs{kvt@headings@\meta{tname}}, which % collects arguments to |\kvt@defaultheader|. Hence, the appended tokens % are enclosed in curly braces. If no |head| is specified for the % column, \meta{cname} is used for the column head. Otherwise, the % |head| value is used. % \begin{macrocode} \ifcsvoid{kvt@col@head@#1@#2}% {\csappto{kvt@headings@#1}{{#2}}}% {\cseappto{kvt@headings@#1}{{\csexpandonce{kvt@col@head@#1@#2}}}}% \listcsadd{kvt@colkeys@#1}{#2}% }% % \end{macrocode} % The following creates the column key that can be used by the row % macros to set the content of the column's content in that row. % \begin{macrocode} \define@cmdkey[KeyValTable]{#1}{#2}[]{}% \presetkeys[KeyValTable]{#1}{#2}{}% } % \end{macrocode} % \end{macro} % % % \begin{macro}{\kvt@defaultheader} % The |\kvt@defaultheader|\marg{head1}\ldots\marg{headn}|\@nil| macro, % takes $n$ header cell titles, \meta{head1} to \meta{headn} and formats % them based on the |headfmt| and |headalign| options. % More precisely, when fully expanded, |\kvt@defaultheader| yields % "\meta{rowcolor}|& |\meta{fmthead1}| & |\ldots| & |\meta{fmtheadn}|\tabularnewline|". % In the above, \meta{rowcolor}=|\rowcolor{|\meta{headbg}|}|. % \begin{macrocode} \newcommand\kvt@defaultheader{% \noexpand\rowcolor{\cmdkvt@Table@headbg}% \kvt@defaultheader@i} \newcommand\kvt@defaultheader@i[1]{% \kvt@ifnil{#1}{\noexpand\tabularnewline}{% \unexpanded{&}% \ifdefvoid\cmdkvt@Table@headalign {\expandonce\cmdkvt@Table@headfmt\unexpanded{#1}} {\noexpand\multicolumn{1}{\expandonce\cmdkvt@Table@headalign} {\expandonce\cmdkvt@Table@headfmt\unexpanded{#1}}}% \kvt@defaultheader@i}} % \end{macrocode} % \begin{macro}{\kvt@ifnil} % The |\kvt@ifnil|\marg{val}\marg{iftrue}\marg{iffalse} macro expands to % \meta{iftrue} if \meta{val} is |\@nil|, and expands to \meta{iffalse} % otherwise. % Fixme: The |\relax| in the following is not fully ideal as it is not % swallowed by the |\ifx| and therefore remains in the macro's % expansion. % \begin{macrocode} \newcommand\kvt@ifnil[1]{% \ifx\@nil#1\relax \expandafter\@firstoftwo\else \expandafter\@secondoftwo\fi} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\kvt@HackIntercolSpace} % The |\kvt@HackIntercolSpace| macro captures the negative space that % cancels out the spacing otherwise caused by the extra column that the % package adds. % \begin{macrocode} \newcommand\kvt@HackIntercolSpace{% @{\hspace{-.5\arrayrulewidth}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@alltables} % The |\kvt@alltables| is an \pkgname{etoolbox} list containing the names % of all tables declared by |\NewKeyValTable|. % \begin{macrocode} \newcommand\kvt@alltables{} % \end{macrocode} % \end{macro} % % % \subsection{Custom Column Headers} % % \begin{macro}{\kvt@parseheadrows} % The |\kvt@parseheadrows|\marg{tname}\marg{headers} % macro parses the \meta{headers} argument of |\NewKeyValTable|. % \begin{macrocode} \newcommand\kvt@parseheadrows[2]{% \csdef{kvt@@colgroups@#1}{}% \csdef{kvt@headrowcount@#1}{0}% \bgroup \def\kvt@@parseheadrows{}% % \end{macrocode} % Now loop over \meta{headers} to split \meta{headers} by |\\|. % Append each item, which specifies a single header row, to % |\kvt@@parseheadrows| for subsequent parsing by |\kvt@parseheadrow|. % If an item equals the special sequence "|::|", then the original % 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}{::} {\appto\kvt@@parseheadrows{% \cseappto{kvt@@colgroups@#1}{% \csexpandonce{kvt@headings@#1}}}} {\appto\kvt@@parseheadrows{\kvt@parseheadrow{#1}{##1}}}% % \end{macrocode} % Increment the header row counter for each |\\|-separated item of % \meta{headers}. % \begin{macrocode} \appto\kvt@@parseheadrows{\csedef{kvt@headrowcount@#1}{% \the\numexpr\csuse{kvt@headrowcount@#1}+1\relax}}% }\kvt@dobrklist{#2}% % \end{macrocode} % Finally, escape the inner group and overwrite the headings % with the result of the parsing. % \begin{macrocode} \expandafter\egroup\kvt@@parseheadrows \csletcs{kvt@headings@#1}{kvt@@colgroups@#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@parseheadrow} % The |\kvt@parseheadrow|\marg{tname}\marg{colspec} macro parses a % single header row and appends the resulting table code to % \cs{kvt@@colgroups@\meta{tname}}. % \begin{macrocode} \newcommand\kvt@parseheadrow[2]{% \bgroup % \end{macrocode} % First parse \meta{colspec}, populating the % \cs{kvt@@colgrpof@\meta{colname}} macros that associate each column % with the column group to which the column belongs. % \begin{macrocode} \def\do##1{\kvt@parsehdcolspec{#1}##1::\@undefined}% \kvt@dossvlist{#2}% % \end{macrocode} % Initialize variables for the subsequent loop. % The |\kvt@@tmpgrphd| macro collects the code for the cells of the % current header row. The |\kvt@@span| counter specifies how many % columns the current cell shall span. % Finally, |\kvt@@curgrp| and |\kvt@@lastgrp| hold the name of the group % in which the current column and, respectively, previous column are in. % Each of the two macros is undefined if there is no such column group. % \begin{macrocode} \let\kvt@@tmpgrphd\@empty \kvt@@span\z@ \undef\kvt@@curgrp \undef\kvt@@lastgrp % \end{macrocode} % Next, loop over all displayed (non-hidden) columns stored in % \cs{kvt@colkeys@\meta{tname}}. The following |\do|\marg{colname} % collects (spanned) columns as specified in \meta{colspec}, in the % ordering in which the table's columns are displayed. The spanned % columns are stored in |\kvt@@tmpgrphd|. % \begin{macrocode} \def\do##1{\letcs\kvt@@curgrp{kvt@@colgrpof@##1}% \ifdefequal\kvt@@curgrp\kvt@@lastgrp % \end{macrocode} % If the column group has not changed, simply increase the spanning % counter. % \begin{macrocode} {\advance\kvt@@span\@ne}% % \end{macrocode} % Otherwise, i.e., if the column group has changed, then conclude the % previous column (if there was one) and reset the span to 1 (to count % for the column in |\kvt@@curgrp|) and set |\kvt@@lastgrp| to the % current one. % \begin{macrocode} {\ifnum\kvt@@span>\z@ \expandafter\kvt@concludecolumn\fi \ifdefvoid\kvt@@curgrp{}{\ifcsdef{kvt@@colgrpdone@\kvt@@curgrp}{% \kvt@error{Column group `\kvt@@curgrp' must consist of only consecutive columns, but it is not}% {Compare `|\kvt@@curgrp|' to the column ordering as specified in `\string\NewKeyValTable{#1}'}}{}}% \kvt@@span\@ne \let\kvt@@lastgrp\kvt@@curgrp}% }\dolistcsloop{kvt@colkeys@#1}% \kvt@concludecolumn % \end{macrocode} % Finally, conclude the whole header row and append the row to the % overall list of rows, stored in \cs{kvt@@colgroups@\meta{tname}}, % while ending the current \hologo{TeX} group. % \begin{macrocode} \appto\kvt@@tmpgrphd{\tabularnewline}% \edef\do{\noexpand\csappto{kvt@@colgroups@#1}{% \noexpand\noexpand\noexpand\rowcolor{\noexpand\cmdkvt@Table@headbg}% \noexpand\unexpanded{\expandonce{\kvt@@tmpgrphd}}}}% \expandafter\egroup\do} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@@span} % The counter |\kvt@@span| is used temporarily in macros for counting % how many columns are spanned by column groups. % \begin{macrocode} \newcount\kvt@@span % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@concludecolumn} % The |\kvt@concludecolumn| macro appends a cell, potentially spanning % multiple columns, to the row under construction (which is in % |\kvt@@tmpgrphd|). % \begin{macrocode} \newcommand\kvt@concludecolumn{% % \end{macrocode} % The following conditional checks whether this is the first column % group in the header row. If this is the case, then the % |\kvt@@extraalign| macro is set to |\kvt@HackIntercolSpace|, such that % the |\multicolumn| below does not throw away this spacing. % \begin{macrocode} \ifdefequal\kvt@@tmpgrphd\@empty {\let\kvt@@extraalign\kvt@HackIntercolSpace} {\let\kvt@@extraalign\@empty}% \appto\kvt@@tmpgrphd{&}% \ifdefvoid\kvt@@lastgrp{}{% \eappto\kvt@@tmpgrphd{\noexpand\multicolumn {\the\kvt@@span} {\expandonce\kvt@@extraalign \csexpandonce{kvt@@colgrp@align@\kvt@@lastgrp}} {\csexpandonce{kvt@@colgrp@head@\kvt@@lastgrp}}}% % \end{macrocode} % Mark the column group as already used and concluded, such that another % use of the same column group can be detected and raise an error. % \begin{macrocode} \cslet{kvt@@colgrpdone@\kvt@@lastgrp}{\@ne}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@parsehdcolspec} % The |\kvt@parsehdcolspec|\marg{tname}\meta{cname}|:|\meta{config}|:|\meta{empty}|\@undefined| % macro parses a single header column (resp. column group), \meta{cname}. % For a column group, \meta{cname} can consist of multiple, % "+"-separated column names. % \begin{macrocode} \def\kvt@parsehdcolspec#1#2:#3:#4\@undefined{% % \end{macrocode} % First link the individual columns of a column group to the group. % In this, ensure that no column is contained in more than one column % group. % \begin{macrocode} \def\kvt@@colreg##1{% \ifinlistcs{##1}{kvt@colkeys@#1}{} {\kvt@error{Column `##1' referenced in column group `#2' not known in table type `#1'}{Check the \string\NewKeyValTable{#1} for the names of known columns and check `##1' for a typo.}}% \ifcsmacro{kvt@@colgrpof@##1} {\kvt@error{Column `##1' used in more than one column group} {Check the fourth, optional argument of \string\NewKeyValTable and eliminate multiple occurrences of column `##1'.}} {\csdef{kvt@@colgrpof@##1}{#2}}% }\kvt@forpsvlist{\kvt@@colreg}{#2}% % \end{macrocode} % Now parse the \meta{config} of the column, resp. column group. % \begin{macrocode} \def\kvt@@colgrp{#2}% \setkeys[kvt]{ColGroup}{#3}} % \end{macrocode} % \end{macro} % % The following defines the options for header cells. % \begin{macrocode} \define@key[kvt]{ColGroup}{head}{% \csdef{kvt@@colgrp@head@\kvt@@colgrp}{#1}} \define@key[kvt]{ColGroup}{align}{% \csdef{kvt@@colgrp@align@\kvt@@colgrp}{#1}} \presetkeys[kvt]{ColGroup}{align=c}{}% % \end{macrocode} % % % \subsection{Row Numbering and Labeling} % % The following counters simplify row numbering in key-value tables. % One can use a table-local counter (|kvtRow|), a table-type local % counter (|kvtTypeRow|), and a global counter (|kvtTotalRow|). % % \begin{macro}{kvtRow} % The |kvtRow| counter can be used by cells to get the current row % number. This row number (in contrast to |taburow|) does not count % table headers. That is, |kvtRow| provides the current \emph{content} % row number, even in tables that are spread over multiple pages. % \begin{macrocode} \newcounter{kvtRow} % \end{macrocode} % \end{macro} % \begin{macro}{kvtTypeRow} % The |kvtTypeRow| counter can be used by cells to get the current row % number, including all previous rows of tables of the same type. This % counter works together with the \cs{kvt@rowcount@\meta{tname}} macro, % which keeps track of the individual row counts of the \meta{tname} % type. % \begin{macrocode} \newcounter{kvtTypeRow} % \end{macrocode} % \end{macro} % \begin{macro}{kvtTotalRow} % The |kvtTotalRow| counter can be used by cells to get the current row % number, including all previous |KeyValTable| tables. % \begin{macrocode} \newcounter{kvtTotalRow} \setcounter{kvtTotalRow}{0} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvtLabel} % The |\kvtLabel|\oarg{labelopts}\marg{counter}\marg{label} macro sets % a label, named \meta{label}, for the current value of the \LaTeX{} % counter named \meta{counter}. % \changes{v0.2}{2016/05/22}{Added macro for row labeling} % \changes{v0.3}{2016/06/09}{Robustified for use with, e.g., \pkgname{cleveref}} % \begin{macrocode} \newcommand\kvtLabel[3][]{% % \end{macrocode} % The following imitates a |\refstepcounter| in the sense of setting the % current label, but it does not touch the \meta{counter} (in case % someone added some custom hooks to them). % \begin{macrocode} \setcounter{kvt@LabelCtr}{\value{#2}}% \addtocounter{kvt@LabelCtr}{-1}% \refstepcounter{kvt@LabelCtr}% % \end{macrocode} % Next, define the \meta{label} (if provided) and show the value of % \meta{counter}. % \begin{macrocode} \ifstrempty{#3}{}{% \ifstrempty{#1}{\label{#3}}{\label[#1]{#3}}}% \csuse{the#2}} % \end{macrocode} % \end{macro} % \begin{macro}{kvt@LabelCtr} % The |kvt@LabelCtr| counter is an auxiliary counter for setting labels, % used by |\kvtLabel|. % \begin{macrocode} \newcounter{kvt@LabelCtr} % \end{macrocode} % \end{macro} % % \subsection{Key-Value Table Content} % % \begin{environment}{KeyValTable} % The |KeyValTable|\oarg{options}\marg{tname} environment encloses a new % table whose type is identified by the given \meta{tname}. Table options % can be overridden by providing \meta{options}. % \begin{macrocode} \newenvironment{KeyValTable}[2][]{% \bgroup% % \end{macrocode} % \begin{macro}{\Row} % The |\Row|\oarg{options}\marg{content} macro is made available locally % in the |KeyValTable| environment. % \begin{macrocode} \def\Row{\kvt@AddKeyValRow {\noalign\bgroup}{\expandafter\egroup\kvt@@row}{#2}}% % \end{macrocode} % \end{macro} % \begin{macrocode} \kvt@SetOptions{#2}{#1}% \csuse{kvt@StartTable@\cmdkvt@Table@shape}{#2}% }{% \csuse{kvt@EndTable@\cmdkvt@Table@shape}% \egroup} % \end{macrocode} % The following saves the row counter value outside the table % environment but still in the then-local scope. % \begin{macrocode} \AfterEndEnvironment{KeyValTable}{% \csdef{kvt@rowcount@\kvt@@recenttable}{\thekvtTypeRow}} % \end{macrocode} % \end{environment} % % \begin{macro}{\kvt@SetOptions} % The |\kvt@SetOptions|\marg{tname}\marg{options} set the 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]{% \bgroup\edef\kvt@@do{\egroup\noexpand% \setkeys[kvt]{Table}% {\csexpandonce{kvt@options@#1},\unexpanded{#2}}% }\kvt@@do} % \end{macrocode} % \end{macro} % % \subsubsection{Table Environment Code} % % \begin{macro}{\kvt@StartTabularlike} % The % |\kvt@StartTabularlike|\marg{env}\marg{tname}\marg{bLong}\marg{bTabu}\marg{bWidth} % macro begins a table environment for the given table type \meta{tname}. % The \meta{env} parameter specifies the concrete environment name. % The parameters \meta{bLong}, \meta{bTabu}, and \meta{bWidth} are % Boolean parameters (expecting value |true| or value |false|). % They specify whether the table environment supports multi-page tables % (\meta{bLong}), whether the environment is a \pkgname{tabu} % environment (\meta{bTabu}), and whether the environment supports % specifying the width of the table (\meta{bWidth}). % \begin{macrocode} \newcommand\kvt@StartTabularlike[5]{% % \end{macrocode} % The |\kvt@@recenttable| allows the |\AfterEndEnvironment| hook for % |KeyValTable| to access the most recent table type. % \begin{macrocode} \gdef\kvt@@recenttable{#2}% % \end{macrocode} % \changes{v1.0}{2019/02/18}{Implemented \texttt{showrules} option} % \begin{macrocode} \ifbool{kvt@Table@showrules} {\def\kvt@@rule##1{\csuse{##1rule}}} {\def\kvt@@rule##1{}}% \csuse{kvt@@patchenvend@#1}% \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. % \begin{macrocode} \bgroup\edef\kvt@@do{\egroup \ifbool{#4}{}{\noexpand\kvt@dottedrowcolors {\ifbool{kvt@Table@showhead} {\the\numexpr\csuse{kvt@headrowcount@#2}+1\relax} {1}}% {\expandonce\cmdkvt@Table@rowbg}}% % \end{macrocode} % \changes{v1.0}{2019/03/09}{Added \texttt{width} option} % \begin{macrocode} \expandafter\noexpand\csname #1\endcsname \ifbool{#5} {\ifbool{#4} {to \expandonce\cmdkvt@Table@width} {{\expandonce\cmdkvt@Table@width}}} {}% {\csexpandonce{kvt@alignments@#2}}% \noexpand\kvt@@rule{top}% % \end{macrocode} % \changes{v0.3}{2016/06/05}{Added \texttt{showhead} option} % \begin{macrocode} \ifbool{kvt@Table@showhead} {\csuse{kvt@headings@#2}\noexpand\kvt@@rule{mid}} {}% \ifbool{#4} {\noexpand\taburowcolors 2{\expandonce\cmdkvt@Table@rowbg}}{}% \ifbool{#3}{\noexpand\endhead}{}% }\kvt@@do} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@stepcounters} % The |\kvt@stepcounters|\oarg{delta} macro increments all row counters % by \meta{delta}. If \meta{delta} is omitted, \meta{delta}=1. % \begin{macrocode} \newcommand\kvt@stepcounters[1][1]{% \addtocounter{kvtRow}{#1}% \addtocounter{kvtTypeRow}{#1}% \addtocounter{kvtTotalRow}{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@DefineStdTabEnv} % The % |\kvt@DefineStdTabEnv|\oarg{shape}\marg{env}\marg{bLong}\marg{bTabu}\marg{bWidth}\marg{endpatch} % 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. % The \meta{endpatch} parameter expects macro code that shall be run % at the beginning of the |KeyValTable| environment to (locally) patch % macros related to the end code of \meta{env} for ensuring % that the bottom rule, |\kvt@@rule{bottom}|, is displayed. % If \meta{endpatch} is empty, the rule is displayed via % \cs{kvt@EndTable@\meta{shape}}. Otherwise, % \cs{kvt@EndTable@\meta{shape}} equals \cs{end\meta{env}}. % Environments such as |tabularx| require the latter to parse for the % end of the environment. % The parameters \meta{bLong}, \meta{bTabu}, and \meta{bWidth} % are the same as for |\kvt@StartTabularlike|. % % 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[6][]{% \expandafter\newcommand\csname kvt@StartTable@#1\endcsname[1]{% \kvt@StartTabularlike{#2}{##1}{#3}{#4}{#5}}% \csedef{kvt@EndTable@#1}{% \ifstrempty{#6}{\noexpand\kvt@@rule{bottom}}{}% \expandafter\noexpand\csname end#2\endcsname}% \ifstrempty{#6}{}{\csdef{kvt@@patchenvend@#2}{#6}}} % \end{macrocode} % \end{macro} % % The following lines define the macros for the various table shapes / % environments. % \begin{macrocode} \kvt@DefineStdTabEnv{tabular}{false}{false}{false}{} \kvt@DefineStdTabEnv{longtable}{true}{false}{false}{} \kvt@DefineStdTabEnv{tabularx}{false}{false}{true}{% \preto\TX@endtabularx{\toks@\expandafter{\the\toks@ \kvt@@rule{bottom}}}} \kvt@DefineStdTabEnv{xltabular}{true}{false}{true}{% \preto\XLT@ii@TX@endtabularx{\toks@\expandafter{\the\toks@ \kvt@@rule{bottom}}}} \kvt@DefineStdTabEnv[onepage]{tabu}{false}{true}{true}{} \kvt@DefineStdTabEnv[multipage]{longtabu}{true}{true}{true}{} % \end{macrocode} % % \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. % \begin{macrocode} \newcommand\kvt@dottedrowcolors[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} % % \subsubsection{Environment-Independent Parts} % % The following block declares the known row options. % \begin{macrocode} \define@cmdkey[kvt]{Row}{bg}{}% \define@boolkey[kvt]{Row}{hidden}[true]{}% \define@cmdkey[kvt]{Row}{below}{} \define@cmdkey[kvt]{Row}{above}{} \define@cmdkey[kvt]{Row}{around}{% \def\cmdkvt@Row@above{#1}\def\cmdkvt@Row@below{#1}} % \end{macrocode} % % \begin{macro}{\kvt@AddKeyValRow} % The % |\kvt@AddKeyValRow|\marg{pre}\marg{post}\marg{tname}\oarg{options}\marg{content} % macro composes a row for the table of type \meta{tname} from the given % \meta{content} and \meta{options}. The \meta{content} is a % key-value list that specifies the content of the individual cells in % the row. The result is returned in macro |\kvt@@row|. % The arguments \meta{pre} and \meta{post} are expanded at the very % beginning, resp.\@ end of the macro. % They allow to control grouping (|\bgroup| and |\egroup|) as well as % table placement via |\noalign|. % \changes{v1.0}{2019/03/17}{Added \oarg{options}} % \begin{macrocode} \newcommand\kvt@AddKeyValRow[3]{% #1% % \end{macrocode} % It's essential that \meta{pre} above comes even before |\@ifnextchar| % and, therefore, cannot be moved into |\kvt@AddKeyValRow@i|: % The |\@ifnextchar| is not fully expandable and therefore any % |\noalign| (in \meta{pre}) following |\@ifnextchar| would lead to % "misplaced |\noalign|" errors. % \begin{macrocode} \@ifnextchar[%] {\kvt@AddKeyValRow@i{#2}{#3}} {\kvt@AddKeyValRow@i{#2}{#3}[]}} % \end{macrocode} % \end{macro} % \begin{macro}{\kvt@AddKeyValRow@i} % The % |\kvt@AddKeyValRow@i|\marg{post}\marg{tname}\oarg{options}\marg{content} % macro parses \meta{options} and evaluates the |hidden| option. % \begin{macrocode} \def\kvt@AddKeyValRow@i#1#2[#3]#4{% \setkeys[kvt]{Row}{#3}% \ifbool{kvt@Row@hidden} {\let\kvt@@row\@empty #1} {\kvt@AddKeyValRow@ii{#1}{#2}{#4}}} % \end{macrocode} % \end{macro} % \begin{macro}{\kvt@AddKeyValRow@ii} % The % |\kvt@AddKeyValRow@ii|\marg{post}\marg{tname}\marg{content} % macro mainly processes \meta{content} as well as \meta{options} % that have already been parsed by |\kvt@AddKeyValRow@i|. % \begin{macrocode} \def\kvt@AddKeyValRow@ii#1#2#3{% \setkeys[KeyValTable]{#2}{#3}% % \end{macrocode} % Initialize and first add the |\noalign| material to the row. % \begin{macrocode} \def\kvt@@row{}% \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}}}% % \end{macrocode} % Place the |everyrow| hook after |\noalign|. % \begin{macrocode} \expandafter\appto\expandafter\kvt@@row\expandafter{\kvt@@everyrow} % \end{macrocode} % The following loop uses |\do|\marg{cname} to append the content of % all columns (in the given format and using the given default value), % where each column value is in % \cs{cmdKeyValTable@\meta{tname}@\meta{cname}}. % Note that currently the default value is formatted using the given % format macro -- a design decision. % \changes{v1.0}{2019/02/03}{Added \cs{multicolumn} support} % \begin{macrocode} \kvt@@span=0\relax \def\do##1{% % \end{macrocode} % First recover the cell content (either the specified value for the row % or, if no value is specified for the row, the cell's default value) % without formatting. % \begin{macrocode} \ifcsvoid{cmdKeyValTable@#2@##1} {\letcs\kvt@@cell{kvt@col@default@#2@##1}} {\letcs\kvt@@cell{cmdKeyValTable@#2@##1}}% % \end{macrocode} % Separately also already create the formatted content. % \begin{macrocode} \edef\kvt@@fmtcell{\csexpandonce{kvt@col@format@#2@##1}{% \expandonce\kvt@@cell}}% % \end{macrocode} % Next, check whether a column-spanning cell is active % ($\cs{kvt@@span}>0$). If this is the case, ensure that if the raw cell % content in the current column is empty, then formatting does not make % the cell non-empty and, thereby, cause errors with the active % column-spanning cell. % \begin{macrocode} \ifnumgreater\kvt@@span{0} {\advance\kvt@@span\m@ne \ifstrempty\kvt@@cell{\def\kvt@@fmtcell{}}{}} {\appto\kvt@@row{&}}% % \end{macrocode} % Now check whether the cell itself spans multiple columns. % \begin{macrocode} \expandafter\kvt@CheckMulticolumn\kvt@@cell \relax\relax\relax\relax\@undefined{#2}{##1}% \expandafter\appto\expandafter\kvt@@row\expandafter{\kvt@@fmtcell}% }\dolistcsloop{kvt@colkeys@#2}% % \end{macrocode} % Finally, add the concluding newline for the row as well as % the vertical space after the row, if requested. % \begin{macrocode} \appto\kvt@@row{\tabularnewline}% \ifdefvoid\cmdkvt@Row@below{}{% \eappto\kvt@@row{\noexpand\noalign{\noexpand\vspace{% \expandonce\cmdkvt@Row@below}}}}% % \end{macrocode} % At the very end of the expansion text, put \meta{post}. % \begin{macrocode} #1} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@everyrow} % The |\kvt@everyrow|\marg{code} registers \meta{code} to be included in % the first (invisible) cell of every row. % \begin{macrocode} \newcommand\kvt@everyrow[1]{\def\kvt@@everyrow{#1}} \newcommand\kvt@@everyrow{} % \end{macrocode} % \end{macro} % Initialize the hook for every row to increment the row counters. % \begin{macrocode} \kvt@everyrow{\kvt@stepcounters}% % \end{macrocode} % % \begin{macro}{\kvt@CheckMulticolumn} % The % |\kvt@CheckMulticolumn|\marg{arg1}\marg{arg2}\marg{arg3}\marg{arg4}|\@undefined|\linebreak[4]\marg{tname}\marg{colname} % macro checks whether a cell's initial content (captured by \meta{arg1} % to \meta{arg4}, starts a multi-column cell. If this is the case, the % macro records the arguments to |\multicolumn| for use by % |\kvt@AddKeyValRow|. % In this case, \meta{arg1}=|\multicolumn|, \meta{arg2}=\meta{n} (number % of columns to span), \meta{arg3}=\meta{format} (column alignment), and % \meta{arg4}=\meta{item} (the content of the cell). % \begin{macrocode} \def\kvt@CheckMulticolumn#1#2#3#4\@undefined#5#6{% \ifx#1\multicolumn % \end{macrocode} % First, record \meta{n} in |\kvt@@span|. The subtraction of $-1$ is % already in preparation for the next column, in which one spanning has % already been reduced. % \begin{macrocode} \kvt@@span=#2\relax \advance\kvt@@span\m@ne % \end{macrocode} % Second, move the defined cell format to inside of the \meta{item} % argument of |\multicolumn| rather than around the |\multicolumn|. % \begin{macrocode} \edef\kvt@@fmtcell{\unexpanded{\multicolumn{#2}{#3}}% {\csexpandonce{kvt@col@format@#5@#6}{\expandonce{#4}}}}% \fi} % \end{macrocode} % \end{macro} % % \subsection{Collecting Key-Value Table Content} % % \begin{macro}{\ShowKeyValTable} % The |\ShowKeyValTable|\oarg{options}\marg{tname} macro shows a table % of type \meta{tname} with given \meta{options}. The rows must have % been collected using |\Row| in |KeyValTableContent| environments or % using |\AddKeyValRow|. % \begin{macrocode} \newcommand\ShowKeyValTable[2][]{% \begin{KeyValTable}[#1]{#2}% \csuse{kvt@rows@#2}% \end{KeyValTable}% \csdef{kvt@rows@#2}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\AddKeyValRow} % The |\AddKeyValRow|\marg{tname}\oarg{options}\marg{content} adds a row % with a given \meta{content} to the existing content for the next table % of type \meta{tname} that is displayed with |\ShowKeyValTable|. The % \meta{content} and \meta{options} parameters are the same as with % |\kvt@AddKeyValRow|. % The resulting row (|\kvt@@row|) is globally appended to % \cs{kvt@rows@\meta{tname}}. % \begin{macrocode} \newcommand\AddKeyValRow[1]{% \kvt@AddKeyValRow {\bgroup} {\csxappto{kvt@rows@#1}{\expandonce{\kvt@@row}}\egroup} {#1}} % \end{macrocode} % \end{macro} % % \begin{environment}{KeyValTableContent} % The |KeyValTableContent|\marg{tname} environment acts as a container % in which rows can be specified without automatically being displayed. % In this environment, rows can be specified via the % |\Row|\marg{content} macro, which is supposedly shorter than using % |\AddKeyValRow|\meta{tname}\meta{content}. % \begin{macrocode} \newenvironment{KeyValTableContent}[1]{% \def\Row{\AddKeyValRow{#1}}}{}% % \end{macrocode} % \end{environment} % % % \subsection{Package Options} % % The \pkgname{tabu} is used by default for typesetting the tables, % additionally with \pkgname{longtable} for tables that can span % multiple pages. % If the default packages are never used or the \pkgname{tabu} package % shall be loaded manually, the |noTabuPkg| option can be used. % \begin{macrocode} \define@boolkey[kvt]{PackageOptions}[kvt@@]{noTabuPkg}[true]{} % \end{macrocode} % % Next, set default package options and process them. % \begin{macrocode} \ExecuteOptionsX[kvt]{% noTabuPkg=false, } \ProcessOptionsX[kvt]\relax % \end{macrocode} % % Finally, implement the outcome of the options parsing. % \begin{macrocode} \ifbool{kvt@@noTabuPkg}{}{% \RequirePackage{longtable,tabu}} % \end{macrocode} % % % \subsection{Auxiliary Code} % % \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. % \begin{macrocode} \DeclareListParser{\kvt@dossvlist}{;} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@forpsvlist} % The |\kvt@forpsvlist|\marg{handler}\marg{list} parses a `+'-separated list. % \begin{macrocode} \DeclareListParser*{\kvt@forpsvlist}{+} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@dobrklist} % The |\kvt@dobrklist|\marg{list} parses a `|\\|'-separated list. % \begin{macrocode} \DeclareListParser{\kvt@dobrklist}{\\} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvt@error} % \begin{macro}{\kvt@warn} % \begin{macrocode} \newcommand\kvt@error[2]{\PackageError{keyvaltable}{#1}{#2}} \newcommand\kvt@warn[1]{\PackageWarning{keyvaltable}{#1}} % \end{macrocode} % \end{macro} % \end{macro} % %\iffalse % %\fi % \Finale \endinput