17

I'm using the tabular features of siunitx (for what it is worth: v1.3 since I'm on TexLive 2009) to align numbers in tables, eg.

\begin{tabular}{ p{1.5cm} S S S }
bla & 1.23 & 4.5 & 67.89 \tabularnewline
\end{tabular}

and that works perfectly fine.

Now I would like to have this table span a specific width, or rather to have several tables to have the same width. For this I would normally use tabularx

\begin{tabularx}{\textwidth}{ p{1.5cm} X X X }
bla & 1.23 & 4.5 & 67.89 \tabularnewline
\end{tabular}

Now, is there a way to combine the two? To have the number formatting and alignment features of siunitx inside an automatically resizing table?

8
  • 2
    The X column in tabularx is then converted to p{<width>} where width is automatically calculated. You can change this by redefining the \tabularxcolumn macro like described in the package manual: \renewcommand{\tabularxcolumn}[1]{...}. I'm sure Joseph Wright (author of siunitx and moderator here) can tell you what to put for .... I'm couldn't find it out for myself yet. (My LaTeX3-fu is still very weak) Commented Mar 4, 2011 at 14:29
  • 7
    There is a feature request for fixed-width columns for siunitx, which I plan to do for version 2.2 (aiming to work on it next month).
    – Joseph Wright
    Commented Mar 4, 2011 at 14:47
  • @Joseph: Could you have a look on the solution I came up with now. It seems to work, but I'm not very good in understanding LaTeX3 code. Commented Mar 4, 2011 at 14:52
  • @Martin: Usually I'd ask people to 'keep away' from siunitx internals - they are not documented and so are liable to arbitrary changes! Your solution is quite nice, with the only thing I'd say being to use \ExplSyntax(On|Off) rather than the 'raw' \catcode approach you've taken. In siunitx, I can't just use a 'p' column as I don't know what options are set when the column is defined - I have to wait until I'm inside the cell!
    – Joseph Wright
    Commented Mar 13, 2011 at 12:18
  • @JosephWright In the current manual (2020/02/25), I cannot find any reference to tabularx. Because some time has passed since your comment, I want to ask, whether by now there is a built in possibility to use the S cells, but get a similar behaviour as with X cells.
    – Sam
    Commented Oct 21, 2020 at 12:16

5 Answers 5

15

The X column in tabularx is then converted to p{<width>} where width is automatically calculated. You can change this by redefining the \tabularxcolumn macro like described in the package manual:

\renewcommand{\tabularxcolumn}[1]{<column definition where #1 is the width>}

The S column uses the c column internally. To replace this with p{<width>} you have to manually place the internal column definition of S into \tabularxcolumn. The following code worked in my tests.

\documentclass{article}

\usepackage{array}
\usepackage{tabularx}
\usepackage{siunitx}


\begingroup
% Allow `_` and `:` in macro names (LaTeX3 style)
\catcode`\_=11
\catcode`\:=11
% Internal code of `S`
\gdef\tabularxcolumn#1{%
    >{\__siunitx_table_collect_begin:Nn S{} }%
    p{#1}%  <- this is different (is `c` in normal `S`)
    <{\__siunitx_table_print:}%
}
\endgroup

\begin{document}

\begin{tabularx}{\textwidth}{p{1.5cm} XXX}
     bla & 1.23 & 4.5  & 67.89 \\
     bla & 1.2  & 4.50 &  7.89 \\
     bla &  .2  &  .50 & 67.8 \\
\end{tabularx}
\end{document}
11
  • 1
    This seems to work. However only with version 2.x of siunitx, not with 1.x due to substantial differences in the syntax.
    – janitor048
    Commented Mar 4, 2011 at 17:00
  • @janitor048: Yes, such "patches" are always version dependent. I don't have siunitx 1.x right now here, so I can't tell you the right code for it, but the principle should be the same. Commented Mar 4, 2011 at 17:31
  • Yeah sure. I mainly wanted to mentioned it for other readers.. I tried to modify your solution for version 1 but the package looks very different from version 2 and I couldn't really find my way through the code. But then, I'm not really familiar with the inner structure of latex packages anyways.
    – janitor048
    Commented Mar 4, 2011 at 18:12
  • 1
    @janitor048: I've added a v1 answer using the same approach.
    – Joseph Wright
    Commented Mar 13, 2011 at 12:24
  • 1
    @Sumit: "doesn't work" doesn't work for me. What is the exact issue? Do you get a compiler error or is the result different of what you expect? Commented May 31, 2014 at 19:28
8

Taking Martin's solution and re-coding for version 1 of siunitx, you'd do something like

\documentclass{article}

\usepackage{siunitx,tabularx}

\makeatletter
\def\tabularxcolumn#1{%
    >{\si@tab@begin@S[]}%
    p{#1}%  <- this is different (is `c` in normal `S`)
    <{\si@tab@end@S}%
}
\makeatother

\begin{document}

\begin{tabularx}{\textwidth}{p{1.5cm} XXX}
     bla & 1.23 & 4.5  & 67.89 \\
     bla & 1.2  & 4.50 &  7.89 \\
     bla &  .2  &  .50 & 67.8 \\
\end{tabularx}
\end{document}
1
  • Yes, that works. Thank you very much! I'll mark Martin's reply as accepted answer though, because it relates to the more recent version of your package. Hope that's fine with you.
    – janitor048
    Commented Mar 16, 2011 at 11:50
3

The quite new tabu package seems to be very encouraging. Section 1.5 of its manual introduces explicitly an example for how to embed siunitx's »S« columns in »X« columns. Regarding tables this package seems to be an allrounder.

3
  • Sounds interesting. I'll have a look at it.. Thanks for the suggestion!
    – janitor048
    Commented Mar 16, 2011 at 11:51
  • 1
    Package is buggy, not compatible with new versions of array (on which is based) and not maintained. Its use is not recommended anymore.
    – Zarko
    Commented May 19, 2021 at 7:04
  • Things change in a decade... It was good while it lasted though
    – ScumCoder
    Commented Nov 27, 2023 at 13:42
2

Here's a variant of @DavidCarlisle's answer for siunitx version 3:

\documentclass{article}
% \usepackage{array}
\usepackage{tabularx}
\usepackage{siunitx}

\begingroup
% Allow `_` and `:` in macro names (LaTeX3 style)
\catcode`\_=11
\catcode`\:=11
\gdef\tabularxcolumn#1{%
    >{\mode_leave_vertical: \siunitx_cell_begin:w \centering}%
    p{#1}%
    <{\siunitx_cell_end:}%
}
\endgroup

\begin{document}
\noindent
\begin{tabularx}{\textwidth}{p{1.5cm}XXX}
     bla & 1.23 & 4.5  & 67.89 \\
     bla & 1.2  & 4.50 &  7.89 \\
     bla &  .2  &  .50 & 67.8 \\
\end{tabularx}
\end{document}

Also check https://github.com/josephwright/siunitx/issues/423 for improved versions - I removed \ignorespaces to make it compile with \color{red} 4.50, but alignment of colored cells is still off.

1

No more need to complex hacking, use tabularray package!

With tabularry you can have columns that are at the same time X type (option co=<n>, n is the coefficient for the extendable column, usually 1, but you can use 2 to have a column with double width, etc.) and S type (option si=<settings>).

You don't even have to worry about having non-numeric fields in the S columns, using option guard where needed.

In the following example, I created a new column type A that is both X and S and has the table-format as a parameter. Still, you can also use a Q column directly, specifying all the parameters.

\documentclass[draft]{article}

\usepackage{tabularray}
\UseTblrLibrary{siunitx}
\sisetup{group-digits=false}
\NewColumnType{A}[1][2.2]{Q[si={table-format=#1},c,co=1]}

\usepackage{caption}

\begin{document}
With \texttt{tabularry} you can have columns that are at the same time \texttt{X} type (option \texttt{co=<n>}, where \texttt{n} is the coefficient for the extendable column, usually 1, but you can use 2 to have a column with double width, etc.) and \texttt{S} type (option \texttt{si=<settings>}).

You don't even have to worry about having non-numeric fields in the \texttt{S} columns, using option \texttt{guard} where needed.

\begin{table}[h]
\caption{A table with columns that are X and \texttt
{siunitx} at the same time}
\begin{tblr}{
    colspec={Q[1.5cm]Q[si={table-format=1.2},c,co=1]A[1.1]A},
    row{1}={guard}
    }
    Head 1 & Head 2 & Head 3 & Head 4\\
    bla & 1.23 & 4.5 & 67.89\\
    bla & 1.23 & 4.5 & 67.89\\
    bla & 1.23 & 4.5 & 67.89\\
\end{tblr}
\end{table}
\begin{table}[h]
\caption{A table with vertical lines to show the dimension of the columns}
\begin{tblr}{
    colspec={Q[1.5cm]*2{A[1.2]}A},
    row{1}={guard},
    vlines
    }
    Head 1 & Head 2 & Head 3 & Head 4\\
    bla & 1.23 & 4.5  & 67.89 \\
    bla & 1.2  & 4.50 &  7.89 \\
    bla &  .2  &  .50 & 67.8 \\
\end{tblr}
\end{table}
\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .