lvjr / tabularray

Typeset tabulars and arrays with LaTeX3
https://ctan.org/pkg/tabularray
247 stars 22 forks source link

Expansion problem with border text #303

Open lvjr opened 1 year ago

lvjr commented 1 year ago

From https://tex.stackexchange.com/questions/648880/settblrinnertblrcells-bg-cant-change-the-background-color-in-tabularr

\documentclass{article}
\usepackage{tabularray,xcolor}
\begin{document}
\colorbox{teal8}{.}
\begin{tblr}{r@{\colorbox{teal8}{.}}l}
  11 & 11 \\
   5 & 1  \\
   6 & 78 \\
  75 & 5  \\
\end{tblr}
\end{document}

The above code produces the following error:

! Use of \@undeclaredcolor doesn't match its definition.
\@ifnextchar ...eserved@d =#1\def \reserved@a {#2}
                                                  \def \reserved@b {#3}\futu...
l.12 \end
         {tblr}
muzimuzhi commented 3 months ago

Also raised in

Row/Column type @ is implemented using text row/column option, so they indeed reported the same bug. https://github.com/lvjr/tabularray/blob/9f5b008556c6feea2c39b005cacd7f3a1da76f1c/tabularray.sty#L2543

muzimuzhi commented 3 months ago

Currently (version 2024A) the value passed to text column option is first stored in \l__tblr_vline_dash_tl with prefix \exp_not:N \@tblr@text, then that tl is fully expanded by \__tblr_spec_gput:nee used in \__tblr_set_vline_cmd:n (see lines 1589 to 1591 in second snippet below). If the passed text value is not fully expandable, error is raised.

https://github.com/lvjr/tabularray/blob/9f5b008556c6feea2c39b005cacd7f3a1da76f1c/tabularray.sty#L1559-L1560 https://github.com/lvjr/tabularray/blob/9f5b008556c6feea2c39b005cacd7f3a1da76f1c/tabularray.sty#L1569-L1581

Value passed to text row option is treated similarly, stored in \l__tblr_hline_dash_tl with prefix and fully expanded by \__tblr_spec_gput:nee used in \__tblr_set_hline_option:nnn, which is used in \__tblr_set_hline_cmd:n.

Code snippets for text row option

https://github.com/lvjr/tabularray/blob/9f5b008556c6feea2c39b005cacd7f3a1da76f1c/tabularray.sty#L1317-L1318 https://github.com/lvjr/tabularray/blob/9f5b008556c6feea2c39b005cacd7f3a1da76f1c/tabularray.sty#L1349-L1354 https://github.com/lvjr/tabularray/blob/9f5b008556c6feea2c39b005cacd7f3a1da76f1c/tabularray.sty#L1400-L1405

One solution is to store \exp_not:N \@tblr@text \exp_not:n {<text value>} in \l__tblr_(h|v)line_dash_tl.

Git patch

```diff From 9ae91b77b66374606bb920e224496dc3c32c56d1 Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Wed, 20 Mar 2024 07:47:52 +0800 Subject: [PATCH] Prevent expansion of h/vline text with \exp_not:n --- tabularray.sty | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tabularray.sty b/tabularray.sty index 027563f..33b9c42 100644 --- a/tabularray.sty +++ b/tabularray.sty @@ -1238,7 +1238,7 @@ { \group_begin: \keys_set_groups:nnn { tblr-hline } { text } {#3} - \tl_if_eq:NnF \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text } + \tl_if_eq:NnF \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text \exp_not:n {} } { \__tblr_set_hline_num:n {#1} \tl_clear:N \l__tblr_hline_dash_tl @@ -1315,7 +1315,11 @@ \keys_define:nn { tblr-hline } { dash .code:n = \tl_set:Nn \l__tblr_hline_dash_tl { \exp_not:N \@tblr@dash #1 }, - text .code:n = \tl_set:Nn \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text #1 }, + text .code:n = + { + \tl_set:Nn \l__tblr_hline_dash_tl + { \exp_not:N \@tblr@text \exp_not:n {#1} } + }, text .groups:n = { text }, wd .code:n = \tl_set:Nn \l__tblr_hline_wd_tl { \dim_eval:n {#1} }, fg .code:n = \tl_set:Nn \l__tblr_hline_fg_tl {#1}, @@ -1480,7 +1484,7 @@ { \group_begin: \keys_set_groups:nnn { tblr-vline } { text } {#3} - \tl_if_eq:NnF \l__tblr_vline_dash_tl { \exp_not:N \@tblr@text } + \tl_if_eq:NnF \l__tblr_vline_dash_tl { \exp_not:N \@tblr@text \exp_not:n {} } { \__tblr_set_vline_num:n {#1} \tl_clear:N \l__tblr_vline_dash_tl @@ -1557,7 +1561,11 @@ \keys_define:nn { tblr-vline } { dash .code:n = \tl_set:Nn \l__tblr_vline_dash_tl { \exp_not:N \@tblr@dash #1 }, - text .code:n = \tl_set:Nn \l__tblr_vline_dash_tl { \exp_not:N \@tblr@text #1 }, + text .code:n = + { + \tl_set:Nn \l__tblr_vline_dash_tl + { \exp_not:N \@tblr@text \exp_not:n {#1} } + }, text .groups:n = { text }, wd .code:n = \tl_set:Nn \l__tblr_vline_wd_tl { \dim_eval:n {#1} }, fg .code:n = \tl_set:Nn \l__tblr_vline_fg_tl {#1}, -- 2.44.0 ```

LaTeX example with the same patch included

```tex \documentclass{article} \usepackage{tabularray} \makeatletter \ExplSyntaxOn \keys_define:nn { tblr-hline } { text .code:n = \tl_set:Nn \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text \exp_not:n {#1} }, } \keys_define:nn { tblr-vline } { text .code:n = \tl_set:Nn \l__tblr_vline_dash_tl { \exp_not:N \@tblr@text \exp_not:n {#1} }, } \cs_undefine:N \tblr_set_hline:nnn \cs_new_protected:Npn \tblr_set_hline:nnn #1 #2 #3 { \group_begin: \keys_set_groups:nnn { tblr-hline } { text } {#3} \tl_if_eq:NnF \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text \exp_not:n {} } { \__tblr_set_hline_num:n {#1} \tl_clear:N \l__tblr_hline_dash_tl \keys_set:nn { tblr-hline } { dash = solid, #3 } \__tblr_set_hline_cmd:n {#2} } \group_end: } \cs_undefine:N \tblr_set_vline:nnn \cs_new_protected:Npn \tblr_set_vline:nnn #1 #2 #3 { \group_begin: \keys_set_groups:nnn { tblr-vline } { text } {#3} \tl_if_eq:NnF \l__tblr_vline_dash_tl { \exp_not:N \@tblr@text \exp_not:n {} } { \__tblr_set_vline_num:n {#1} \tl_clear:N \l__tblr_vline_dash_tl \keys_set:nn { tblr-vline } { dash = solid, #3 } \__tblr_set_vline_cmd:n {#2} } \group_end: } \ExplSyntaxOff \makeatother \begin{document} \SetTblrInner{cells = {preto={\small (\therownum, \thecolnum)}}} \begin{tblr}{hlines, vlines} & & \\ \\ \\ \end{tblr} \qquad % \begin{tblr}{ hlines = {text = {\bfseries ---h---}}, vlines = {text = {\fontfamily{pcr}\selectfont v}} } & & \\ \\ \\ \end{tblr} \qquad % % empty text \begin{tblr}{ hlines = {text = }, vlines = {text = } } & & \\ \\ \\ \end{tblr} \end{document} ``` ![image](https://github.com/lvjr/tabularray/assets/6376638/6a5cc552-cc63-4f2d-b44e-6f65fc29f1fa)

Another solution is to do \__tblr_spec_gput:neV { ... } { ... } \l__tblr_(h|v)line_dash_tl but then the logic detecting and skipping \@tblr@dash and/or \@tblr@text need adaption.

Perhaps \@tblr@dash and \@tblr@text can be replaced with expl3 quark or scan mark variables.

muzimuzhi commented 3 months ago

@wwojciech As workarounds, apart from hiding text value in commands that can survive full expansion (https://github.com/lvjr/tabularray/discussions/484#discussioncomment-8846612), wrapping text value in \unexpanded{...} also works.

\documentclass{article}
\usepackage{tabularray}

\begin{document}
\begin{tblr}{hlines, vlines}
  & & \\
  \\
  \\
\end{tblr}
\qquad
%
% workaround: use only protected commands in text
\protected\def\myHlineTextStyle{\bfseries}
\protected\def\myVlineTextStyle{\fontfamily{pcr}\selectfont}
\begin{tblr}{
  hlines = {text={\myHlineTextStyle ---h---}},
  vlines = {text={\myVlineTextStyle v}}
}
  & & \\
  \\
  \\
\end{tblr}
\qquad
%
% workaround: wrap text in \unexpanded{...}
\begin{tblr}{
  hlines = {text = {\unexpanded{\bfseries ---h---}}},
  vlines = {text = {\unexpanded{\fontfamily{pcr}\selectfont v}}}
}
  & & \\
  \\
  \\
\end{tblr}
\end{document}

image