3

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.

4

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}

enter image description here

  • 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

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.