The keyvaltable package ∗
Richard Grewe [email protected]
April 4, 2020
Abstract
Thekeyvaltablepackage’s main goal is to facilitate typesetting tables…
(a) …easily and yet still
looking rather nicely through horizontal rules and alternating row background colors by default;
(b) …in a way that separates content from presentation
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;
(c) …with re-usable layout for tables of the same type
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.
Contents
1 Basic Usage 2
2 Defining Table Types 2 3 Typesetting Tables 3 4 Row Numbering & Labeling 6 5 Changing the Appearance 9
6 Customizing the Layout 15 7 Use with Other Packages 22 8 Related Packages 25
9 Future Work 25
10 Implementation 26
∗This document corresponds tokeyvaltable v2.2, dated 2020/04/05. The package is available online athttp://www.ctan.org/pkg/keyvaltableandhttps://github.com/Ri-Ga/keyvaltable.
1 Basic Usage
We start with a basic usage example. An explanation of the involved macros follows afterwards.
\NewKeyValTable{Recipe}{
amount: align=r;
ingredient: align=l;
step: align=X;
}\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}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl
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 thealignkey.
The alignmentsr(right) andl(left) are the standardtabularalignments; the X alignment is provided by thetabularxpackage (see the documentation there).
After defining 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 parameterRecipeof theKeyValTable identifies the type of the table. In the parameter of the \Row macro, the content of the individual cells can be specified by key-value pairs such asamount=150g, which puts “150g” into theamountcolumn 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 thekeyvaltablepackage can be used in the general case and how its visual appearance can be customized is subject of the remainder of this documentation.
�
To quickly sketch a table type, one can even omit properties of columns and just list their names, separated by semicolons, as the following example shows. All columns then get the default alignment: l.\NewKeyValTable{Recipe}{amount;ingredient;step}
\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}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl
2 Defining Table Types
As the example inSection 1shows, \NewKeyValTabledefines a table type.
\NewKeyValTable[hoptionsi]{htnamei}{hcolspecsi}[hlayouti]
The macro defines a table type with namehtnameiwhose columns are specified byhcolspecsi. Thehcolspecsiparameter must be a semicolon-separated list. Each column specification is of the form
hcolnamei:hpropertyi=hvaluei,hpropertyi=hvaluei,…
In such a specification, hcolnamei represents the name of the column. The hpropertyi=hvalueipairs configure certain properties of the column. Thehpropertyi can be one of the following:
align=l, c,r,p,X,… initially: l
This property specifies the alignment of content in the column. Thehvalueican be set to any column alignment understood by table environments.1
default=hcontenti initially: hemptyi
This property specifies the defaulthcontentiof a cell in this column, i.e., in case that a\Row does not provide content for the cell. Initially (i.e., if unset for a column), this is an empty string.
format=hsingle argument macroi initially: \kvtStrutted 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.
Initially, the format is defined to take the content as is but puts a\strutbefore and after the content (to yield a better vertical row spacing).
head=hcontenti initially: hcolnamei
This property specifies thehcontentiof the column’s header row. The initial value for this property is the name of the column.
hidden=true,false default: true,initially: false This property specifies whether a table column shall be displayed or not. The hvalueifor this property can betrue (to hide the cell) or false(to display the cell). Usinghiddenwithouthvalueiis equivalent to specifyinghidden=true.
The following example shows all of the above column properties in action.
\NewKeyValTable{ShoppingList}{
what: head=article, format=\textbf;
amount: align=r, default=1;
why: hidden;
}\begin{KeyValTable}{ShoppingList}
\Row{what=melon}
\Row{what=apples, amount=6}
\Row{what=bicycle, why=Bob's birthday}
\end{KeyValTable}
article amount
melon 1
apples 6
bicycle 1
The hoptionsiandhlayoutiparameters of \NewKeyValTableare described in Section 5.1and, respectively,Section 6.1of this documentation.
3 Typesetting Tables
Thekeyvaltable package offers three possibilities for typesetting tables. The first is in the traditional LATEX form, in which there is an environment that encloses the individual row specifications. The second possibility is to specify rows throughout the document, bind them to a name, and finally typeset a table from all rows bound to the particular name. The third possibility is to source the row specifications from a file.
1More complex values, for instance using the notation of thearraypackage for inserting material
3.1 Specifying Rows in a Table Environment
The first possibility for typesetting a table using thekeyvaltablepackage, is via the KeyValTableenvironment. Section 1presents an example of this possibility.
\begin{KeyValTable}
\end{KeyValTable} [hoptionsi]{htnamei}
TheKeyValTable environment creates a table of typehtnamei. The typehtnamei 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 hoptionsiare described inSection 5.1.
\Row[hoptionsi]{hcontenti}
A table row is produced by the \Row macro. The hcontentimust be a comma- separated list ofhcnamei=htextipairs. Thehcnameiidentifies a column that was registered for the table typehtnamei. Thehtextispecifies the content of the cell in the respective column. Each column for which nohtextiis provided inhcontenti, will result in a cell that is filled with the column’s default value. Thehoptionsi argument customizes row properties and is further explained inSection 5.3.
3.2 Tables of Collected Rows
The content of a table’s rows might logically belong to locations that are scattered throughout a document, e.g., to individual sections of the document. In this situation, it can be convenient to have the rows specified close to the locations their contents belong to, instead of specified in the table environment.
The following example illustrates the use of this feature for taking and collecting notes in a document:
\NewKeyValTable{Notes}{type; text}
\NewCollectedTable{notes}{Notes}
\subsection*{Notes}
\ShowCollectedTable{notes}
\section{Introduction}
\CollectRow{notes}{type=remark, text=intro too long}
Lorem ipsum dolor sit amet, \ldots
\section{Analysis}
\CollectRow{notes}{type=task, text=proofread Analysis}
Lorem ipsum dolor sit amet, \ldots
Notes
type text
remark intro too long task proofread Analysis
1 Introduction
Lorem ipsum dolor sit amet, …
2 Analysis
Lorem ipsum dolor sit amet, … SeeSection 4.3 on how to (automatically) include references to, e.g., section or page numbers in tables. The key macros (highlighted in bold font) used in the example are the following three.
\NewCollectedTable{hcnamei}{htnamei}
This macro defines the namehcnameifor a new collection of rows. The collection is associated with the table type htnamei. This macro must be used before
\CollectRowfor ahcnamei.
\CollectRow[hoptionsi]{hcnamei}{hcontenti}
This macro adds the row contenthcontentiand row optionshoptionsito the row collectionhcnamei.
\ShowCollectedTable[hoptionsi]{hcnamei}
This macro typesets a table of the row collectionhcnamei, with the table options hoptionsi. The table includes rows that are collected only afterwards in the document. For this, LATEX must be run at least two times.
3.3 Sourcing Rows From a File
Rather than specifying the rows of a table inside aKeyValTableenvironment, the rows can also be sourced from a file. More concretely, this file must consist of the\Row macros that specify the content of the rows. For information on how to source rows from CSV files, seeSection 7.2.
\ShowKeyValTableFile[hoptionsi]{htnamei}{hfilenamei}
This macro produces aKeyValTableenvironment of typehtnameiwhose content is taken from the filehfilenamei. Thehoptionsispecify the table options, which are directly passed to the options argument of theKeyValTable environment.
\begin{filecontents}{snowman.kvt}
\Row{amount=3, ingredient=balls of snow, step=staple all 3 balls}
\Row{amount=1, ingredient=carrot, step=stick into top ball}
\Row{amount=2, ingredient=coffee beans, step=put diagonally above carrot}
\end{filecontents}
\ShowKeyValTableFile{Recipe}{snowman.kvt}
amount ingredient step
3 balls of snow staple all 3 balls 1 carrot stick into top ball 2 coffee beans put diagonally above
carrot
3.4 Tables of Collected Rows (Legacy Interface)
This section documents legacy functionality ofkeyvaltable, that is now superseded by the functionality described inSection 3.2. The legacy functionality compares to the new functionality as follows:
• Rows must be collected before the place in the document where they are displayed in a table.
• For each table type, there can be only one collection of rows. After the collection has been typeset in a table the collection is emptied again.
• Row content is not written into the aux file. This might be relevant for very large tables.
The following macros and environments implement the functionality.
\AddKeyValRow{htnamei}[hoptionsi]{hcontenti}
A table row is produced by the\AddKeyValRowmacro. Thehtnameiidentifies the table type and the hcontenti provides the content of the cells in the row. The format of thehcontentiis the same as for the\Rowmacro described in Section3.
\ShowKeyValTable[hoptionsi]{htnamei}
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 KeyValTableenvironment. This macro resets the list of rows for the specified table type.
\begin{KeyValTableContent}
\end{KeyValTableContent} {htnamei}
For simplifying the addition of rows, theKeyValTableContentenvironment can be used. In this environment, the\Rowmacro can be used just like in theKeyValTable environment. The only difference is that theKeyValTableContent environment does not cause the table to be displayed. For displaying the content collected in KeyValTableContentenvironments, the\ShowKeyValTablemacro can be used.
The following example demonstrates the use, based on the previously defined Recipetable type.
\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}
amount ingredient step
3 balls of snow staple all 3 balls 1 carrot stick into top ball 2 coffee beans put diagonally above
carrot
4 Row Numbering & Labeling
The mechanism of default column values enables a simple means for automatic row numbering, labeling, and referencing document entities.
4.1 Row Numbering
For row numbering, one can use one of three row counters provided by thekeyvaltable package: kvtRow, kvtTypeRow, and kvtTotalRow. The counters are explained after the following example, which demonstrates the use for the case of thekvtRow counter.
\NewKeyValTable[headformat=\textbf]{Numbered}{
line: align=r, head=\#,
format=\kvtStrutted[\textbf], default=\thekvtRow;
text: align=l, head=Text}
\begin{KeyValTable}{Numbered}
\Row{text=First row}
\Row{text=Second row}
\end{KeyValTable}
# Text 1 First row 2 Second row
kvtRow ThekvtRowcounter counts the row in thecurrenttable. 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.
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.
kvtTotalRow ThekvtTotalRowcounter counts the rows in the current table and includes the number of rows of all previous tables produced using thekeyvaltablepackage.
By default, all rows are counted by the aforementioned counters. However, this default can be changed.
uncounted=true,false default: true,initially: false This row option specifies whether the row shall not be counted (true) or shall be counted (false). If onlyuncountedis used without a value, this is equivalent to uncounted=true. The following example illustrates the option.
\begin{KeyValTable}{Numbered}
\Row{text=First row}
\Row[uncounted]{line={--}, text=interlude}
\Row{text=Second row}
\end{KeyValTable}
# Text 1 First row – interlude 2 Second row By default, all counters start at value1. Through the following possibilities, this behavior can be changed.
resume=true,false default: true,initially: false This option is available inKeyValTableenvironments. When this option is set to true, the value of thekvtRowcounter is resumed from the previous KeyValTable environment. The other two counters are not affected by this option.
4.2 Row Labeling
Row numbering can easily be combined with row labeling. The following example shows how theformatcolumn property can be used for this purpose.
\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}
# Text 1 First row 2 After row 1
\kvtLabel[hlabeloptsi]{hcounteri}{hlabeli}
The \kvtLabel macro shows the current value of the hcounteri – in particular kvtRow, kvtTypeRow, and kvtTotalRow – and sets the hlabeli to the value of hcounteri. When using the macro with theformatproperty, only the first argument (hcounteri) must be provided, as the above example shows. The second argument (hlabeli) is provided by the respective cell content.
The\kvtLabelmacro should work well with packages that change the referenc- ing, likeclevereforvarioref. When using a package that adds an optional argument to the\labelcommand (likecleverefdoes), thehlabeloptsican be used to pass an optional argument to\label. This feature is demonstrated inSection 7.1.
4.3 Referencing in Collected Rows
The example in Section 3.2 illustrates well a situation in which referencing the locations in the document at which rows are collected. The following example augments the original example to achieve exactly this.
\NewKeyValTable{Notes2}{
id: default=\thekvtRow.;
type; text;
where: default={\S\thesection\ (p.\@\thepage)};}
\NewCollectedTable{notes2}{Notes2}
\subsection*{Notes}
\ShowCollectedTable{notes2}
\section{Introduction}
\CollectRow{notes2}{type=remark, text=intro too long}
Lorem ipsum dolor sit amet, \ldots
\section{Analysis}
\CollectRow{notes2}{type=task, text=proofread!}
Lorem ipsum dolor sit amet, \ldots
Notes
id type text where
1. remark intro too long §1 (p.8) 2. task proofread! §2 (p.8)
1 Introduction
Lorem ipsum dolor sit amet, …
2 Analysis
Lorem ipsum dolor sit amet, … Thekeyvaltablepackage is carefully designed to take the values of counters such as the page counter and the section counter from the point in the document where
\CollectRow is used. At the same time, the table row counters are taken from the point inside the respective table. This applies to \thekvtRow as well as to
\arabic{kvtRow}and other counter formats. For customizing this behavior, the following three macros can be used.
\kvtDeclareTableMacros{hmacro-listi}
\kvtDeclareTableCounters{hcounter-listi}
These macros take a comma-separated list of macros (respectively counters) and declares these as “table macros” (“table counters”). A macro or counter de- clared this way is expanded only inside the table environment and not at the point where\CollectRowis used. Thekeyvaltable already declares\thekvtRow,
\thekvtTypeRow, and \thekvtTotalRow as table macros and declares kvtRow, kvtTypeRow, andkvtTotalRowas table counters.
\kvtDeclareCtrFormatters{hmacro-listi}
This macro takes a comma-separated list of macros and declares them as macros for formatting counter values. Examples for such macros are \arabic, \alph,
\Alph, \roman, \Roman, \fnsymbol, which keyvaltable already declares. When other counter-formatting macros shall be used in the default value of a col- umn, such as \ordinal of the fmtcount package, they have to be passed to
\kvtDeclareCtrFormattersfirst.
5 Changing the Appearance
The appearance (e.g., colors, rules) of a table can be changed at the level of the overall table as well as for individual rows, columns, and cells.
5.1 Table Appearance
The appearance of a table can be configured through thehoptionsiparameters of
• KeyValTable, \ShowKeyValTable, and \ShowKeyValTableFile (affecting the particular table),
• \NewKeyValTable(affecting all tables of the table type), and
• \kvtSet(affecting all tables).
In this list, the former take precedence over the latter. That is, table options override table type options and table type options override global options for all tables.
In each case, hoptionsi must be specified as a comma-separated list of hpropertyi=hvalueipairs. The followinghpropertyikeys can be configured.
backend=tabular, tabularx,longtable,xltabular,tabu,longtabu
shape=multipage,onepage initially: multipage
Thebackendproperty specifies the table environment to be used for producing the table. A set of six environments is currently supported, including environments that can span multiple pages and environments whose columns can stretch/shrink to fill the available space (“X” columns). Theshapeproperty abstracts from the concrete environments. In case ofmultipage, the table may span multiple pages and depending on whetherX-columns are used or not, an appropriate environment is selected. In case ofonepage, the table does not split into multiple pages. See Section 6.4for more details on the available shapes and backends. Only one of shapeandbackend can be specified. If both are specified, the property that is specified last wins.
width=hdimensioni initially: \linewidth
This property specifies the width of the table, if the selected shape/backend supports it (seeSection 6.4).
valign=t, c,b initially: hemptyi
halign=l, c,r initially: hemptyi
These two properties specify the vertical and, respectively, horizontal alignment of the table, if the selectedshape/backendsupports it (seeSection 6.4).
showhead=true,false initially: true
This property specifies whether the header row shall be shown. Thehvalueimust be a Boolean (i.e., true orfalse), where truespecifies that the header row is shown andfalsespecifies that the header row is not shown.
showrules=true,false initially: true
norules=true,false default: true,initially: false Theshowrulesproperty specifies whether top and bottom rules as well as a rule below the header row are drawn (true) or not (false). The norulesproperty
serves the same purpose, but the valuetruehides the rules and the valuefalse causes the rules to be drawn. Note that both properties only affect the rules thatkeyvaltableproduces automatically; rules manually added, e.g., via\hlineor
\midruleare not affected by the properties.
headalign=hemptyi or hcoltypei initially: hemptyi This property specifies the alignment for header cells. If left empty, each header cell receives the same alignment as the respective column.
headbg=hcolori initially: black!14
This property specifies the background color of the header rows. Thehcolorimust be a single color specification that is understood by thexcolorpackage. Thehcolori is passed directly to the\rowcolormacro. Ifhcoloriis empty, then no background color is produced for the header row.
headformat=hsingle argument macroi initially: h“identity”i This property specifies a format to be applied to all header cells. The value specified for theheadformat key is used to format each header. The value can be a macro that takes once argument, through which it is provided the header (as specified in the column’sheadproperty). Initially, an “identity” macro is used, meaning that eachhead is taken without change.
rowbg=hcolori initially: white..black!10
This property specifies the background colors of content rows. Thehvalueifor this property must be of the formathoddcolori..hevencolori. The first row after the header is colored withhoddcolori, the second row withhevencolori, and so forth.
Both colors must be understood by thexcolorpackage. Ifhcoloriis empty, then no background color is produced for content rows.
norowbg=true,false default: true,initially: false nobg=true,false default: true,initially: false These properties are shorthands forrowbg={}(turning off background colors for content rows) and, respectively, forrowbg={},headbg={}(turning off background colors for header rows and for content rows). Using these options without a value is equivalent to using true for the value. For instance, nobg is equivalent to nobg=true.
Figure 1on the following page demonstrates thehoptionsiin examples.
5.1.1 Table Styles and Resumable Options
Rather than specifying properties for individual tables or table types,keyvaltable also supports namedtable styles.
style=hlist of style namesi initially: hemptyi
Through this property of tables or table types, a list of styles can be applied to a single table or, respectively, a table type. Each style must have been defined with
\kvtNewTableStylebefore.
\kvtNewTableStyle{hnamei}{hoptionsi}
\kvtSet{format=\texttt}
\NewKeyValTable[showhead=false, rowbg=blue!10..blue!15, ]{TabOptions}{opt; val}
\begin{KeyValTable}{TabOptions}
\Row{opt=showhead, val=false}
\Row{opt=rowbg, val=blue!10..blue!15}
\end{KeyValTable}
showhead false
rowbg blue!10..blue!15
\NewKeyValTable[showrules=false,headbg=blue!25, headalign=c,headformat=\textbf,norowbg, halign=r,
]{TabOptions2}{opt; val}
\begin{KeyValTable}{TabOptions2}
\Row{opt=showrules, val=false}
\Row{opt=headbg, val=blue!25}
\Row{opt=headalign, val=c}
\Row{opt=headformat, val=\string\textbf}
\Row{opt=norowbg, val=true}
\Row{opt=halign, val=r}
\end{KeyValTable}
opt val
showrules false headbg blue!25 headalign c headformat \textbf norowbg true
halign r
\NewKeyValTable[valign=t,nobg,norules,
shape=onepage,width=3cm,headformat=\textbf, ]{TabOptions3}{opt: align=X;}
\begin{KeyValTable}{TabOptions3}
\Row{opt=nobg}
\Row{opt=norules}
\end{KeyValTable}
\begin{KeyValTable}{TabOptions3}
\Row{opt={shape=onepage}}
\Row{opt={valign=t}}
\Row{opt={width=3cm}}
\end{KeyValTable}
optnobg norules
optshape=onepage valign=t width=3cm
Figure 1: Examples for table options
This macro declares a new table style with the givenhnameiand defines it to be equivalent to using the givenhoptionsi. Thehnameimust not already be defined.
\kvtRenewTableStyle{hnamei}{hoptionsi}
This macro re-defines an existing table stylehnameiwith newhoptionsi.
The following example demonstrates table styles for an individual table.
\kvtNewTableStyle{plain}{
norules,nobg,headformat=\textbf}
\begin{KeyValTable}[style=plain]{Recipe}
\Row{amount=150g, ingredient=ice cream, step=put into bowl}
\Row{amount= 50g, ingredient=cherries, step=heat up and add to bowl}
\end{KeyValTable}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl
�
Thehoptionsiin \kvtNewTableStyle can be left empty. In this case, the table style does not have any effect on the appearance of tables. However, the style can already be used for “tagging” tables and table types, while the final options for the style can be configured at a later point in time.Even without table styles, the appearance of the previousKeyValTablecan be used again through the following option.
resume*=true,false default: true,initially: false When set totrue, this option makes the table use the options from the previ- ousKeyValTable environment. This option also implies theresume option (see Section 4.1on page7).
If the previous environment also usedresume*, then the options of its prede- cessor environment are used, and so forth. Note that this means that table options are not accumulated over subsequent uses ofresume*. This behavior is the same as in theenumitempackage.
5.2 Column Appearance
Column appearance is configured through the parametersalign, head, format, anddefaultof columns in\NewKeyValTable. For theformat, the following macro exists to ensure proper height and depth of rows even if the content itself is more narrow.
\kvtStrutted[hinneri]{hargi}
This macro places a \strutbeforehargiand a \strutafterhargi. This has the effect that the first and last row ofhargiobtain a “natural” height and depth even if their content is smaller. The second\strutis omitted when it would cause a new line to be produced. SeeSection 4for an example.
5.3 Row Appearance
Through the hoptionsi argument of the \Row and the \KeyValRow macros, the appearance of rows can be configured. As with other option arguments of the keyvaltablepackage, the options must be a comma-separated list of key-value pairs.
The following options are supported.
hidden=true,false default: true,initially: false This property specifies whether the row shall be hidden (true) or not (false). If onlyhiddenis used without a value, this is equivalent to hidden=true.
align=hemptyi or hcoltypei initially: hemptyi
This property specifies the alignment of the cells in the row. If this property is not specified, the respective columns’ alignment is used. The alignment applies to normal cells as well as to cells in column groups.2
bg=hcolori initially: hemptyi
This property specifies the background color for the particular row. If this option is not specified (or set to an empty value explicitly), the background color is determined by therowbgoption of the table.
format=hsingle argument macroi initially: h“identity”i format*=hsingle argument macroi initially: h“identity”i format!=hsingle argument macroi initially: hnonei These properties specify formatting for all cells of the particular row. The difference between the three properties is how they interact with the column formats of the respective cells in the row. Theformat property is applied to the cell content beforethe column format, and theformat*property is appliedafter the column format. Theformat!property overrides any column formats in the respective row and also renders theformatandformat*properties ineffective.
headlike=true,false default: true,initially: false This property, when used without a value or with valuetrue, specifies that the row shall be formatted like a header row. Concretely, the alignment, background color, and format of the row’s cells is then set to the values of the table’sheadalign, headbg, andheadformatproperties.
above=hdimensioni initially: hemptyi
below=hdimensioni initially: hemptyi
around=hdimensioni initially: hemptyi
These properties specify extra vertical space above and, respectively, below the row. Thearoundproperty is a short-hand for setting both, aboveandbelow, to the same value. Note that the vertical 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\vspace.
�
Initial values for all row options can be set with\kvtSet{Row/hoptioni=hvaluei} (see alsoSection 5.5).The following example demonstrates some of the options.
\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=Gold,format=\textit]{
step=serve with a smile}
\end{KeyValTable}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl serve with a smile
2Note that the alignment does not override the alignment specified in any\multicolumnif it
5.3.1 Row Styles
Rather than specifying properties for individual rows,keyvaltable also supports namedrow styles.
style=hlist of style namesi initially: hemptyi Through this property of rows, a list of styles can be applied to the row. Each style must have been defined with\kvtNewRowStylebefore.
\kvtNewRowStyle{hnamei}{hrow-optionsi}
This macro declares a new row style with the given hnameiand defines it to be equivalent to using the given hrow-optionsi. The hnamei must not already be defined.
\kvtRenewRowStyle{hnamei}{hrow-optionsi}
This macro re-defines an existing row stylehnameiwith newhrow-optionsi. The following example produces the same output as the previous example, but uses row styles.
\kvtNewRowStyle{optional}{hidden}
\kvtNewRowStyle{highlight}{above=1ex,bg=Gold}
\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[style=optional]{amount=25g,
ingredient=cream, step=decorate on top}
\Row[style=highlight]{step=serve with a smile}
\end{KeyValTable}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl serve with a smile
�
Thehrow-optionsiin\kvtNewRowStylecan be left empty. In this case, the row style does not have any effect on the appearance of rows. However, the style can already be used for “tagging” rows and the final options for the style can be configured at a later point in time.5.3.2 Rules Between Rows
Additional horizontal rules between rows can simply be added by placing the respec- tive rule command between\Row commands. The following example demonstrates this possibility.
\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}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl serve with a smile
5.4 Cell Appearance
Individual cells can be formatted by using the respective LATEX code directly in the value of the cell. One can disable the column’s configuredformatfor the cell by using the starred column name in\Row. The following example demonstrates starred column names.
\usepackage{url}\urlstyle{sf}
\NewKeyValTable{Links}{
service;
url: format=\url }
\begin{KeyValTable}{Links}
\Row{service=CTAN,
url=ctan.org/pkg/keyvaltable}
\Row{service=github,
url=github.com/Ri-Ga/keyvaltable}
\Row{service=Google Play, url*=none}
\end{KeyValTable}
service url
CTAN ctan.org/pkg/keyvaltable github github.com/Ri-Ga/keyvaltable Google Play none
5.5 Setting Global Defaults
\kvtSet{hoptionsi}
Thekeyvaltablepackage allows changing the default values globally for the parame- ters of tables and columns. This can be done by using the\kvtSetmacro.
\kvtSet{headbg=red,default=?,align=r}
\NewKeyValTable{Defaults}{x; y}
\begin{KeyValTable}{Defaults}
\Row{x=1}
\Row{y=4}
\end{KeyValTable}
x y 1 ?? 4
6 Customizing the Layout
The keyvaltable package provides some means for altering tables beyond those described in the previous sections. Those means are described in the following.
6.1 Custom Table Headers
By default, a table type defined by\NewKeyValTableincludes a single header row and each column of the table type has a header cell in this row. Through the optionalhlayoutiparameter of\NewKeyValTable, one can define multiple header rows and can define header cells that span multiple columns.
The following two examples illustrate how the headers key in the hlayouti parameter can be used for specifying custom headers.3 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.
3Inkeyvaltable v1.0, thehlayouti parameter specifiedonly the headers and did not use a headerskey for this. For compatibility, this can be enabled with thecompat=1.0package option.
\NewKeyValTable{Headers1}{
id: align=r, default=\thekvtRow.;
amount: align=r; ingredient: align=l;
step: align=X;
}[headers={
amount+ingredient: head=\textbf{ingredient};
step: head=\textbf{step}, align=l;
]}
\begin{KeyValTable}{Headers1}
\Row{amount=150g, ingredient=ice cream, step=put into bowl}
\Row{amount= 50g, ingredient=cherries, step=heat up and add to bowl}
\end{KeyValTable}
ingredient step
1. 150g ice cream put into bowl
2. 50g cherries heat up and add to bowl
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
“::”.
\NewKeyValTable{Headers2}{
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;
}[headers={
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}{Headers2}
\Row{date=01.01.1970,
min/Berlin=0\degree C, max/Berlin=...}
\end{KeyValTable}
temperature Berlin Paris date min max min max 01.01.1970 0◦C ...
The syntax for a hvaluei of theheaders key in thehlayouti parameter is as follows:
• hvalueiis a list, separated by “\\”, where each element in the list specifies the columns of a single headerhrowi.
• Eachhrowi, 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 headerhcelli.
• Eachhcelliis of the form
hcoli+…+hcoli:hpropertyi=hvaluei,hpropertyi=hvaluei,…
where eachhcoliis 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 inhcelli.
The hpropertyi=hvalueipairs configure properties of the header cell. Supported hpropertyikeys are the following.
align=halignment-letteri, hemptyi initially: c
This property specifies the alignment of content in the header cell. Thehvalueican be set to any column alignment understood by the underlying table environment used (see Section 6.4). This particularly includes l, c, r, and p, as well as X for some of the table environments. The initial value can be modified with
\kvtSet{HeadCell/align=...}.
head=htexti initially: hcolspeci
This property specifies the content of the header cell. The initial value for this property is the column specification, i.e., “hcoli+…+hcoli”.
6.2 Column Spanning
Thekeyvaltablepackage supports column spanning via “column groups”. A column group is a collection of adjacent columns, has its own name, and can be assigned a value just like “normal” columns can be. The following example demonstrates how column groups can be defined and be used.
\NewKeyValTable{AltRecipe}{
amount: align=r, format=\textbf;
ingredient: align=l;
step: align=X;
}[colgroups={
all: span=step+amount+ingredient }]\begin{KeyValTable}{AltRecipe}
\Row{amount=150g, ingredient=ice cream, step=put into bowl}
\Row{amount= 50g, ingredient=cherries, step=heat up and add to bowl}
\midrule
\Row{all=serve with a smile}
\end{KeyValTable}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl serve with a smile
As the example shows, column groups are defined through thecolgroupskey of the second optional argument of\NewKeyValTable. This key expects a semicolon- separated list of individual column groups definitions. Each such definition takes the same shape as a normal column definition – that is, first the name of the column group, then a colon, and then a comma-separated list of column properties.
The properties that can be set are the following.
span=hplus-separated columnsi
This property specifies which columns the column group shall span, as a plus- separated list of column names. Some or all of the columns can be hidden. All the displayed columns must be adjacent in the table, though.
align=halignment-letteri, hemptyi initially: c format=hsingle argument macroi initially: \kvtStrutted These properties are analogous to the respective properties of normal columns.
The only difference is that the initial column alignment of column groups is “c”
while the alignment of normal columns is “l”.
�
Initial values for all thealignandformatoptions can be set with\kvtSet, via the ColGroup/alignand, respectivelyColGroup/formatkeys (see alsoSection 5.5).6.2.1 Manual Column Spanning
The\multicolumnmacro 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.
\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}
col1 col2 col3
1 2 3
1 2+3
1+2 3
1+2+3
A word of warning: The\multicolumnmacro 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 (becausecol1spans two columns but the second, col3 is not empty). Thus, column spanning via
\multicolumnshould be used with care.
6.3 Captions
There are two ways to add captions tokeyvaltabletables: The first way is to enclose the table in atableenvironment. This is particularly suit for tables that do not span multiple pages, such as those produced through theonepage shape or the backendstabular,tabularx, andtabu (seeSection 6.4).
\begin{table}
\begin{KeyValTable}[shape=onepage]{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}
\caption{Cherries++}
\label{Cherries}
\end{table}
Table~\ref{Cherries} shows the recipe.
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl Table 23: Cherries++
Table 23 shows the recipe.
The second way to add captions is through thecaptionoption ofkeyvaltable tables. This option is available for the “multipage” shape and, respectively, the table backendslongtable,xltabular, andlongtabu(seeSection 6.4).
caption=htexti initially: hnonei
caption/lot=htexti initially: hnonei
caption/alt=htexti initially: hnonei
label=hnamei initially: hnonei
These options set the caption and, respectively, label of a table. Through the optioncaption/lot, the caption to be put into the list of tables can be specified;
if omitted,caption is used. Through the option caption/alt, the alternative
caption to be displayed on those pages of multipage tables where the main caption is not shown; if omitted, no caption is displayed on these pages.
The position of the caption is determined by the following option.
captionpos=t, b initially: b
This option specifies the position of table captions. Value “t” specifies that captions are at the top of (above) their tables; value “b” specifies that captions are at the bottom of (below) their tables. Moreover, in case of “t” the main caption is on top of thefirst page of a table while in case of “b” the main caption is at the bottom of thelast page of a table.
The following example shows the options in action.
\begin{KeyValTable}[captionpos=t,
caption=Cherries++, label=Cherries2]{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}
Table~\ref{Cherries2} shows the recipe.
Table 1: Cherries++
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl Table 1 shows the recipe.
6.4 Alternative Table Environments
The keyvaltable package internally uses traditional table environments, such as tabular, for typesetting the actual tables. Through the shape and backend properties of a table or table type, the table environment used by for the table or, respectively, table type can be changed. Table 2on page21compares the possible shapes/environments with regards to
• whether they support tables that span multiple pages,
• whether they supportcaptionandlabeloptions,
• whether they supportX-type (variable-width) columns,
• whether their width can be specified (through thewidth option), and
• whether they support a vertical or horizontal alignment of the table to be specified.
Finally, the table also lists the names of the packages that provide the respective environments. The packages for the shapesonepageandmultipageare loaded automatically. All other packages must be loaded via \usepackage when the respective shape or backend shall be used.
Examples can be found inFigure 2on the next page.
\NewKeyValTable[showrules=false]{ShapeNoX}{
id: align=l, default=\thekvtTypeRow;
l: align=l; c: align=c; r: align=r;}[headers={
l+c+r: head=\textbf{\kvtTableOpt{shape} shape}\\ ::}]
\begin{KeyValTable}[backend=tabular]{ShapeNoX}
\Row{l=left, c=center, r=right}
\Row{l=left-2, c=2-center-2, r=2-right}
\end{KeyValTable}\\
\begin{KeyValTable}[backend=longtable]{ShapeNoX}
\Row{l=left, c=center, r=right}
\Row{l=left-2, c=2-center-2, r=2-right}
\end{KeyValTable}
tabular shape
id l c r
1 left center right 2 left-2 2-center-2 2-right
longtable shape
id l c r
3 left center right 4 left-2 2-center-2 2-right
\NewKeyValTable[showrules=false]{ShapeWithX}{
id: align=l, default=\thekvtTypeRow;
l: align=l; X: align=X; r: align=r;}[headers={
l+X+r: head=\textbf{\kvtTableOpt{shape} shape}\\ ::}]
\begin{KeyValTable}[backend=tabularx]{ShapeWithX}
\Row{l=left, X=expandable, r=right}
\Row{l=left-2, X=expandable-2, r=2-right}
\end{KeyValTable}\medskip\\
\begin{KeyValTable}[backend=xltabular]{ShapeWithX}
\Row{l=left, X=expandable, r=right}
\Row{l=left-2, X=expandable-2, r=2-right}
\end{KeyValTable}
\begin{KeyValTable}[backend=tabu]{ShapeWithX}
\Row{l=left, X=expandable, r=right}
\Row{l=left-2, X=expandable-2, r=2-right}
\end{KeyValTable}
\begin{KeyValTable}[backend=longtabu]{ShapeWithX}
\Row{l=left, X=expandable, r=right}
\Row{l=left-2, X=expandable-2, r=2-right}
\end{KeyValTable}
tabularx shape
id l X r
1 left expandable right 2 left-2 expandable-2 2-right
xltabular shape
id l X r
3 left expandable right 4 left-2 expandable-2 2-right
tabu shape
id l X r
5 left expandable right 6 left-2 expandable-2 2-right
longtabu shape
id l X r
7 left expandable right 8 left-2 expandable-2 2-right
Figure 2: Examples for the backend option
shape backend multipage caption Xcolumns width align packages
onepage tabular/tabularx X X v tabularx
multipage longtable/xltabular X X X X h longtable, xltabular
with package optioncompat=1.0:
onepage tabu X X v tabu
multipage longtabu X X X X h tabu,longtable
tabular v
tabularx X X v tabularx
longtable X X h longtable
xltabular X X X X h xltabular
tabu X X v tabu
longtabu X X X X h tabu,longtable
Table 2: Comparison of table shapes and backends
7 Use with Other Packages
7.1 Named References (cleveref)
The\kvtLabelfeature of thekeyvaltablepackage can be used together with named references, as provided by thecleveref package. A name to a row label can be given by using the optional first argument to the\kvtLabelformatting 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.
\usepackage{cleveref}
\crefname{row}{line}{lines}
\NewKeyValTable[headformat=\textbf]{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}
Line Text 1 First row 2 After line 1
7.2 Tables from CSV Files (datatool and csvsimple)
Thekeyvaltablepackage itself does not offer its own functionality for generating tables from CSV files. However, together with existing CSV packages, table content can be sourced from CSV files. The remainder of this section shows how this can be achieved by example. The following CSV file serves as the data file in the examples.
We use the sameRecipe table type as previously.
id,amount,ingredient,step
snowman,3,balls of snow,staple all 3 balls snowman,1,carrot,stick into top ball
snowman,2,coffee beans,put diagonally above carrot cherries,150g,ice cream,put into bowl
cherries,50g,cherries,heat up and add to bowl
Listing 1: recipes.csv
datatool The package provides a variety of macros for loading and also displaying CSV database content. The following shows how the macros \DTLloaddb and
\DTLforeach*can be used, together with\AddKeyValRowand\ShowKeyValTable.
The example also shows how a simple filter can be applied to the rows via
\DTLforeach*.
\usepackage{datatool}
\DTLloaddb{recipes}{recipes.csv}
\DTLforeach*[\equal{\Id}{snowman}]{recipes}
{\Id=id,
\Amount=amount,\Ingr=ingredient,\Step=step}
{\AddKeyValRow{Recipe}[expandonce]{
amount=\Amount,ingredient=\Ingr,step=\Step}}
\ShowKeyValTable{Recipe}
amount ingredient step
3 balls of snow staple all 3 balls 1 carrot stick into top ball 2 coffee beans put diagonally above
carrot
Two aspects shall be noted. Firstly, we use \AddKeyValRow rather than KeyValTable, because\DTLforeach*interferes with howKeyValTableconstructs its rows and yields “misplaced\noalign” errors. We do not use \CollectRow here, because it requires two runs and we do not need the feature to show the table before the rows are specified. Secondly, we use the row optionexpandonceto ensure that the macros\Amount,\Ingr, and \Stepare expanded (i.e., replaced by their values). Without this option, all rows would only carry the three macros and display the value that these macros have at the time of the\ShowKeyValTable.
expandonce=true,false default: true,initially: false expand=true,false default: true,initially: false These row options can be used when programmatically constructing the rows of a table, particularly withKeyValTableContentand\CollectRow. Theexpandonce option expands all the cell values given to a row (default values not included) exactly once before including it in the respective row. Theexpandoption fully expands the cell values, inprotect’ed mode (i.e., robust commands are not expanded).
csvsimple For the sake of our example, using this package is very similar to using datatool.
\usepackage{csvsimple}
\csvreader[head to column names,
filter equal={\id}{cherries}]{recipes.csv}{}
{\AddKeyValRow{Recipe}[expand]{
amount=\amount,ingredient=\ingredient, step=\step}}
\ShowKeyValTable{Recipe}
amount ingredient step
150g ice cream put into bowl
50g cherries heat up and add to bowl
Two differences are noteworthy here: First, we can avoid specifying macro names for the columns through thehead to column names, which uses the column names as macro names. Second, we have to use theexpandoption rather thanexpandonce here, becausecsvsimpleapparently does not directly store the column value in the respective macro.
7.3 Computational Cells (xint)
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 thexintpackage and defining a custom format macro (here\Math) that takes over the computation.
\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}
type value simple 15.5 advanced 53.0
7.4 Cell Formatting (makecell)
Thekeyvaltablepackage can be used together with themakecellpackage in at least two ways:
1. formatting header cells using theheadproperty of columns;
2. formatting content cells using theformatproperty of columns.
The following example gives an impression.
\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}
short two lines just a test
8 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 thekeyvaltablepackage.
tablestyles: This package simplifies typesetting tables with common and/or more appealing appearances than default LATEX tables. This corresponds to what keyvaltable supports with the various coloring and formatting options to
\kvtSet,\NewKeyValTable, and individual tables. Thetablestylespackage builds on the default LATEX environments and syntax for typesetting tables (with column alignments specified in an argument to the table environment,
and columns separated by&in the body of the environment).
ctable: This package focuses on typesetting tables with captions and notes. With this package, the specification of table content is quite close to normal tabularenvironments, except that the package’s table creation is done via a macro,\ctable.
easytable: This package provides an environmentTABwhich 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 sim- pler table creation, likekeyvaltable. However, the package does not pursue separation of content from presentation or re-use of table layouts.
tabularkv: Despite the similarity in the name, this package pursues a different pur- pose. 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.
9 Future Work
• support for different headers on the first page vs. on subsequent pages of a multipage table; support configurable spacing between and above/below header rows
• support for more flexibility with regards to captions position (top vs. bottom) and distinct captions on first/middle/last page of the table.
• improved row coloring that makes sure that the alternation re-starts on continued pages of a table that spans several pages
• rerun detection for recorded rows (possibly viarerunfilecheck)
• nesting ofKeyValTableenvironments (this is so far not tested by the package author and might not work or work only to a limited extent)
10 Implementation
Content
10.1 Package Dependencies . 26 10.2 Auxiliary Code . . . 26 10.3 Setting Options . . . 28 10.4 Declaring Key-Value Ta-
bles . . . 32 10.5 Custom Layout Parame-
ters. . . 35
10.6 Row Numbering and La- beling . . . 41 10.7 Key-Value Table Content 41 10.8 Collecting Key-Value
Table Content . . . 56 10.9 Package Options . . . . 60 10.10Compatibility . . . 60
10.1 Package Dependencies
We use etoolbox for some convenience macros that make the code more easily maintainable and usexkeyvalfor options in key–value form. Thetrimspacespackage is used once for trimming spaces before a string comparison.
1\RequirePackage{etoolbox}
2\RequirePackage{xkeyval}
3\RequirePackage{trimspaces}
We usebooktabsfor nice horizontal lines andxcolorfor row coloring.
4\PassOptionsToPackage{table}{xcolor}
5\RequirePackage{xcolor}
6\RequirePackage{booktabs}
10.2 Auxiliary Code
10.2.1 List Parsing
\kvt@DeclareTrimListParser The\kvt@DeclareTrimListParser(*){hcommandi}{hseparatori}macro is equiv- alent toetoolbox’s \DeclareListParser, except that the hcommandi is defined such that it will remove trailing spaces from list elements before passing the list elements to the processing macro (i.e., to\door the user-provided macro). Note:
With\DeclareListParser,hcommandiis defined to only remove leading spaces but not trailing ones. This implementation relies on the internals ofetoolboxand works with v2.4 of the package, at least.
7\newcommand\kvt@DeclareTrimListParser{%
8 \@ifstar{\kvt@DeclareTrimListParser@i{*}}
9 {\kvt@DeclareTrimListParser@i{}}}
10\newcommand\kvt@DeclareTrimListParser@i[3]{%
11 \DeclareListParser#1{#2}{#3}\expandafter
12 \patchcmd\csname etb@lst@\expandafter\@gobble\string#2\endcsname
13 {\etb@listitem}{\kvt@etb@listitem}{}
14 {\kvt@warn{Failed to patch a command defined by the etoolbox
15 package, possibly because etoolbox internals have changed.
16 You might encounter superfluous spaces.}}}
The cascade of \expandafter below ensures that first the trimming macro is expanded and afterwards the outer\unexpandedof the timming macro’s expansion is expanded, which by definition of the “noexp” trimming macro fully expands the macro’s logic. The auxiliary macro below is only for switching the two arguments such that the expansion control can be applied to the second argument.
17\newcommand\kvt@etb@listitem[2]{%
18 \expandafter\expandafter\expandafter\kvt@etb@listitem@i
19 \expandafter\expandafter\expandafter{\trim@post@space@noexp{#2}}{#1}}
20\newcommand\kvt@etb@listitem@i[2]{\etb@listitem{#2}{#1}}
\kvt@dossvlist The \kvt@dossvlist{hlisti} macro parses a semicolon-separated list and runs
\dohitemifor every element of the list.
21\DeclareListParser{\kvt@dossvlist}{;}
\kvt@forpsvlist The\kvt@forpsvlist{hhandleri}{hlisti}parses a ‘+’-separated list.
22\kvt@DeclareTrimListParser*{\kvt@forpsvlist}{+}
\kvt@dobrklist The\kvt@dobrklist{hlisti}parses a ‘\\’-separated list.
23\kvt@DeclareTrimListParser{\kvt@dobrklist}{\\}
10.2.2 Errors and Warnings
\kvt@error
\kvt@warn These macros produce error and warning messages.
24\newcommand\kvt@error[2]{\PackageError{keyvaltable}{#1}{#2}}
25\newcommand\kvt@warn[1]{\PackageWarning{keyvaltable}{#1}}
10.2.3 Setting Keys
\kvt@setkeys
\kvt@setcmdkeys
\kvt@setcskeys
The\kvt@setkeys{hkeysi}{hfami}macro abbreviates\setkeys[kvt]hfamihkeysi (note the reverse order of arguments). The\kvt@setcmdkeys{hkeycmdi}{hfami}
and\kvt@setcskeys{hkeycsi}{hfami}abbreviate the cases wherehkeysiare stored in macrohkeycmdior, respectively, stored in a macro with name hkeycsi.
26\newcommand\kvt@setkeys[2]{\setkeys[kvt]{#2}{#1}}
27\newcommand\kvt@setcmdkeys[2]{%
28 \expandafter\kvt@setkeys\expandafter{#1}{#2}}
29\newcommand\kvt@setcskeys[2]{%
30 \expandafter\kvt@setcmdkeys\expandafter{\csname #1\endcsname}{#2}}
\kvt@setkeys@nopresets The\kvt@setkeys@nopresets{hkeysi}{hfamilyi}macro expands to a\kvt@setkeys in which no presets are active.
31\newcommand\kvt@setkeys@nopresets[2]{%
32 \kvt@xkv@disablepreset[kvt]{#2}{\kvt@setkeys{#1}{#2}}}
\kvt@colsetkeys
\kvt@colsetcmdkeys
\kvt@colsetcskeys
The\kvt@colsetkeys{hfami}{hkeysi}macro abbreviates\setkeys[KeyValTable]
with the same arguments. The \kvt@colsetcmdkeys{hfamcmdi}{hkeysi} and
\kvt@colsetcskeys{hfamcsi}{hkeysi}abbreviate the cases wherehfamiis stored in macrohfamcmdior, respectively, stored in a macro with namehfamcsi.
33\newcommand\kvt@colsetkeys[2]{\setkeys[KeyValTable]{#1}{#2}}
34\newcommand\kvt@colsetcmdkeys[2]{%
35 \expandafter\kvt@colsetkeys\expandafter{#1}{#2}}
36\newcommand\kvt@colsetcskeys[2]{%
37 \expandafter\kvt@colsetcmdkeys\expandafter{\csname #1\endcsname}{#2}}
\kvtStrutted The\kvtStrutted[hinneri]{hargi}macro prefixes and suffixes the argumenthargi 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. The optional[hinneri]argument, if provided, should be a macro that takes one argument. In this case, instead ofhargi,hinneri{hargi}is prefixed and sufficed with\strut.
38\newcommand\kvtStrutted[2][\@firstofone]{%
39 \strut#1{#2}\ifhmode\expandafter\strut\fi}
10.3 Setting Options
\kvtSet The\kvtSet{hoptionsi}set the default options, which apply to all tables typeset with the package.
40\newcommand\kvtSet[1]{%
41 \kvt@setkeys{#1}{global,Table,Column}%
42 \ifdefvoid\kvt@@presetqueue{}
43 {\kvt@@presetqueue\undef\kvt@@presetqueue}}
\kvt@lazypreset The\kvt@@lazypreset{hfamilyi}{hhead keysi}macro collects a request for pre- settinghhead keysiin family keyhfamilyi. Using this macro, one can avoid causing problems with usingxkeyval’s\presetkeysinside thehfunctionidefined for a key (e.g., via\define@key). The collected requests can be performed by expanding
the\kvt@@presetqueue macro.
44\newcommand\kvt@lazypreset[2]{%
45 \appto\kvt@@presetqueue{\presetkeys[kvt]{#1}{#2}{}}}
\kvt@keysetter The\kvt@keysetter{hmacroi}{hfami}{hkeyi}{hvaluei}{hfunci}macro is an aux- iliary macro that can be used inside the “func” argument of \[email protected] macros. If hmacroi is not defined, \kvt@keysetter expands to an instance of
\kvt@lazypresetin order to set a global default. Otherwise, \kvt@keysetter expands tohfunci, which is supposed to set a key for the specific context referenced byhmacroi.
46\newcommand\kvt@keysetter[5]{%
47 \ifdefvoid{#1}
48 {\kvt@lazypreset{#2}{#3=#4}}
49 {#5}}
\kvtTableOpt The \kvtTableOpt{hoptnamei} macro, inside a KeyValTable environment, ex- pands to the value of the table optionhoptnamei.
50\newcommand\kvtTableOpt[1]{\csname cmdkvt@Table@#1\endcsname}
10.3.1 Table Options
The following code defines the possible table options.
51\define@cmdkey[kvt]{Table}{rowbg}{}