% \iffalse meta-comment % % Copyright (C) 2016 by Richard Gay % ------------------------------------------------------- % % 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> [2016/05/22 v0.2 Package for filling tables using key-value lists] % % %<*driver> \documentclass{ltxdoc} \usepackage[columns=2]{idxlayout} \usepackage[table]{xcolor} \usepackage{enumitem} \usepackage{showexpl} \lstset{gobble=2,frame=trbl,backgroundcolor=\color{black!5!white}} \lstset{explpreset={numbers=none,columns=fixed,basicstyle=\footnotesize\ttfamily}} \lstset{preset={\small\sffamily},overhang=2cm,pos=r} \usepackage{pbox} \newcommand\NiceDescribeStuff[2]{% #1=margin text, #2=body text \medskip\par\noindent\leavevmode% \marginpar{\hfill\pbox[t]{2\marginparwidth}{\ttfamily #1}% \hspace*{-\marginparsep}}% \ifstrempty{#2}{}{#2\smallskip\\}} \newcommand\NiceDescribeEnv[2]{% #1=envname, #2=parameters \NiceDescribeStuff{% \textcolor{gray}{\cs{begin}}\string{#1\string}\\ \textcolor{gray}{\cs{end}}\string{#1\string}}{#2}} \newcommand\NiceDescribeMacro[2]{% #1=macro, #2=parameters \NiceDescribeStuff{\hbox to 0pt{\hss\string#1}}{#2}} \newcommand\NiceDescribeConstant[1]{% #1=constant \NiceDescribeStuff{\hbox to 0pt{\hss #1\quad}}{}\ignorespaces} % The following macro simulates labels and references, assuming % labels are only referenced after they have been defined. This % is used in LTXexample environments, in which the normal label % and ref mechanism is otherwise disabled. \newcommand\FakeRefs{% \def\ref##1{\csuse{fakelabel@##1}}% \def\label##1{\global\csletcs{fakelabel@##1}{@currentlabel}}% \let\marginpar=\origmarginpar } \let\origmarginpar=\marginpar \usepackage{keyvaltable} \usepackage{hypdoc} \EnableCrossrefs \CodelineIndex \RecordChanges % the following packages are for the examples \usepackage{xintexpr} \usepackage{makecell} \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} % % \GetFileInfo{keyvaltable.dtx} % % \DoNotIndex{\newcommand,\newenvironment,\def,\gdef,\edef} % % % \title{The \textsf{keyvaltable} package\thanks{This document % corresponds to \textsf{keyvaltable}~\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 Gay \\ \texttt{gay@mais.informatik.tu-darmstadt.de}} % % \maketitle % % \section{Introduction} % % The main goal of the \textsf{keyvaltable} package is to offer means % for typesetting tables % \begin{enumerate}[nosep] % \item easily and yet still looking rather nicely, % \item in a way that separates content from presentation, % and % \item with re-usable layout for tables of the same type. % \end{enumerate} % For this purpose, the package essentially builds on two concepts: % \begin{description}[noitemsep] % \item[table types:] % A table type is identified by a table name, \meta{tname}, and has a % list of columns as well as further properties such as the background % colors of rows. Each column also has a name, \meta{cname}, as well as % further properties such as the heading of the column and the alignment % of the column's content. % \item[key-value rows:] % A table row is specified by a list 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. % \end{description} % The the display of the tables, the \textsf{keyvaltable} package builds % on the packages \textsf{tabu}, \textsf{longtable}, and % \textsf{booktabs}. % % \section{Usage} % % We start with a basic usage example. An explanation of the involved % macros follows afterwards.\medskip % % \begin{LTXexample} % \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 \textsf{tabu} package (see the % documentation there). % % 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 \textsf{keyvaltable} 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}} % 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}. % \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{description} % \item[|align|:] % 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 \textsf{tabu} package. This % particularly includes |l|, |c|, |r|, |p|, and |X|. By default (i.e., % if this property is not set explicitly), this property is set % to~|l|. % \item[|default|:] % This property specifies the default value of a cell in this column, % i.e., in case that a |\Row| does not provide content for the cell. % By default (i.e., if unset for a column), this is an empty string. % \item[|format|:] % This property specifies a formatting macro for content of the cell. % By default, the formatting macro takes the content as is but puts a % |\strut| before and after the content (to yield a better vertical % spacing). % \item[|head|:] % This property specifies the content of the column's header row. The % default value for this property is the name of the column. % \item[|hidden|:] % This property specifies whether a table column shall be displayed or % not. The \meta{value} for this property can be |true| (to display % the cell; the default) or |false| (to not display the cell). % \end{description} % % \subsection{Typesetting Tables}\label{sec:typesetting-tables} % % The first possibility for typesetting a table using the % \textsf{keyvaltable} 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{description}\label{page:table-options} % \item[|rowbg|:] % This property specifies the background colors of content rows. The % format of the \meta{value} for this property must be % \meta{oddcolor}|..|\meta{evencolor}.\footnote{The \meta{value} is % passed directly to \cs{taburowcolors} of the \textsf{tabu} package.} % The default is |white..black!10|, i.e., alternatingly white and light % very gray. % \item[|headbg|:] % This property specifies the background color of the head row. The % \meta{value} must be a single color specification that is understood % by the \textsf{xcolor} package.\footnote{The \meta{value} is passed % directly to the \cs{rowcolor} macro.} The default is |black!14|. % \item[|shape|:] % This property specifies the table's shape. For \meta{value}, the % package currently supports |multipage| (the default) and |onepage|. % 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. % \end{description} % % \NiceDescribeMacro{\Row}{\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. % % \subsection{Tables of Collected Rows}\label{sec:collected-tables} % % As an alternative to producing a table within a single environment, % the \textsf{keyvaltable} 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}[preset=\NewKeyValTable{Recipe}{amount:align=r;ingredient:align=l;step:align=X[l]}] % \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 \textsf{keyvaltable} 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} % \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 \textsf{keyvaltable} 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} % \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} % % \NiceDescribeConstant{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. % % \NiceDescribeConstant{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. % % \NiceDescribeConstant{kvtTotalRow} % The |kvtTotalRow| counter counts the rows in the current table and % includes the number of rows of all previous tables produced using the % \textsf{keyvaltable} 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}[preset=\FakeRefs] % \NewKeyValTable{Labeled}{ % label: align=r, head=\#, % 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}{\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. % % \section{Use with Other Packages} % % \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 \textsf{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 \textsf{keyvaltable} package can be used together with the % \textsf{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 \textsf{keyvaltable} package. % % \begin{description} % \item[\textsf{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[\textsf{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 the % \textsf{keyvaltable}. However, the package does not pursue % separation of content from presentation or re-use of table layouts. % \item[\textsf{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 configurable default heading format % \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} % % We use \textsf{etoolbox} for some convenience macros that make the % code more easily maintainable and use \textsf{xkeyval} for options % in key--value form. % \begin{macrocode} \RequirePackage{etoolbox} \RequirePackage{xkeyval} % \end{macrocode} % We use \textsf{tabu} for creating the tables and \textsf{longtable} % for tables that can span multiple pages (via |longtabu|). We use % \textsf{booktabs} for nice horizontal lines and \textsf{xcolor} % for row coloring % \begin{macrocode} \RequirePackage[table]{xcolor} \RequirePackage{booktabs} \RequirePackage{longtable,tabu} % \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 \textsf{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}{\mkv@dossvlist} % The |\mkv@dossvlist|\marg{list} macro parses a semicolon-separated % list and runs |\do|\meta{item} for every element of the list. % \begin{macrocode} \DeclareListParser{\mkv@dossvlist}{;} % \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@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{default}\marg{choice} % macro adds a new column 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@addchoicecolumnprop[3]{% % \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}{#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}{#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} % \begin{macrocode} \kvt@addtableprop{rowbg}{white..black!10} \kvt@addtableprop{headbg}{black!14} \kvt@addchoicetableprop{shape}{multipage}{multipage,onepage} \kvt@addcolumnprop{default}{} \kvt@addcolumnprop{format}{\kvt@struttedcell} \kvt@addcolumnprop{align}{l} \kvt@addcolumnprop{head}{} \kvt@addchoicecolumnprop{hidden}{false}{false,true} \kvtSet{} % \end{macrocode} % % \begin{macro}{\kvt@struttedcell} % The |\kvt@struttedcell|\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. % \begin{macrocode} \newcommand\kvt@struttedcell[1]{\strut #1\strut} % \end{macrocode} % \end{macro} % % \subsection{Declaring Key-Value Tables} % % \begin{macro}{\NewKeyValTable} % The |\NewKeyValTable|\oarg{options}\marg{tname}\marg{colspecs} % 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} % \begin{macrocode} \newcommand\NewKeyValTable[3][]{% % \end{macrocode} % First initialize the ``variables''. % \begin{macrocode} \csdef{kvt@options@#2}{#1}% \csdef{kvt@headings@#2}{}% \csdef{kvt@alignments@#2}{}% \csdef{kvt@colkeys@#2}{}% \csdef{kvt@rowcount@#2}{1}% \csdef{kvt@rows@#2}{}% \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}% \mkv@dossvlist{#3}% } % \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}}% \ifcsvoid{kvt@headings@#1}{}{\csappto{kvt@headings@#1}{&}}% \ifcsstring{kvt@col@head@#1@#2}{}% {\cseappto{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@alltables} % The |\kvt@alltables| is an \textsf{etoolbox} list containing the names % of all tables declared by |\NewKeyValTable|. % \begin{macrocode} \newcommand\kvt@alltables{} % \end{macrocode} % \end{macro} % % % \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}{1} % \end{macrocode} % \end{macro} % % \begin{macro}{\kvtLabel} % The |\kvtLabel|\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} % \begin{macrocode} \newcommand\kvtLabel[2]{% % \end{macrocode} % The following imitates a |\refstepcounter| in the sense of setting the % current label, but it does not touch the \meta{counter}. % \begin{macrocode} \protected@edef\@currentlabel {\csname p@#1\endcsname\csname the#1\endcsname}% % \end{macrocode} % Next, define the \meta{label} (if provided) and show the value of % \meta{counter}. % \begin{macrocode} \ifstrempty{#2}{}{\label{#2}}% \csuse{the#1}} % \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% \def\Row##1{\kvt@AddKeyValRow{#2}{##1}\kvt@@row\\}% \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} % % \begin{macro}{\kvt@StartTable@onepage} % \begin{macro}{\kvt@StartTable@multipage} % \begin{macro}{\kvt@StartTabu} % The |\kvt@StartTable@onepage|\marg{tname} begins the table % environment for a |KeyValTable| of shape |onepage|, which includes % displaying the head row, and setting the row counters. % The |\kvt@StartTable@multipage|\marg{tname} does the same for a table % environment of shape |multipage|. % These macros internally use |\kvt@StartTabu|\marg{env}\marg{tname} for % beginning a table environment of the \textsf{tabu} package. The % \meta{env} specifies the concrete environment, either |tabu| or % |longtabu|. % \begin{macrocode} \newcommand\kvt@StartTable@onepage[1]{% \kvt@StartTabu{tabu}{#1}} \newcommand\kvt@StartTable@multipage[1]{% \kvt@StartTabu{longtabu}{#1}} \newcommand\kvt@StartTabu[2]{% % \end{macrocode} % The |\kvt@@recenttable| allows the |\AfterEndEnvironment| hook for % |KeyValTable| to access the most recent table type. % \begin{macrocode} \gdef\kvt@@recenttable{#2}% \bgroup\edef\kvt@@do{\egroup \noexpand\taburowcolors[2] 2{\cmdkvt@Table@rowbg}% \noexpand\begin{#1}{\csuse{kvt@alignments@#2}}% \noexpand\toprule \noexpand\rowcolor{\cmdkvt@Table@headbg}% }\kvt@@do% \csuse{kvt@headings@#2}\\\midrule \iftabu@long\expandafter\endhead\fi \setcounter{kvtRow}{1}% \setcounter{kvtTypeRow}{\csuse{kvt@rowcount@#2}}% \everyrow{% \addtocounter{kvtRow}{1}% \addtocounter{kvtTypeRow}{1}% \addtocounter{kvtTotalRow}{1}% }% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\kvt@EndTable@onepage} % \begin{macro}{\kvt@EndTable@multipage} % The |\kvt@EndTable@onepage| and |\kvt@EndTable@multipage| macros end a % table environment of the |onepage| or, respectively, |multipage| % shape. % \begin{macrocode} \newcommand\kvt@EndTable@onepage{% \bottomrule% \end{tabu}} \newcommand\kvt@EndTable@multipage{% \bottomrule% \end{longtabu}} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\kvt@AddKeyValRow} % The |\kvt@AddKeyValRow|\marg{tname}\marg{content} adds a new row to % the current table of type \meta{tname}. The \meta{content} is a % key-value list that specifies the content of the individual cells in % the row. The macro assumes that the current content of the table is % stored in |\kvt@@row| and modifies this macro by appending the % additional row. % \begin{macrocode} \newcommand\kvt@AddKeyValRow[2]{% \setkeys[KeyValTable]{#1}{#2}% % \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. % \begin{macrocode} \def\do##1{% \ifdefvoid\kvt@@row{}{\appto\kvt@@row{&}}% \eappto\kvt@@row{% \csexpandonce{kvt@col@format@#1@##1}{% \ifcsvoid{cmdKeyValTable@#1@##1}% {\csexpandonce{kvt@col@default@#1@##1}}% {\csexpandonce{cmdKeyValTable@#1@##1}}}% }% }\dolistcsloop{kvt@colkeys@#1}% } % \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}\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}, like with |\kvt@AddKeyValRow|, is supposed to be a % key-value list specifying the content of the cells in the row. % \begin{macrocode} \newcommand\AddKeyValRow[2]{% \bgroup% \kvt@AddKeyValRow{#1}{#2}% \csxappto{kvt@rows@#1}{\expandonce{\kvt@@row}\noexpand\\}% \egroup} % \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} % %\iffalse % %\fi % \Finale \endinput