Incompatibility with `colortbl` package breaks `table-number-alignment` of siunitx columns
MWE:
\documentclass{scrbook}
\usepackage{colortbl}
\usepackage{tabularray}
\UseTblrLibrary{siunitx}
\begin{document}
\begin{table}
\begin{tblr}{
|
X[si={table-alignment-mode=format,table-number-alignment=right}]
|
X[si={table-alignment-mode=format,table-number-alignment=center}]
|
X[si={table-alignment-mode=format,table-number-alignment=left}]
|
}
1.1 & 2.2 & 3.3 \\
\end{tblr}
\caption{Foo}
\end{table}
\end{document}
Unless you disable \usepackage{colortbl}, all columns will be incorrectly left-aligned. Other alignment options such as c seem to work. Package loading order does not matter.
I have not found a prior report of this issue. For practical relevance, I use a documentclass that does \usepackage[table]{xcolor} and this breaks my table alignment (https://github.com/krono/swathesis/issues/64). A workaround is available (not loading colortbl), so I'm just reporting this for others.
PS: Thanks for this awesome package!
It seems it's caused by the special alignment code in siunitx, when colortbl is loaded. Such special treatment is for uses in traditional tables which are affected by array package. But unfortunately, interferes with the default column alignment halign=j (justify) in tabularray.
Following example is an attempt to cancel that special treatment for tabularray tables. The third table in it also shows that you can always use l/c/r options to alter/overwrite the column alignment.
\documentclass{article}
\usepackage{colortbl}
\usepackage{tabularray}
\UseTblrLibrary{siunitx}
\ExplSyntaxOn
\makeatletter
\cs_undefine:N \__tblr_siunitx_process:Nn
\cs_new_protected:Npn \__tblr_siunitx_process:Nn #1 #2
{
\__tblr_siunitx_restore_align: % <<< added
\tl_if_head_is_group:nTF {#2}
{ #2 }
{
\group_begin:
\tl_set:Nx \l_tmpa_tl
{
\__tblr_data_item:neen { cell }
{ \int_use:N \c@rownum } { \int_use:N \c@colnum } { si }
}
\exp_args:NV \sisetup \l_tmpa_tl
#1 {#2}
\group_end:
}
}
\hook_gput_code:nnn {begindocument} {tabularray}
{
\@ifpackageloaded { colortbl }
{
% quite fragile
% see https://github.com/josephwright/siunitx/blob/2bf3bd790e58894d8de2cafcc1f8f0da9eb2af19/siunitx-table.dtx#L673-L688
\cs_new_protected:Npn \__tblr_siunitx_restore_align:
{ \cs_set_eq:NN \__siunitx_table_align_auxi:nn \__siunitx_table_align_auxii:nn }
}
{
\cs_new_eq:NN \__tblr_siunitx_restore_align: \prg_do_nothing:
}
}
\makeatother
\ExplSyntaxOff
\begin{document}
\parindent=-\parindent
tabular, \verb|S[...]| \\
\begin{tabular}{
|S[table-alignment-mode=format,table-number-alignment=right]
|S[table-alignment-mode=format,table-number-alignment=center]
|S[table-alignment-mode=format,table-number-alignment=right]
|
}
{Some values} & {Some values} & {Some values} \\
1.1 & 2.2 & 3.3 \\
11.1 & 22.2 & 33.3
\end{tabular}
tblr \verb|S[...]|, \verb|halign=c| applied \\
\begin{tblr}{
|S[table-alignment-mode=format,table-number-alignment=right]
|S[table-alignment-mode=format,table-number-alignment=center]
|S[table-alignment-mode=format,table-number-alignment=left]
|
}
{{{Some values}}} & {{{Some values}}} & {{{Some values}}} \\
1.1 & 2.2 & 3.3 \\
11.1 & 22.2 & 33.3
\end{tblr}
tblr, \verb|X[<halign>, si={...}]| \\
\begin{tblr}{
|X[r,si={table-alignment-mode=format,table-number-alignment=right}]
|X[c,si={table-alignment-mode=format,table-number-alignment=center}]
|X[l,si={table-alignment-mode=format,table-number-alignment=left}]
|
}
1.1 & 2.2 & 3.3 \\
11.1 & 22.2 & 33.3
\end{tblr}
tblr, \verb|X[si={...}]| \\
\begin{tblr}{
|X[si={table-alignment-mode=format,table-number-alignment=right}]
|X[si={table-alignment-mode=format,table-number-alignment=center}]
|X[si={table-alignment-mode=format,table-number-alignment=left}]
|
}
1.1 & 2.2 & 3.3 \\
11.1 & 22.2 & 33.3
\end{tblr}
\end{document}
This needs to be fixed in siunitx, since we must not patch private macros in siunitx.
@lvjr Is there a marker I can pick up to know we are in a tblr column not a standard array one?
@josephwright How about checking \g_tblr_level_int (a public integer for the nesting level of tabularray tables)?
I have a fix in hand - I'll patch in the next release (probably next week).
Would checking nesting level (\g_tblr_level_int) fail in rare cases, for example when an array using S column is nested in tblr? Maybe need some words in doc.
Would checking nesting level (
\g_tblr_level_int) fail in rare cases, for example when anarrayusingScolumn is nested intblr? Maybe need some words in doc.
There's a reason I asked if I can pick up being in a tblr cell :)
@lvjr I can't add a test at the moment in siunitx as tabularray has loads of failures when running expl3 debugging :(
@josephwright The dev version of tabularray.sty should work with \debug_on:n { check-declarations }, see ecafbe9cf87bdd7c727607a40516ad061f5a4e33 and #22.
But \debug_on:n { deprecation } will keep raising errors since Jianrui (lvjr) decided to support the most-recent four TeX Live releases, see 77ca1bc7393f6ca1ec9846381acb76ef3b91ae5c.
@muzimuzhi Thanks - I might have to test without deprecation checking for this case then - should be safe enough in this one case.
Would checking nesting level (
\g_tblr_level_int) fail in rare cases, for example when anarrayusingScolumn is nested intblr? Maybe need some words in doc.There's a reason I asked if I can pick up being in a
tblrcell :)
But a tblr cell could have an array in it. I can't see what is the difference.
@lvjr That's why I was asking about a marker - I wondered if there was flag that was on in a cell but turned off for nested tabulars - I take it 'no'
That's why I was asking about a marker - I wondered if there was flag that was on in a cell but turned off for nested tabulars - I take it 'no'
For nested tabular/array environments, I guess we can check \@currenvir.
Ideally, tabularray can provide something for siunitx like
\prg_new_conditional:Npnn \tblr_if_si_cell: { p, T, F, TF }
{
\bool_lazy_and:nnTF
{ \l__tblr_if_si_column_bool } % need to be set true by "si" column type
{ \tblr_if_tblr_env_p: }
{ \prg_return_true: }
{ \prg_return_false: }
}
\prg_new_conditional:Npnn \tblr_if_tblr_env: { p, T, F, TF }
{
\tl_if_exist:cT { l__tblr_default_ \@currenvir _inner_tl }
}
Alternatively, siunitx can provide a new option that the si column type will always set.
Alternatively,
siunitxcan provide a new option that thesicolumn type will always set.
After reading again your workaround code above, I believe this is the most reliable solution: siunitx adds a new option such as disable-colortbl-fix and tabularray applies \sisetup{disable-colortbl-fix} in its S cells.