# Keyword command parameters with table (tabular)

I am trying to make a command with named (key-value) parameters to produce a table row. The reason is that table has more than 9 columns (command parameters) that will have position changed, be deleted or added. So it is hard to keep it with regular command (both because positions and limited number of args).

I tried to make it work with xkeyval package, but something gets broken inside table. Here is MWE:

\documentclass{article}
\usepackage{xkeyval}
\begin{document}

\makeatletter
\define@key{myrowkey}{name}{\def\MyRowName{#1}}
\define@key{myrowkey}{num}{\def\MyRowNum{#1}}
\makeatother

\newcommand\myrow[1]{
\setkeys{myrowkey}{#1}
\MyRowName, \MyRowNum & \\ \hline
}

\newcommand\myrowb[1]{
\setkeys{myrowkey}{#1}
\MyRowName & \MyRowNum \\ \hline
}

\begin{table}
\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrow{name=Abc,num=2000}
\myrow{name=Def,num=2000}
\end{tabular}
\end{table}

\end{document}



-

The definitions are made within the first cell of the tabular and don't survive to the next cell. You need to make their definitions global so they can span multiple columns. If you change \def to \gdef in the key definitions it will work.

\documentclass{article}
\usepackage{xkeyval}% http://ctan.org/pkg/xkeyval
\begin{document}

\makeatletter
\define@key{myrowkey}{name}{\gdef\MyRowName{#1}}
\define@key{myrowkey}{num}{\gdef\MyRowNum{#1}}
\makeatother

\newcommand\myrow[1]{%
\setkeys{myrowkey}{#1}%
\MyRowName, \MyRowNum & \\ \hline
}

\newcommand\myrowb[1]{%
\setkeys{myrowkey}{#1}%
\MyRowName & \MyRowNum \\ \hline
}

\begin{table}
\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrowb{name=Abc,num=2000}
\myrow{name=Def,num=2000}
\end{tabular}
\end{table}

\end{document}


Note the use of % to avoid spurious spaces in your definitions of \myrow and \myrowb. See What is the use of percent signs (%) at the end of lines?

-
Wow, that was simple :P Thnx! –  Ivan Sep 19 '13 at 17:47
@Ivan: Note that this solution will copy elements from one row to the next if it is not specified in the keys. You could add the defaults to the \setkeys command within \myrowb: \setkeys{name={},num={},#1}. –  Werner Sep 19 '13 at 18:01
Yes, I am aware of that. In my full version I have keyreset command for this. –  Ivan Sep 20 '13 at 8:50

Without \gdef; this has the advantage that if you need to omit some entry, you just don't set the key (provided you set up at the beginning an empty value for each key).

\documentclass{article}
\usepackage{xkeyval}

\makeatletter
\define@key{myrowkey}{name}{\def\MyRowName{#1}}
\define@key{myrowkey}{num}{\def\MyRowNum{#1}}

\newcommand\myrow[1]{%
\setkeys{myrowkey}{#1}%
\begingroup\protected@edef\x{\endgroup
\MyRowName, \MyRowNum &
}\x \\ \hline
}

\newcommand\myrowb[1]{%
\setkeys{myrowkey}{#1}%
\begingroup\protected@edef\x{\endgroup
\MyRowName & \MyRowNum
}\x \\ \hline
}
\makeatother

\begin{document}

\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrow{name=Abc,num=2000}
\myrow{name=Def,num=2000}
\end{tabular}

\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrowb{name=Abc,num=2000}
\myrowb{name=Def,num=2000}
\end{tabular}

\end{document}


The idea is to expand the key values before TeX “sees” the &.

The same idea implemented in LaTeX3

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\tl_new:N \l_ivan_row_name_tl
\tl_new:N \l_ivan_row_num_tl
\keys_define:nn { ivan/tab }
{
name .code:n    = { \tl_set:Nn \l_ivan_row_name_tl { \exp_not:n { #1 } } },
name .initial:n = {},
num  .code:n    = { \tl_set:Nn \l_ivan_row_num_tl { \exp_not:n { #1 } } },
num  .initial:n = {}
}

\NewDocumentCommand\myrow{m}
{
\keys_set:nn { ivan/tab } { #1 }
\use:x
{
\l_ivan_row_name_tl,~\l_ivan_row_num_tl
&
}
\\ \hline
}

\NewDocumentCommand\myrowb{m}
{
\keys_set:nn { ivan/tab } { #1 }
\use:x
{
\l_ivan_row_name_tl & \l_ivan_row_num_tl
}
\\ \hline
}
\ExplSyntaxOff

\begin{document}

\begin{tabular}{|c|c|}\hline
A & B \\ \hline
\myrow{name=Abc,num=2000}
\myrowb{name=\textbf{X}} % no num
\myrowb{name=Def,num=1}
\end{tabular}

\end{document}


As you see, not giving a value will leave the entry empty. Adding keys is made with the same scheme.

-
Could you please elaborate what do you mean (and how this code achieves it) by "expanding values before TeX sees the '&'". (I roughly understand what happens in my example, but I am not sure that I understand how you circumvent it.) –  Ivan Sep 20 '13 at 8:54