6

I am trying to define a command for tabular entries using keyval.

\documentclass{article}

\usepackage{keyval}

\makeatletter
\define@key{tabularEntryKeys}{a}[\dots]{#1 & }
\define@key{tabularEntryKeys}{b}[\dots]{#1   }
\makeatother

\newcommand{\tabularEntry}[1]{\setkeys{tabularEntryKeys}{#1}}

\begin{document}

\begin{tabular}{c|c}\hline
  \tabularEntry{a=1,b=2} % shall be "1 & 2"
\end{tabular}

\end{document}

However it does not compile. Any suggestions?

3

Here is one more approach. It does neither global definitions nor use of e-TeX extensions and \edef.

tabularkeys

\documentclass{article}

\usepackage{keyval}
\def\TAB{&}

\makeatletter
\define@key{tabularEntryKeys}{a}[\dots]{\def\tek@rowA{#1}}
\define@key{tabularEntryKeys}{b}[\dots]{\def\tek@rowB{#1}}
% initialize
\def\tek@rowA{}
\def\tek@rowB{}

\newcommand{\tabularEntry}[1]{\setkeys{tabularEntryKeys}{#1}%
                              \tek@rowA \expandafter\TAB\tek@rowB }
\makeatother

\begin{document}

\begin{tabular}{c|c}
\hline
  \tabularEntry{a=1,b=2} \\
  \tabularEntry{a=1} \\
  \tabularEntry{b=2} \\
  \tabularEntry{a,b} \\
  \tabularEntry{a} \\
  \tabularEntry{b} \\
  \tabularEntry{} \\
\end{tabular}
% \begin{tabular}{c|c}\hline
%   \tabularEntry{a=1,b=2}\\
%   \tabularEntry{a=3,b=7}\\
%   \tabularEntry{a=10,b=20}
% \end{tabular}

\end{document}

In case of more cells in one row, one needs a variant to avoid many many \expandafter's: (notice the extra spaces added before #1 and in the initial defaults values except for \tek@rowA and \tekrowD)

\usepackage{keyval}
\def\TAB{&}
\makeatletter
\define@key{tabularEntryKeys}{a}[\dots]{\def\tek@rowA{#1}}
\define@key{tabularEntryKeys}{b}[\dots]{\def\tek@rowB{ #1}}
\define@key{tabularEntryKeys}{c}[\dots]{\def\tek@rowC{ #1}}
\define@key{tabularEntryKeys}{d}[\dots]{\def\tek@rowD{#1}}
% initialize
\def\tek@rowA{}
\def\tek@rowB{ }
\def\tek@rowC{ }
\def\tek@rowD{}

\newcommand{\tabularEntry}[1]{\setkeys{tabularEntryKeys}{#1}%
     \tek@rowA \expandafter\TAB
     \romannumeral0\expandafter\tek@rowB\expandafter\TAB
     \romannumeral0\expandafter\tek@rowC\expandafter\TAB
     \tek@rowD 
}
\makeatother
  • If you use something like -`Q instead of 0 you won't need the extra spaces. – egreg May 24 '14 at 19:16
  • @egreg no sorry, this wouldn't work: first I would still need to leave the spaces in the initial default values; second b=\empty would create an error. In both cases the cause of the error is premature expansion of \TAB. – user4686 May 24 '14 at 21:46
  • @egreg but thanks for the input. I do use \romannumeral-`0 at some places in xint, for example in things \romannumeral-`0#1\relax. – user4686 May 24 '14 at 22:02
4

Here is how it works:

\documentclass{article}

\usepackage{keyval}    

\makeatletter
\define@key{tabularEntryKeys}{a}[\dots]{\gdef\A{#1}}
\define@key{tabularEntryKeys}{b}[\dots]{\gdef\B{#1}}
\makeatother

\newcommand\tabularEntry[1]{\setkeys{tabularEntryKeys}{#1} \A & \B}

\begin{document}

\begin{tabular}{c|c}\hline
    \tabularEntry{a=1,b=2}
\end{tabular}

\end{document}
  • 1
    moreover \tabularEntry {b=2,a=1} will also work in this approach, whereas the OP's code could not, even if the scope closing nature of & in a tabular was avoided. – user4686 May 24 '14 at 15:05
  • Sorry, no, but this is wrong under many respects. For instance, if you specify a new row as \tabularEntry{b=3}, the previous value given to a will appear. – egreg May 24 '14 at 16:00
  • @egreg, in this case it's not a bug, it's a feature. a is repeating several times. – sergej May 24 '14 at 16:18
  • @sergej This doesn't appear in your question. – egreg May 24 '14 at 16:25
2

Your \setkeys command can't straddle two cells. On the other hand globally defining \A and \B doesn't seem a good idea.

\documentclass{article}

\usepackage{keyval,etoolbox}    

\makeatletter
\define@key{tabularEntryKeys}{a}[\dots]{\def\tek@rowA{\unexpanded{#1}}}
\define@key{tabularEntryKeys}{b}[\dots]{\def\tek@rowB{\unexpanded{#1}}}
% initialize
\def\tek@rowA{}
\def\tek@rowB{}
\newcommand\tabularEntry[1]{%
  \setkeys{tabularEntryKeys}{#1}%
  \edef\tek@row{\tek@rowA & \tek@rowB}\tek@row
}
\makeatother

\begin{document}

\begin{tabular}{c|c}
\hline
  \tabularEntry{a=1,b=2} \\
  \tabularEntry{a=1} \\
  \tabularEntry{b=2} \\
  \tabularEntry{a,b} \\
  \tabularEntry{a} \\
  \tabularEntry{b} \\
  \tabularEntry{} \\
\end{tabular}

\end{document}

Note that the optional argument in \define@key is the value assigned to the key when the key is specified without =<value> following, not an initial value.

enter image description here

If you want the values to repeat if a key is not specified, then say

\define@key{tabularEntryKeys}{a}[\dots]{\gdef\tek@rowA{\unexpanded{#1}}}
\define@key{tabularEntryKeys}{b}[\dots]{\gdef\tek@rowB{\unexpanded{#1}}}

but don't use “easy” macro names such as \A or \B.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.