%% %% This is file `keyvaltable.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% keyvaltable.dtx (with options: `package') %% %% Copyright (C) 2016-2020 by Richard Grewe %% %% This file may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.2 of this license %% or (at your option) any later version. The latest version of this %% license is in: %% %% http://www.latex-project.org/lppl.txt %% %% and version 1.2 or later is part of all distributions of LaTeX version %% 1999/12/01 or later. %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{keyvaltable} [2020/04/05 v2.2 Package for filling tables using key-value lists] \RequirePackage{etoolbox} \RequirePackage{xkeyval} \RequirePackage{trimspaces} \PassOptionsToPackage{table}{xcolor} \RequirePackage{xcolor} \RequirePackage{booktabs} \newcommand\kvt@DeclareTrimListParser{% \@ifstar{\kvt@DeclareTrimListParser@i{*}} {\kvt@DeclareTrimListParser@i{}}} \newcommand\kvt@DeclareTrimListParser@i[3]{% \DeclareListParser#1{#2}{#3}\expandafter \patchcmd\csname etb@lst@\expandafter\@gobble\string#2\endcsname {\etb@listitem}{\kvt@etb@listitem}{} {\kvt@warn{Failed to patch a command defined by the etoolbox package, possibly because etoolbox internals have changed. You might encounter superfluous spaces.}}} \newcommand\kvt@etb@listitem[2]{% \expandafter\expandafter\expandafter\kvt@etb@listitem@i \expandafter\expandafter\expandafter{\trim@post@space@noexp{#2}}{#1}} \newcommand\kvt@etb@listitem@i[2]{\etb@listitem{#2}{#1}} \DeclareListParser{\kvt@dossvlist}{;} \kvt@DeclareTrimListParser*{\kvt@forpsvlist}{+} \kvt@DeclareTrimListParser{\kvt@dobrklist}{\\} \newcommand\kvt@error[2]{\PackageError{keyvaltable}{#1}{#2}} \newcommand\kvt@warn[1]{\PackageWarning{keyvaltable}{#1}} \newcommand\kvt@setkeys[2]{\setkeys[kvt]{#2}{#1}} \newcommand\kvt@setcmdkeys[2]{% \expandafter\kvt@setkeys\expandafter{#1}{#2}} \newcommand\kvt@setcskeys[2]{% \expandafter\kvt@setcmdkeys\expandafter{\csname #1\endcsname}{#2}} \newcommand\kvt@setkeys@nopresets[2]{% \kvt@xkv@disablepreset[kvt]{#2}{\kvt@setkeys{#1}{#2}}} \newcommand\kvt@colsetkeys[2]{\setkeys[KeyValTable]{#1}{#2}} \newcommand\kvt@colsetcmdkeys[2]{% \expandafter\kvt@colsetkeys\expandafter{#1}{#2}} \newcommand\kvt@colsetcskeys[2]{% \expandafter\kvt@colsetcmdkeys\expandafter{\csname #1\endcsname}{#2}} \newcommand\kvtStrutted[2][\@firstofone]{% \strut#1{#2}\ifhmode\expandafter\strut\fi} \newcommand\kvtSet[1]{% \kvt@setkeys{#1}{global,Table,Column}% \ifdefvoid\kvt@@presetqueue{} {\kvt@@presetqueue\undef\kvt@@presetqueue}} \newcommand\kvt@lazypreset[2]{% \appto\kvt@@presetqueue{\presetkeys[kvt]{#1}{#2}{}}} \newcommand\kvt@keysetter[5]{% \ifdefvoid{#1} {\kvt@lazypreset{#2}{#3=#4}} {#5}} \newcommand\kvtTableOpt[1]{\csname cmdkvt@Table@#1\endcsname} \define@cmdkey[kvt]{Table}{rowbg}{} \define@cmdkey[kvt]{Table}{headbg}{} \define@cmdkey[kvt]{Table}{headalign}{} \define@cmdkey[kvt]{Table}{headformat}{} \define@cmdkey[kvt]{Table}{width}{} \define@boolkey[kvt]{Table}{showhead}{} \define@boolkey[kvt]{Table}{showrules}{} \define@choicekey[kvt]{Table}{captionpos}{t,b} {\csdef{cmdkvt@Table@captionpos}{#1}} \define@choicekey[kvt]{Table}{valign}{t,c,b} {\csdef{cmdkvt@Table@valign}{#1}} \define@choicekey[kvt]{Table}{halign}{l,c,r} {\csdef{cmdkvt@Table@halign}{#1}} \define@key[kvt]{Table}{style}{\kvt@UseTableStyles{#1}} \define@boolkey[kvt]{Table}{norowbg}[true]{% \kvt@setkeys{rowbg={}}{Table}} \define@boolkey[kvt]{Table}{nobg}[true]{% \kvt@setkeys{rowbg={},headbg={}}{Table}} \define@boolkey[kvt]{Table}{norules}[true]{% \ifbool{#1} {\kvt@setkeys{showrules=false}{Table}} {\kvt@setkeys{showrules=true}{Table}}} \define@key[kvt]{Table}{backend}{\ifinlist{#1}{\kvt@@tablebackends} {\csdef{cmdkvt@Table@shape}{#1}} {\kvt@error{Table backend '#1' not known} {Check for misspellings in '#1'}}} \define@key[kvt]{Table}{shape}{\ifinlist{#1}{\kvt@@tableshapes} {\csdef{cmdkvt@Table@shape}{#1}} {\ifinlist{#1}{\kvt@@tablebackends} {\kvt@warn{Using a backend ('#1') as shape is deprecated. Use the 'backend' option instead.}% \csdef{cmdkvt@Table@shape}{#1}} {\kvt@error{Table shape '#1' not known} {Check for misspellings in '#1'}}}} \define@cmdkey[kvt]{TableEnv}{caption}{} \define@cmdkey[kvt]{TableEnv}{caption/lot}{} \define@cmdkey[kvt]{TableEnv}{caption/alt}{} \define@cmdkey[kvt]{TableEnv}{label}{} \define@boolkey[kvt]{TableEnv}{resume}[true]{% \ifbool{#1}{\ifundef\kvt@@rowcountlast {\kvt@error{No previous table whose counter could be resumed.} {Check whether the "resume" is intentional and whether a previously existing predecessor table has disappeared.}}{}}{}} \define@boolkey[kvt]{TableEnv}{resume*}[true]{% \ifbool{#1} {\ifundef\kvt@@lastenvopt {\kvt@error{No previous table whose options could be resume*'d.} {Check whether the "resume*" is intentional and whether a previously existing predecessor table has disappeared.}}{}% \kvt@setcmdkeys\kvt@@lastenvopt{Table}% \kvt@setkeys{resume}{TableEnv}} {}} \define@key[kvt]{Column}{default}{\kvt@colkeysetter{default}{#1}} \define@key[kvt]{Column}{format}{\kvt@colkeysetter{format}{#1}} \define@key[kvt]{Column}{align}{\kvt@colkeysetter{align}{#1}} \define@key[kvt]{Column}{head}{\kvt@colkeysetter{head}{#1}} \define@boolkey[kvt]{Column}{hidden}[true]{% \kvt@colkeysetter{hidden}{#1}} \newcommand\kvt@colkeysetter[2]{% \kvt@keysetter{\kvt@@column}{Column}{#1}{#2}{% \csdef{kvt@col@#1@\kvt@@column}{#2}}} \newcommand\kvt@def@globalopt[2]{% \define@key[kvt]{global}{#1/#2}{\kvt@lazypreset{#1}{#2={##1}}}} \newcommand\kvt@def@globalopts[2]{% \forcsvlist{\kvt@def@globalopt{#1}}{#2}} \define@cmdkey[kvt]{ColGroup}{span}{% \csgdef{kvt@colgrp@span@\kvt@@tname @\kvt@@colgrp}{#1}} \define@cmdkey[kvt]{ColGroup}{align}{% \csgdef{kvt@colgrp@align@\kvt@@tname @\kvt@@colgrp}{#1}} \define@cmdkey[kvt]{ColGroup}{format}{% \csgdef{kvt@colgrp@format@\kvt@@tname @\kvt@@colgrp}{#1}} \kvt@def@globalopts{ColGroup}{align, format} \define@cmdkey[kvt]{Layout}{headers}{% \expandafter\kvt@parseheadrows\expandafter{\kvt@@tname}{#1}} \define@cmdkey[kvt]{Layout}{colgroups}{% \expandafter\kvt@parsecolgroups\expandafter{\kvt@@tname}{#1}} \define@key[kvt]{HeadCell}{head}{% \csdef{kvt@@hdcell@head@\kvt@@hdcell}{#1}} \define@key[kvt]{HeadCell}{align}{% \csdef{kvt@@hdcell@align@\kvt@@hdcell}{#1}} \kvt@def@globalopts{HeadCell}{align} \define@cmdkey[kvt]{Row}{bg}{} \define@cmdkey[kvt]{Row}{format}{} \define@cmdkey[kvt]{Row}{format*}{} \define@cmdkey[kvt]{Row}{format!}{} \define@cmdkey[kvt]{Row}{align}{} \define@boolkey[kvt]{Row}{headlike}[true]{% \ifbool{#1}{% \edef\kvt@@opts{% bg={\expandonce\cmdkvt@Table@headbg},% format!={\expandonce\cmdkvt@Table@headformat},% align={\expandonce\cmdkvt@Table@headalign}}% \expandafter\kvt@setkeys@nopresets\expandafter{\kvt@@opts}{Row}% }{}} \define@boolkey[kvt]{Row}{hidden}[true]{} \define@cmdkey[kvt]{Row}{below}{} \define@cmdkey[kvt]{Row}{above}{} \define@key[kvt]{Row}{around}{% \kvt@setkeys@nopresets{below={#1},above={#1}}{Row}} \define@key[kvt]{Row}{style}{\kvt@UseRowStyles{#1}} \define@boolkey[kvt]{Row}{uncounted}[true]{} \define@boolkey[kvt]{Row}{expand}[true]{} \define@boolkey[kvt]{Row}{expandonce}[true]{} \kvt@def@globalopts{Row}{ bg,hidden,below,above,around,style,uncounted, expand,expandonce} \AtEndOfPackage{\kvtSet{% rowbg=white..black!10, headbg=black!14, showhead=true, showrules=true, headformat=\@firstofone, headalign=, shape=multipage, width=\linewidth, captionpos=b, default=, format=\kvtStrutted, align=l, head=, hidden=false, Row/bg={}, Row/hidden=false, Row/above={}, Row/below={}, Row/uncounted=false, Row/expand=false, Row/expandonce=false, ColGroup/align=c, ColGroup/format=\kvtStrutted, HeadCell/align=c, }} \newcommand\NewKeyValTable[3][]{% \@ifnextchar[%] {\kvt@NewKeyValTable{#1}{#2}{#3}}% {\kvt@NewKeyValTable{#1}{#2}{#3}[]}} \def\kvt@NewKeyValTable#1#2#3[#4]{% \ifinlist{#2}{\kvt@alltables} {\kvt@error{Table type with name '#2' already defined} {Check '#2' for typos and check other uses of \string\NewKeyValTable}}{}% \csdef{kvt@options@#2}{#1}% \csdef{kvt@headings@#2}{}% \csdef{kvt@alignments@#2}{}% \csdef{kvt@allcolumns@#2}{}% \csdef{kvt@displaycols@#2}{}% \csdef{kvt@rowcount@#2}{0}% \csdef{kvt@rows@#2}{}% \csdef{kvt@headings@#2}{\kvt@defaultheader}% \listadd\kvt@alltables{#2}% \def\do##1{% \kvt@parsecolspec{#2}##1::\@undefined}% \kvt@dossvlist{#3}% \csdef{kvt@headrowcount@#2}{1}% \csappto{kvt@headings@#2}{{\@nil}}% \kvt@parselayout{#4}{#2}% } \def\kvt@parsecolspec#1#2:#3:#4\@undefined{% \kvt@checkcolspecempty{#4}{column}{#2}% \def\kvt@@column{#2}% \trim@spaces@in\kvt@@column \expandafter\kvt@parsecolspec@i\expandafter{\kvt@@column}{#1}{#3}} \newcommand\kvt@parsecolspec@i[3]{\kvt@parsecolspec@ii{#2}{#1}{#3}} \newcommand\kvt@parsecolspec@ii[3]{% \def\kvt@@column{#1@#2}% \ifinlistcs{#2}{kvt@allcolumns@#1} {\kvt@error{Column name '#2' declared more than once in table type '#1'}{Check '#2' for typos; column names declared so far:% \forlistcsloop{ }{kvt@allcolumns@#1}}}{}% \listcsadd{kvt@allcolumns@#1}{#2}% \kvt@setkeys{#3}{Column}% \ifcsstring{kvt@col@hidden@#1@#2}{true}{}{% \cseappto{kvt@alignments@#1}{\csexpandonce{kvt@col@align@#1@#2}}% \ifcsvoid{kvt@col@head@#1@#2}% {\csappto{kvt@headings@#1}{{#2}}}% {\cseappto{kvt@headings@#1}{{\csexpandonce{kvt@col@head@#1@#2}}}}% \listcsadd{kvt@displaycols@#1}{#2}% }% \define@cmdkey[KeyValTable]{#1}{#2}[]{}% \define@key[KeyValTable]{#1}{#2*}{% \csdef{cmdKeyValTable@#1@#2}{##1}% \csdef{kvt@@noformat@#1@#2}{1}}% \presetkeys[KeyValTable]{#1}{#2}{}% \undef\kvt@@column} \newcommand\kvt@defaultheader{% \noexpand\kvt@rowcolorornot{\cmdkvt@Table@headbg}% \kvt@defaultheader@i{}} \newcommand\kvt@defaultheader@i[2]{% \kvt@ifnil{#2}{\noexpand\tabularnewline}{% \unexpanded{#1}% \ifdefvoid\cmdkvt@Table@headalign {\expandonce\cmdkvt@Table@headformat{\unexpanded{#2}}} {\noexpand\multicolumn{1}{\expandonce\cmdkvt@Table@headalign} {\expandonce\cmdkvt@Table@headformat{\unexpanded{#2}}}}% \kvt@defaultheader@i{&}}} \newcommand\kvt@ifnil[1]{% \ifx\@nil#1\relax \expandafter\@firstoftwo\else \expandafter\@secondoftwo\fi} \newcommand\kvt@alltables{} \newcommand\kvt@parselayout[2]{% \def\kvt@@tname{#2}% \kvt@setkeys{#1}{Layout}% \undef\kvt@@tname} \newcommand\kvt@parsecolgroups[2]{% \begingroup \def\kvt@@result{}% \def\do##1{\kvt@parsecolgroup{#1}##1::\@undefined}% \kvt@dossvlist{#2}% \expandafter\endgroup\kvt@@result} \def\kvt@parsecolgroup#1#2:#3:#4\@undefined{% \kvt@checkcolspecempty{#4}{column group}{#2}% \ifinlistcs{#2}{kvt@allcolumns@#1}{\kvt@error {Name `#2' cannot be used for a column group in table type `#1', as it is already used for a column} {Check the \string\NewKeyValTable{#1} for the names of known columns and check `#2' for a typo.}}{}% \ifinlistcs{#2}{kvt@grpcolkeys@#1}{\kvt@error {Name `#2' is used twice in table type `#1'} {Check the \string\NewKeyValTable{#1} for typos in the names of columns groups.}}{}% \def\kvt@@colgrp{#2}% \kvt@setkeys{#3}{ColGroup}% \kvt@checkcolgroupcs{kvt@colgrp@span@#1@#2}{#1}{#2}% \eappto\kvt@@result{% \noexpand\define@cmdkey[KeyValTable]{#1}{#2}{% \ifdefvoid\kvt@@colgrp@first{}{% \noexpand\kvt@xkv@disablepreset[KeyValTable]{#1}{% \noexpand\setkeys[KeyValTable]{#1}{% \expandonce\kvt@@colgrp@first=\noexpand\kvt@@@colgroup {\unexpanded{#2}}% {\expandonce\kvt@@colgrp@n}% {\csexpandonce{kvt@colgrp@align@#1@#2}}% {\unexpanded{##1}}}}% }% }}% \listcsadd{kvt@grpcolkeys@#1}{#2}} \newcommand\kvt@checkcolspecempty[3]{% \ifstrempty{#1}{}{\ifstrequal{#1}{:}{}{\kvt@error {Too many ':' in definition of #2 '#3'} {Check whether there is an accidental ':' that should actually be a ',' or ';'.}}}} \newcommand\kvt@checkcolgroup[3]{% \def\kvt@@psvdo##1{% \ifinlistcs{##1}{kvt@allcolumns@#2}{}{\kvt@error {Column `##1' referenced in column group `#3' not known in table type `#2'} {Check the \string\NewKeyValTable{#2} for the names of known columns and check `##1' for a typo.}}% \ifcsvoid{kvt@@incolgrp@##1}{}{\kvt@error {Column `##1' used more than once in column group `#3' of table type `#2'} {Check `##1' for a typo.}}% \csdef{kvt@@incolgrp@##1}{#2}% }\kvt@forpsvlist{\kvt@@psvdo}{#1}% \def\kvt@@colgrp@n{0}% \let\kvt@@colgrp@first\relax \def\kvt@@status{0}% \def\kvt@@coldo##1{% \ifcsvoid{kvt@@incolgrp@##1} {\expandafter\ifcase\kvt@@status \or \def\kvt@@status{2}\fi}% {\expandafter\ifcase\kvt@@status \def\kvt@@status{1}\def\kvt@@colgrp@first{##1}% \or\or \kvt@error{Column group `\kvt@@colgrp' must consist of only consecutive columns, but it is not}% {Compare `\string\kvt@@curgrp' to the column ordering as specified in `\string\NewKeyValTable{#1}'}% \fi \edef\kvt@@colgrp@n{\the\numexpr\kvt@@colgrp@n+1\relax}% \csundef{kvt@@incolgrp@##1}}% }\forlistcsloop{\kvt@@coldo}{kvt@displaycols@#2}} \newcommand\kvt@checkcolgroupcs[3]{% \expandafter\expandafter\expandafter \kvt@checkcolgroup \expandafter\expandafter\expandafter{\csname #1\endcsname}{#2}{#3}} \newcommand\kvt@parseheadrows[2]{% \ifstrempty{#2}{}{\kvt@parseheadrows@i{#2}{#1}}} \newcommand\kvt@parseheadrows@i[2]{% \csdef{kvt@@custheadrows@#2}{}% \csdef{kvt@headrowcount@#2}{0}% \begingroup \def\kvt@@parseheadrows{}% \def\do##1{% \ifstrequal{##1}{::} {\appto\kvt@@parseheadrows{% \cseappto{kvt@@custheadrows@#2}{% \csexpandonce{kvt@headings@#2}}}} {\appto\kvt@@parseheadrows{\kvt@parseheadrow{#2}{##1}}}% \appto\kvt@@parseheadrows{\csedef{kvt@headrowcount@#2}{% \the\numexpr\csuse{kvt@headrowcount@#2}+1\relax}}% }\kvt@dobrklist{#1}% \expandafter\endgroup\kvt@@parseheadrows \csletcs{kvt@headings@#2}{kvt@@custheadrows@#2}} \newcommand\kvt@parseheadrow[2]{% \begingroup \def\do##1{\kvt@parsehdcolspec{#1}##1::\@undefined}% \kvt@dossvlist{#2}% \let\kvt@@tmpgrphd\@empty \kvt@@span\z@ \undef\kvt@@curhd \undef\kvt@@lasthd \kvt@def@atseconduse\kvt@@switchcol{\appto\kvt@@tmpgrphd{&}}% \def\do##1{\letcs\kvt@@curhd{kvt@@hdcellof@##1}% \ifdefequal\kvt@@curhd\kvt@@lasthd {\advance\kvt@@span\@ne}% {\ifnum\kvt@@span>\z@ \expandafter\kvt@concludehdcolumn\fi \ifdefvoid\kvt@@curhd{}{\ifcsdef{kvt@@hdcelldone@\kvt@@curhd}{% \kvt@error{Header cell `\kvt@@curhd' must consist of only consecutive columns, but it is not}% {Compare `\string\kvt@@curhd' to the column ordering as specified in `\string\NewKeyValTable{#1}'}}{}}% \kvt@@span\@ne \let\kvt@@lasthd\kvt@@curhd}% }\dolistcsloop{kvt@displaycols@#1}% \kvt@concludehdcolumn \appto\kvt@@tmpgrphd{\tabularnewline}% \edef\do{\noexpand\csappto{kvt@@custheadrows@#1}{% \unexpanded{\noexpand\kvt@rowcolorornot{\cmdkvt@Table@headbg}}% \noexpand\unexpanded{\expandonce{\kvt@@tmpgrphd}}}}% \expandafter\endgroup\do} \newcommand\kvt@rowcolorornot[1]{\ifstrempty{#1}{}{\rowcolor{#1}}} \newcommand\kvt@rowcolorcmdornot[1]{\ifdefvoid{#1}{}{% \expandafter\rowcolor\expandafter{#1}}} \newcount\kvt@@bodyrow \newcount\kvt@@span \newcommand\kvt@concludehdcolumn{% \kvt@@switchcol \ifdefvoid\kvt@@lasthd{}{% \eappto\kvt@@tmpgrphd{\noexpand\multicolumn {\the\kvt@@span} {\csexpandonce{kvt@@hdcell@align@\kvt@@lasthd}} {\noexpand\cmdkvt@Table@headformat {\csexpandonce{kvt@@hdcell@head@\kvt@@lasthd}}}}% \cslet{kvt@@hdcelldone@\kvt@@lasthd}{\@ne}}} \def\kvt@parsehdcolspec#1#2:#3:#4\@undefined{% \kvt@checkcolspecempty{#4}{header cell}{#2}% \def\kvt@@colreg##1{% \ifinlistcs{##1}{kvt@allcolumns@#1}{} {\kvt@error{Column `##1', referenced in header cell `#2', not known in table type `#1'}{Check the \string\NewKeyValTable{#1} for the names of known columns and check `##1' for a typo.}}% \ifcsmacro{kvt@@hdcellof@##1} {\kvt@error{Column `##1' used in more than one header cell} {Check the fourth, optional argument of \string\NewKeyValTable and eliminate multiple occurrences of column `##1'.}} {\csdef{kvt@@hdcellof@##1}{#2}}% }\kvt@forpsvlist{\kvt@@colreg}{#2}% \def\kvt@@hdcell{#2}% \kvt@setkeys{#3}{HeadCell}} \newcounter{kvtRow} \newcounter{kvtTypeRow} \newcounter{kvtTotalRow} \setcounter{kvtTotalRow}{0} \newcommand\kvtLabel[3][]{% \setcounter{kvt@LabelCtr}{\value{#2}}% \addtocounter{kvt@LabelCtr}{-1}% \refstepcounter{kvt@LabelCtr}% \ifstrempty{#3}{}{% \ifstrempty{#1}{\label{#3}}{\label[#1]{#3}}}% \csuse{the#2}} \newcounter{kvt@LabelCtr} \newenvironment{KeyValTable}[2][]{% \def\Row{\kvt@AddKeyValRow {\noalign\bgroup}{\expandafter\egroup\kvt@@row}{#2}}% \kvt@SetOptions{#2}{#1}% \ifbool{kvt@TableEnv@resume*}{} {\gdef\kvt@@lastenvopt{#1}}% \csuse{kvt@StartTable@\cmdkvt@Table@shape}{#2}% }{% \csuse{kvt@EndTable@\cmdkvt@Table@shape}} \newcommand\kvt@SetOptions[2]{\expandafter \kvt@SetOptions@i\expandafter{\csname kvt@options@#1\endcsname}{#2}} \newcommand\kvt@SetOptions@i[2]{\expandafter \kvt@setkeys\expandafter{#1,#2}{Table,TableEnv}} \define@boolkey[metatbl]{EnvProp}{isLong}{\metatbl@boolprop{isLong}{#1}} \define@boolkey[metatbl]{EnvProp}{isTabu}{\metatbl@boolprop{isTabu}{#1}} \define@boolkey[metatbl]{EnvProp}{hasWidth}{% \metatbl@boolprop{hasWidth}{#1}} \define@boolkey[metatbl]{EnvProp}{hasCaption}{% \metatbl@boolprop{hasCaption}{#1}} \define@boolkey[metatbl]{EnvProp}{canVAlign}{% \metatbl@boolprop{canVAlign}{#1}} \define@boolkey[metatbl]{EnvProp}{canHAlign}{% \metatbl@boolprop{canHAlign}{#1}} \define@cmdkey[metatbl]{EnvProp}{packages}{\metatbl@setprop{pkg}{#1}} \define@key[metatbl]{EnvProp}{atEnd}{\metatbl@setprop[1]{atEnd}{#1}} \newrobustcmd\metatblRegisterEnv[2]{% \edef\metatbl@@envname{#1}% \csdef{metatbl@@registered@#1}{true}% \setkeys[metatbl]{EnvProp}{#2}} \newcommand\metatbl@setprop[3][0]{% \expandafter\newcommand \csname metatbl@EnvProp@#2@\metatbl@@envname\endcsname[#1]{#3}} \newcommand\metatbl@boolprop[2]{% \providebool{metatbl@EnvProp@#1@\metatbl@@envname}% \setbool{metatbl@EnvProp@#1@\metatbl@@envname}{#2}} \newcommand\metatblRegistered[1]{\ifcsdef{metatbl@@registered@#1}} \newcommand\metatblIsLong[1]{\ifbool{metatbl@EnvProp@isLong@#1}} \newcommand\metatblIsTabu[1]{\ifbool{metatbl@EnvProp@isTabu@#1}} \newcommand\metatblHasWidth[1]{\ifbool{metatbl@EnvProp@hasWidth@#1}} \newcommand\metatblHasCaption[1]{\ifbool{metatbl@EnvProp@hasCaption@#1}} \newcommand\metatblCanVAlign[1]{\ifbool{metatbl@EnvProp@canVAlign@#1}} \newcommand\metatblCanHAlign[1]{\ifbool{metatbl@EnvProp@canHAlign@#1}} \newcommand\metatblUsePackage[1]{% \def\do##1{% \metatbl@csnamearg\usepackage{metatbl@EnvProp@pkg@##1}}% \docsvlist{#1}} \newcommand\metatblRequire[1]{% \def\do##1{% \metatbl@csnamearg\RequirePackage{metatbl@EnvProp@pkg@##1}}% \docsvlist{#1}} \newcommand\metatblAtEnd[2]{% \csname metatbl@EnvProp@atEnd@#1\endcsname{#2}} \newcommand\metatbl@csnamearg[2]{% \expandafter\expandafter\expandafter#1% \expandafter\expandafter\expandafter{\csname#2\endcsname}} \metatblRegisterEnv{tabular}{% isLong=false, hasWidth=false, isTabu=false, hasCaption=false, canVAlign=true, canHAlign=false, packages={}, atEnd={\preto\endtabular{#1}}, } \metatblRegisterEnv{tabularx}{% isLong=false, hasWidth=true, isTabu=false, hasCaption=false, canVAlign=true, canHAlign=false, packages=tabularx, atEnd={% \preto\TX@endtabularx{\toks@\expandafter{\the\toks@#1}}% \preto\XLT@i@TX@endtabularx{\toks@\expandafter{\the\toks@#1}}}, } \metatblRegisterEnv{longtable}{% isLong=true, hasWidth=false, isTabu=false, hasCaption=true, canVAlign=false, canHAlign=true, packages={longtable}, atEnd={\preto\endlongtable{#1}}, } \metatblRegisterEnv{xltabular}{% isLong=true, hasWidth=true, isTabu=false, hasCaption=true, canVAlign=false, canHAlign=true, packages=xltabular, atEnd={\preto\XLT@ii@TX@endtabularx{\toks@\expandafter{\the\toks@#1}}}, } \metatblRegisterEnv{tabu}{% isLong=false, hasWidth=true, isTabu=true, hasCaption=false, canVAlign=true, canHAlign=false, packages={tabu}, atEnd={\preto\endtabular{#1}}, } \metatblRegisterEnv{longtabu}{% isLong=true, hasWidth=true, isTabu=true, hasCaption=true, canVAlign=false, canHAlign=true, packages={tabu,longtable}, atEnd={\preto\endlongtable{#1}}, } \newrobustcmd\metatbl@ifhasXcolumns[1]{% \begingroup \def\metatbl@@branch{\@secondoftwo}% \def\NC@rewrite@X{\def\metatbl@@branch{\@firstoftwo}\NC@find l}% \@mkpream{#1}% \expandafter\endgroup\metatbl@@branch} \newcommand\kvt@StartTabularlike[2]{% \metatblAtEnd{#1}{\kvt@@endhook}% \let\kvt@@endhook\@empty \let\kvt@@prehook\@empty \ifbool{kvt@Table@showrules} {\def\kvt@@rule##1{\csuse{##1rule}}} {\def\kvt@@rule##1{}}% \appto\kvt@@prehook{\kvt@@rule{top}}% \appto\kvt@@endhook{\kvt@@rule{bottom}}% \appto\kvt@@endhook{\noalign{% \csxdef{kvt@rowcount@#2}{\thekvtTypeRow}% \csxdef{kvt@@rowcountlast}{\thekvtRow}}}% \ifdefvoid\cmdkvt@TableEnv@caption {\let\kvt@@caption@main\@empty \let\kvt@@caption@alt\@empty} {\metatblHasCaption{#1} {\edef\kvt@@caption@main{% \csexpandonce{kvt@caption@\cmdkvt@Table@captionpos}% \ifcsvoid{cmdkvt@TableEnv@caption/lot}{} {[{\csexpandonce{cmdkvt@TableEnv@caption/lot}}]}% {\expandonce\cmdkvt@TableEnv@caption \ifdefvoid\cmdkvt@TableEnv@label{}{% \noexpand\label{\expandonce\cmdkvt@TableEnv@label}}}% \noexpand\\}% \ifcsvoid{cmdkvt@TableEnv@caption/alt} {\def\kvt@@caption@alt{}} {\edef\kvt@@caption@alt{% \csexpandonce{kvt@caption@\cmdkvt@Table@captionpos}[]% {\csexpandonce{cmdkvt@TableEnv@caption/alt}}% \noexpand\\}}% }{\kvt@error {Caption lost, table backend '#1' does not support captions} {Consider placing the KeyValTable environment inside a 'table' environment and use the \string\caption\space macro inside.}}}% \ifdefstring{\cmdkvt@Table@captionpos}{t} {\let\kvt@@caption@headmain\kvt@@caption@main\let\kvt@@caption@footmain\@empty \let\kvt@@caption@headalt\kvt@@caption@alt \let\kvt@@caption@footalt\@empty} {\let\kvt@@caption@footmain\kvt@@caption@main\let\kvt@@caption@headmain\@empty \let\kvt@@caption@footalt\kvt@@caption@alt \let\kvt@@caption@headalt\@empty}% \ifbool{kvt@Table@showhead} {\eappto\kvt@@prehook{\csuse{kvt@headings@#2}\noexpand\kvt@@rule{mid}}} {}% \ifdefvoid{\cmdkvt@Table@valign}{}{\metatblCanVAlign{#1}{} {\undef{\cmdkvt@Table@valign}% \kvt@warn{Table environment '#1' of table '#2' does not support the vertical alignment option (valign). Ignoring the option}}}% \ifdefvoid{\cmdkvt@Table@halign}{}{\metatblCanHAlign{#1}{} {\undef{\cmdkvt@Table@halign}% \kvt@warn{Table environment '#1' of table '#2' does not support the horizontal alignment option (halign). Ignoring the option}}}% \global\kvt@@bodyrow=0\relax \ifbool{kvt@TableEnv@resume} {\setcounter{kvtRow}{\csuse{kvt@@rowcountlast}}} {\setcounter{kvtRow}{0}}% \setcounter{kvtTypeRow}{\csuse{kvt@rowcount@#2}}% \expandafter\kvt@setrowcolors\expandafter{\cmdkvt@Table@rowbg}% \begingroup\edef\kvt@@do{\endgroup \expandafter\noexpand\csname #1\endcsname \ifdefvoid{\cmdkvt@Table@halign}{} {\metatblIsTabu{#1}{}{[\cmdkvt@Table@halign]}}% \metatblHasWidth{#1} {\metatblIsTabu{#1} {to \expandonce\cmdkvt@Table@width} {{\expandonce\cmdkvt@Table@width}}} {}% \ifdefvoid{\cmdkvt@Table@valign}{}{[\cmdkvt@Table@valign]}% \ifdefvoid{\cmdkvt@Table@halign}{} {\metatblIsTabu{#1}{[\cmdkvt@Table@halign]}{}}% {\csexpandonce{kvt@alignments@#2}}% \expandonce\kvt@@caption@headmain \expandonce\kvt@@prehook \metatblIsLong{#1}{% \noexpand\endfirsthead \expandonce\kvt@@caption@headalt \expandonce\kvt@@prehook \noexpand\endhead}{}% \expandonce\kvt@@caption@footmain \metatblIsLong{#1}{% \noexpand\endlastfoot \expandonce\kvt@@caption@footalt \noexpand\endfoot}{}% }\kvt@@do} \newcommand\kvt@caption@t{\caption} \newcommand\kvt@caption@b{% \noalign{\parbox{0pt}{\vskip\baselineskip}}% \caption} \newcommand\kvt@setrowcolors[1]{% \ifstrempty{#1}{}{\kvt@setrowcolors@i#1\@nil}} \def\kvt@setrowcolors@i#1..#2\@nil{% \def\kvt@@bgcolor@odd{#1}% \def\kvt@@bgcolor@even{#2}} \newcommand\kvt@userowcolors{\ifnumodd{\the\kvt@@bodyrow} {\kvt@rowcolorcmdornot{\kvt@@bgcolor@odd}} {\kvt@rowcolorcmdornot{\kvt@@bgcolor@even}}} \newcommand\kvt@RegisterBackend[1]{% \ifinlist{#1}{\kvt@@tablebackends} {\kvt@error{Backend '#1' already registered} {Internal error. Check use of \string\kvt@RegisterBackend.}} {\kvt@CheckMetatblEnv{#1}% \listadd{\kvt@@tablebackends}{#1}% \kvt@DefineStdTabEnv{#1}{#1}}} \newcommand\kvt@RegisterShape[3]{% \ifinlist{#1}{\kvt@@tableshapes} {\kvt@error{Shape '#1' already registered} {Internal error. Check use of \string\kvt@RegisterShape.}} {\kvt@CheckMetatblEnv{#2}\kvt@CheckMetatblEnv{#3}% \listadd{\kvt@@tableshapes}{#1}% \ifstrequal{#2}{#3} {\kvt@DefineStdTabEnv{#1}{#2}} {\kvt@DefineDualTabEnv{#1}{#2}{#3}}}} \newcommand\kvt@CheckMetatblEnv[1]{\metatblRegistered{#1}{} {\kvt@error{Environment '#1' not supported by keyvaltable} {Check \string\metatblRegisterEnv\space for how to make it supported.}}} \newcommand\kvt@@tablebackends{} \newcommand\kvt@@tableshapes{} \newcommand\kvt@DefineStdTabEnv[2]{% \csdef{kvt@StartTable@#1}##1{% \kvt@StartTabularlike{#2}{##1}}% \csedef{kvt@EndTable@#1}{% \expandafter\noexpand\csname end#2\endcsname}} \newcommand\kvt@DefineDualTabEnv[3]{% \expandafter\newcommand\csname kvt@StartTable@#1\endcsname[1]{% \kvt@ifhasXcolumns{##1} {\csedef{kvt@EndTable@#1}{% \expandafter\noexpand\csname end#3\endcsname}% \kvt@StartTabularlike{#3}{##1}% }{\csedef{kvt@EndTable@#1}{% \expandafter\noexpand\csname end#2\endcsname}% \kvt@StartTabularlike{#2}{##1}}}} \newcommand\kvt@ifhasXcolumns[1]{% \expandafter\expandafter\expandafter\metatbl@ifhasXcolumns \expandafter\expandafter\expandafter{% \csname kvt@alignments@#1\endcsname}} \kvt@RegisterBackend{tabular} \kvt@RegisterBackend{longtable} \kvt@RegisterBackend{tabularx} \kvt@RegisterBackend{xltabular} \kvt@RegisterBackend{tabu} \kvt@RegisterBackend{longtabu} \newcommand\kvt@AddKeyValRow[3]{% #1% \@ifnextchar[%] {\kvt@AddKeyValRow@i{#2}{#3}} {\kvt@AddKeyValRow@i{#2}{#3}[]}} \def\kvt@AddKeyValRow@i#1#2[#3]#4{% \kvt@setkeys{#3}{Row}% \ifbool{kvt@Row@hidden} {\let\kvt@@row\@empty #1} {\kvt@AddKeyValRow@ii{#1}{#2}{#4}}} \def\kvt@AddKeyValRow@ii#1#2#3{% \setkeys[KeyValTable]{#2}{#3}% \def\kvt@@row{}% \ifdefvoid\cmdkvt@Row@above{}{% \eappto\kvt@@row{\noexpand\noalign{\noexpand\vspace{% \expandonce\cmdkvt@Row@above}}}}% \appto\kvt@@row{\noalign{\global\advance\kvt@@bodyrow\@ne}}% \ifbool{kvt@Row@uncounted}{}{% \appto\kvt@@row{\noalign{\kvt@stepcounters}}}% \ifdefvoid\cmdkvt@Row@bg {\appto\kvt@@row{\kvt@userowcolors}} {\eappto\kvt@@row{\noexpand\rowcolor{\expandonce\cmdkvt@Row@bg}}}% \ifdefvoid\cmdkvt@Row@align {\let\kvt@@rowmkmulticolumn\@empty} {\edef\kvt@@rowmkmulticolumn{% \noexpand\multicolumn{1}{\expandonce\cmdkvt@Row@align}}}% \ifcsvoid{cmdkvt@Row@format!} {\edef\kvt@@cellfmtbuilder##1##2{% \noexpand\edef##1####1{% \noexpand\kvt@expandonce@onearg\noexpand\kvt@@mkmulticolumn {\ifcsvoid{cmdkvt@Row@format*}{\@firstofone} {\noexpand\unexpanded{\csexpandonce{cmdkvt@Row@format*}}}% {\noexpand\csexpandonce{##2}{% \ifdefvoid\cmdkvt@Row@format{\@firstofone} {\noexpand\unexpanded{\expandonce\cmdkvt@Row@format}}% {####1}}}}}}}% {\edef\kvt@@cellfmtbuilder##1##2{% \noexpand\edef##1####1{% \noexpand\kvt@expandonce@onearg\noexpand\kvt@@mkmulticolumn{% \noexpand\unexpanded{\csexpandonce{cmdkvt@Row@format!}}% {####1}}}}}% \kvt@@span=0\relax \kvt@def@atseconduse\kvt@@switchcol{\appto\kvt@@row{&}}% \def\do##1{% \ifnumgreater\kvt@@span{0} {\advance\kvt@@span\m@ne \ifcsvoid{cmdKeyValTable@#2@##1}{} {\ifdefvoid\kvt@@curcgname {\kvt@error{Column '##1' nonempty inside a \string\multicolumn}{}} {\kvt@error{Column '##1' nonempty inside column group '\kvt@@curcgname'}{}}}} {\kvt@@switchcol \let\kvt@@mkmulticolumn\kvt@@rowmkmulticolumn \letcs\kvt@@curcolformat{kvt@col@format@#2@##1}% \ifcsvoid{cmdKeyValTable@#2@##1} {\letcs\kvt@@cell{kvt@col@default@#2@##1}} {\letcs\kvt@@cell{cmdKeyValTable@#2@##1}% \expandafter\kvt@CheckMulticolumn\expandafter{\kvt@@cell}{#2}% \ifbool{kvt@Row@expandonce} {\expandafter\let\expandafter\kvt@@cell\kvt@@cell}{}% \ifbool{kvt@Row@expand} {\protected@edef\kvt@@cell{\kvt@@cell}}{}}% \ifcsvoid{kvt@@noformat@#2@##1} {\kvt@@cellfmtbuilder\kvt@@formatter{kvt@@curcolformat}}% {\let\kvt@@formatter\@firstofone}% \csundef{kvt@@noformat@#2@##1}% \edef\kvt@@fmtcell{\expandafter\expandonce\expandafter{% \expandafter\kvt@@formatter\expandafter{% \kvt@@cell}}}% \expandafter\appto\expandafter\kvt@@row\expandafter{% \kvt@@fmtcell}}% }\dolistcsloop{kvt@displaycols@#2}% \undef\kvt@@cellfmtbuilder \appto\kvt@@row{\tabularnewline}% \ifdefvoid\cmdkvt@Row@below{}{% \eappto\kvt@@row{\noexpand\noalign{\noexpand\vspace{% \expandonce\cmdkvt@Row@below}}}}% #1} \newcommand\kvt@def@atseconduse[2]{\def#1{\def#1{#2}}} \newcommand\kvt@expandonce@onearg[2]{% \ifdefequal{#1}{\@empty}{#2}{\expandonce{#1}{#2}}} \newcommand\kvt@stepcounters[1][1]{% \addtocounter{kvtRow}{#1}% \addtocounter{kvtTypeRow}{#1}% \addtocounter{kvtTotalRow}{#1}} \newcommand\kvt@CheckMulticolumn[2]{% \kvt@CheckMulticolumn@i{#2}#1% \relax\relax\relax\relax\relax\kvt@@undefined} \def\kvt@CheckMulticolumn@i#1#2#3#4#5#6#7\kvt@@undefined{% \ifdefmacro{#2}{% \ifx#2\multicolumn \kvt@SetMulticolumn{#4}{#3}{#5}% \let\kvt@@curcgname\@empty \else\ifx#2\kvt@@@colgroup \letcs\kvt@@curcolformat{kvt@colgrp@format@#1@#3}% \def\kvt@@curcgname{#3}% \ifdefvoid\cmdkvt@Row@align {\kvt@SetMulticolumn{#5}{#4}{#6}} {\expandafter \kvt@SetMulticolumn\expandafter{\cmdkvt@Row@align}{#4}{#6}}% \fi\fi}{}} \newcommand\kvt@@@colgroup{kvt@@@colgroup} \newcommand\kvt@SetMulticolumn[3]{% \kvt@@span=#2\relax \advance\kvt@@span\m@ne \def\kvt@@cell{#3}% \def\kvt@@mkmulticolumn{\multicolumn{#2}{#1}}} \newcommand\kvtNewRowStyle{\kvt@NewStyle{row}{\kvtRenewRowStyle}} \newcommand\kvtRenewRowStyle{\kvt@RenewStyle{row}{\kvtNewRowStyle}} \newcommand\kvtNewTableStyle{\kvt@NewStyle{table}{\kvtRenewTableStyle}} \newcommand\kvtRenewTableStyle{\kvt@RenewStyle{table}{\kvtNewTableStyle}} \newcommand\kvt@NewStyle[4]{% \ifcsundef{kvt@@#1style@#3} {\csdef{kvt@@#1style@#3}{#4}} {\kvt@error{The #1 style '#3' is already defined}{Use \string#2\space to change an existing style.}}} \newcommand\kvt@RenewStyle[4]{% \ifcsundef{kvt@@#1style@#3} {\kvt@error{A #1 style '#3' is not defined} {Use \string#2\space to define a new #1 style.}} {\csdef{kvt@@#1style@#3}{#4}}} \newcommand\kvt@UseRowStyles[1]{% \kvt@UseStyles{row}{Row}{\kvt@NewRowStyle}{#1}} \newcommand\kvt@UseTableStyles[1]{% \kvt@UseStyles{table}{Table}{\kvt@NewTableStyle}{#1}} \newcommand\kvt@UseStyle[4]{% \ifcsundef{kvt@@#1style@#4} {\kvt@error{A #1 style '#4' is not defined} {Use \string#3\space to define a new #1 style.}} {\kvt@setcskeys{kvt@@#1style@#4}{#2}}} \newcommand\kvt@UseStyles[4]{% \kvt@xkv@disablepreset[kvt]{#2}{% \forcsvlist{\kvt@UseStyle{#1}{#2}{#3}}{#4}}} \newcommand\kvt@xkv@disablepreset[3][KV]{% \ifnumgreater{\XKV@depth}{1} {#3} {\kvt@xkv@savepreset{#1}{#2}{h}% \kvt@xkv@savepreset{#1}{#2}{t}% #3% \kvt@xkv@restorepreset{#1}{#2}{h}% \kvt@xkv@restorepreset{#1}{#2}{t}}} \newcommand\kvt@xkv@savepreset[3]{% \csletcs{kvt@@saved@preset#3}{XKV@#1@#2@preset#3}% \csundef{XKV@#1@#2@preset#3}} \newcommand\kvt@xkv@restorepreset[3]{% \csletcs{XKV@#1@#2@preset#3}{kvt@@saved@preset#3}} \newcommand\NewCollectedTable[2]{% \ifcsvoid{kvt@@tnameof@#1} {\csgdef{kvt@@tnameof@#1}{#2}} {\kvt@error{Name '#1' for a row collection is already defined} {Check for other \string\NewCollectedTable{#1}.}}} \newcommand\CollectRow[3][]{% \ifcsvoid{kvt@@tnameof@#2} {\kvt@error{No row collection with name '#2' defined} {Use \string\NewCollectedTable in the preamble to define it.}} {% \begingroup \kvt@setkeys{#1}{Row}% \kvt@colsetcskeys{kvt@@tnameof@#2}{#3}% \endgroup \kvt@protected@write\@auxout{\string\kvt@RecordedRow{#1}{#2}{% \kvt@coldefaults{#2}% #3}}% }} \newcommand\kvt@protected@write[2]{\protected@write{#1} {\def\do##1{\def##1{\string##1}}% \dolistloop{\kvt@@writeprotected@cmds}% \forlistloop{\kvt@writeprotect@fmt}{\kvt@@numberformatters}} {#2}} \newcommand\kvt@writeprotect@fmt[1]{% \csletcs{kvt@@fmt@#1}{#1}% \csdef{#1}##1{% \ifcsdef{kvt@@c@##1} {\expandafter\string\csname#1\endcsname{##1}} {\csname kvt@@fmt@#1\endcsname{##1}}}} \newcommand\kvtDeclareTableMacros[1]{% \forcsvlist{\listadd\kvt@@writeprotected@cmds}{#1}} \newcommand\kvt@@writeprotected@cmds{} \newcommand\kvtDeclareTableCounters[1]{% \def\do##1{\cslet{kvt@@c@##1}\@ne}% \docsvlist{#1}} \newcommand\kvtDeclareCtrFormatters[1]{% \def\do##1{\listeadd\kvt@@numberformatters{% \expandafter\@gobble\string##1}}% \docsvlist{#1}} \newcommand\kvt@@numberformatters{} \kvtDeclareTableMacros{\thekvtRow,\thekvtTypeRow,\thekvtTotalRow} \kvtDeclareTableCounters{kvtRow,kvtTypeRow,kvtTotalRow} \kvtDeclareCtrFormatters{\arabic,\alph,\Alph,\roman,\Roman,\fnsymbol} \newcommand\kvt@coldefaults[1]{% \kvt@coldefaults@i{\csuse{kvt@@tnameof@#1}}} \newcommand\kvt@coldefaults@i[1]{% \forlistcsloop{\kvt@coldefault{#1}}{kvt@displaycols@#1}} \newcommand\kvt@coldefault[2]{\ifcsvoid{kvt@col@default@#1@#2}{}{% #2={\csuse{kvt@col@default@#1@#2}},}} \newcommand\kvt@RecordedRow[3]{% \csgappto{kvt@@rowsof@#2}{\Row[{#1}]{#3}}} \newcommand\ShowCollectedTable[2][]{% \ifcsvoid{kvt@@tnameof@#2} {\kvt@error{No row collection with name '#2' defined} {Use \string\NewCollectedTable in the preamble to define it.}} {\ifcsvoid{kvt@@rowsof@#2} {\kvt@warn{No row data available for name '#2'. A LaTeX rerun might be needed^^M for the row data to be available}% \kvt@tableofcname{#2}{#1}{???\tabularnewline}}% {\kvt@tableofcname{#2}{#1}{\csuse{kvt@@rowsof@#2}}}}} \newcommand\kvt@tableof[3]{% \begin{KeyValTable}[{#2}]{#1}% #3% \end{KeyValTable}} \newcommand\kvt@tableofcname[1]{\expandafter \kvt@tableofcname@i\expandafter{\csname kvt@@tnameof@#1\endcsname}} \newcommand\kvt@tableofcname@i[1]{\expandafter \kvt@tableof\expandafter{#1}} \newcommand\ShowKeyValTableFile[3][]{% \IfFileExists{#3} {\begin{KeyValTable}[{#1}]{#2}\@@input#3 \end{KeyValTable}}% {\kvt@error{No KeyValTable file '#3'} {Check whether the file really exists or whether there is a typo in the argument '#3'}}} \newcommand\ShowKeyValTable[2][]{% \begin{KeyValTable}[#1]{#2}% \csuse{kvt@rows@#2}% \end{KeyValTable}% \csdef{kvt@rows@#2}{}} \newcommand\AddKeyValRow[1]{% \kvt@AddKeyValRow {\begingroup} {\csxappto{kvt@rows@#1}{\expandonce{\kvt@@row}}\endgroup} {#1}} \newenvironment{KeyValTableContent}[1]{% \def\Row{\AddKeyValRow{#1}}}{}% \define@cmdkey[kvt]{PackageOptions}[kvt@@pkg@]{compat}{} \ExecuteOptionsX[kvt]{% compat=2.0, } \ProcessOptionsX[kvt]\relax \newcommand\kvt@IfVersion[2]{% \ifdimcomp{\kvt@@pkg@compat pt}{#1}{#2pt}} \kvt@IfVersion{<}{2.0}{% \metatblRequire{tabu,longtabu} \kvt@RegisterShape{onepage}{tabu}{tabu} \kvt@RegisterShape{multipage}{longtabu}{longtabu} }{% \metatblRequire{tabularx,longtable,xltabular} \kvt@RegisterShape{onepage}{tabular}{tabularx} \kvt@RegisterShape{multipage}{longtable}{xltabular} } \kvt@IfVersion{<}{2.0}{% \renewcommand\kvt@parselayout[2]{\kvt@parseheadrows{#2}{#1}}% }{} \endinput %% %% End of file `keyvaltable.sty'.