# Using siunitx S columns with keyval macro-expanded entries

I have the following table that compiles with regular 'c' columns, but doesn't work with an S-column. Is there a way to format the following table using alignment features in the siunitx package?

\documentclass{article}

\usepackage{xkeyval}
\usepackage{siunitx}

\makeatletter
\define@key{results}{a}{\gdef\a{#1}}
\define@key{results}{b}{\gdef\b{#1}}
\define@key{results}{c}{\gdef\c{#1}}

\newcommand{\row}[1]{\setkeys{results}{#1}\a & \b & \c}

\begin{document}

\begin{center}
\begin{tabular}{ccc}%     % doesn't work as an S column
\row{a=1.112,b=4.5,c=5.6}\\
\row{a=3.2,b=6.134,c=-5.6}\\
\end{tabular}
\end{center}

\end{document}


I've looked into the siunitx documentation (specifically Section 7.2 ("Expanding content in tables"), but haven't been very successful in implementing any of their suggestions.

It seems like I should want the \row{...} command to be expanded before being aligned with the S column, but I am not even sure if that is the right question to be asking

As an aside, I would like to use keyval arguments mainly because I would like to be able to pass more than 9 arguments to a "row" command. I won't likely use all input values, but want flexibility in which ones I choose to use and how I use them. Also, I like the idea of formatting data using named macros \a & \b & \c rather than #1 & #2 & #3, as it seems that this reduces the chances of making errors when creating table entries.

I would not use xkeyval for this, but expl3.

The main problem is with the first column: if you want to set the keys, the first column cannot be S; a trick is to use a “phantom” column.

I added a \rowformat command to set the order of the keys. In the image, the second table is the same as the first one.

\documentclass{article}
\usepackage{xparse,siunitx}

\ExplSyntaxOn
\NewDocumentCommand{\rowformat}{m}
{
\seq_clear:N \l__donna_table_rowformat_seq
\clist_map_inline:nn { #1 }
{
\seq_put_right:Nn \l__donna_table_rowformat_seq
{ \prop_item:Nn \l__donna_table_row_prop { ##1 } }
}
\cs_set_protected:Nx \__donna_row:
{
\exp_not:n { \tl_set:Nx \l__donna_table_row_tl }
{ & \seq_use:Nn \l__donna_table_rowformat_seq { & } }
}
}
\NewDocumentCommand{\row}{m}
{
\prop_clear:N \l__donna_table_row_prop
\keys_set:nn { donna/table } { #1 }
\__donna_row:
\tl_use:N \l__donna_table_row_tl
}
\prop_new:N \l__donna_table_row_prop
\seq_new:N \l__donna_table_rowformat_seq
\tl_new:N \g__donna_table_row_tl

\keys_define:nn { donna/table }
{
unknown .code:n = \prop_put:NVn \l__donna_table_row_prop \l_keys_key_tl { #1 },
}
\cs_generate_variant:Nn \prop_put:Nnn { NV }
\ExplSyntaxOff

\begin{document}

\rowformat{a,b,c}

\begin{tabular}{
c@{} % the phantom column
S[table-format=1.3]
S[table-format=1.3]
S[table-format=-1.1]
}
\row{a=1.112,b=4.5,c=5.6}\\
\row{a=3.2,b=6.134,c=-5.6}\\
\end{tabular}

\begin{tabular}{
S[table-format=1.3]
S[table-format=1.3]
S[table-format=-1.1]
}
1.112 & 4.5 & 5.6 \\
3.2 & 6.134 & -5.6\\
\end{tabular}

\rowformat{a,c,b}
\begin{tabular}{
c@{}
S[table-format=1.3]
S[table-format=-1.1]
S[table-format=1.3]
}
\row{a=1.112,b=4.5,c=5.6}\\
\row{a=3.2,b=6.134,c=-5.6}\\
\end{tabular}

\end{document}


• Thanks for the tip on adding the phantom column, i.e. the following fix seems to work \tabular{c@{}SSS}} seems to be the only change that I needed to get my code to compile. – Donna Aug 20 '16 at 11:52
• But I'll be honest - I am unfamiliar with the Expl syntax - is this a programming language in Latex? Why do you prefer it over what I did? – Donna Aug 20 '16 at 11:57
• I just noticed that the phantom column trick seems to prevent the first column from formatting correctly. That is, the numbers are not aligned on the decimal. – Donna Aug 20 '16 at 12:32
• Edit to first comment : I also need to add an & after the setkeys command in my \row macro. – Donna Aug 20 '16 at 13:00
• @Donna Yes, I added one & too. The advantage of my approach is that you can define the keys on the fly in the \rowformat command. – egreg Aug 20 '16 at 17:47