From 8abdfcec525ef0d777e485bd64c048b264f127ed Mon Sep 17 00:00:00 2001 From: Yukai Chou <muzimuzhi@gmail.com> Date: Sat, 16 Nov 2024 01:10:41 +0800 Subject: [PATCH] feat: keep braces when splitting So special cells needs only one group of braces. --- build.lua | 2 +- tabularray.sty | 25 +++++++++++++---- testfiles-old/library-009.tex | 4 +-- testfiles-old/table-001.tlg | 3 ++ testfiles/loading-001.tlg | 3 ++ zutil.sty | 52 +++++++++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 zutil.sty diff --git a/build.lua b/build.lua index 2e9badb..e098647 100644 --- a/build.lua +++ b/build.lua @@ -1,7 +1,7 @@ module = "tabularray" -sourcefiles = { "tabularray.sty" } +sourcefiles = { "tabularray.sty", "zutil.sty" } checkengines = { "pdftex", "xetex", "luatex" } stdengine = "pdftex" diff --git a/tabularray.sty b/tabularray.sty index 8e18117..03a81a5 100644 --- a/tabularray.sty +++ b/tabularray.sty @@ -33,6 +33,8 @@ \usepackage{xparse} } +\RequirePackage{zutil} + \AtBeginDocument{ \@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{} \@ifpackageloaded{hyperref}{ @@ -2726,7 +2728,7 @@ \cs_new_protected:Npn \__tblr_split_table_to_lines:NN #1 #2 { \__tblr_insert_braces:N #1 - \seq_set_split:NnV \l__tblr_tmpa_seq { \\ } #1 + \zutil_seq_set_split_keep_braces:NnV \l__tblr_tmpa_seq { \\ } #1 \seq_clear:N #2 \seq_map_inline:Nn \l__tblr_tmpa_seq { @@ -2773,7 +2775,7 @@ %% #1: row number, #2 the line text \cs_new_protected:Npn \__tblr_split_one_line:nn #1 #2 { - \seq_set_split:Nnn \l__tblr_tmpa_seq { & } { #2 } + \zutil_seq_set_split_keep_braces:Nnn \l__tblr_tmpa_seq { & } { #2 } \int_set:Nn \c@rownum {#1} \int_zero:N \c@colnum \seq_map_inline:Nn \l__tblr_tmpa_seq @@ -2849,7 +2851,8 @@ { \__tblr_save_real_cell_text:w #1 } } } - { \__tblr_save_real_cell_text:w {#1} } + % prefix #1 with \prg_do_nothing: to prevent brace stripping + { \__tblr_save_real_cell_text_aux:w \prg_do_nothing: {#1} } } \cs_new_protected:Npn \__tblr_extract_one_table_command:N #1 @@ -2895,6 +2898,12 @@ \tl_set:Nn \l__tblr_saved_cell_text_after_table_commands_tl {#1} } +\cs_new_protected:Npn \__tblr_save_real_cell_text_aux:w #1 \q_stop + { + % o-type expansion is used to digest \prg_do_nothing: + \tl_set:No \l__tblr_saved_cell_text_after_table_commands_tl {#1} + } + %%% -------------------------------------------------------- %%> \section{Initialize Table Inner Specifications} %%% -------------------------------------------------------- @@ -3590,11 +3599,15 @@ \group_begin: \tl_set:Ne \l__tblr_c_tl { \__tblr_spec_item:ne { text } {[#1][#2]} } %% when the cell text is guarded by a pair of curly braces, - %% we unbrace it and ignore cmd option of the cell, see issue #90. + %% we unbrace then trim spaces from it and ignore cmd option of the cell, + %% see issue #90. \bool_lazy_and:nnTF { \tl_if_single_p:N \l__tblr_c_tl } { \exp_args:NV \tl_if_head_is_group_p:n \l__tblr_c_tl } - { \exp_last_unbraced:NNV \tl_set:Nn \l__tblr_c_tl \l__tblr_c_tl } + { + \tl_set:Ne \l__tblr_c_tl + { \exp_after:wN \tl_trim_spaces:n \l__tblr_c_tl } + } { \tl_set:Ne \l__tblr_cell_cmd_tl { \__tblr_data_item:neen { cell } {#1} {#2} { cmd } } @@ -3696,7 +3709,7 @@ { \tl_set_eq:NN \l__tblr_tmpb_tl \l__tblr_c_tl \__tblr_insert_braces:N \l__tblr_tmpb_tl - \seq_set_split:NnV \l__tblr_tmpa_seq { \\ } \l__tblr_tmpb_tl + \zutil_seq_set_split_keep_braces:NnV \l__tblr_tmpa_seq { \\ } \l__tblr_tmpb_tl \tl_set:Nn \l__tblr_w_tl { 0pt } \seq_map_variable:NNn \l__tblr_tmpa_seq \l__tblr_tmpa_tl { diff --git a/testfiles-old/library-009.tex b/testfiles-old/library-009.tex index fce7fb2..237fc3b 100644 --- a/testfiles-old/library-009.tex +++ b/testfiles-old/library-009.tex @@ -20,7 +20,7 @@ \BEGINTEST{siunitx: testing multiline cells}%#90 \centering \begin{tblr}{colspec=lSS,hlines,vlines} -{two line \\ column header} & {{{column header}}} & {{{two line \\ column header}}} \\ +{two line \\ column header} & {column header} & {two line \\ column header} \\ \end{tblr} \ENDTEST @@ -29,7 +29,7 @@ \BEGINTEST{testing multiline cells with three pairs of braces}%#90 \centering \begin{tblr}{hlines,vlines} -{{{one line cell}}} & {{{two line \\ text}}} \\ +{one line cell} & {two line \\ text} \\ \end{tblr} \ENDTEST diff --git a/testfiles-old/table-001.tlg b/testfiles-old/table-001.tlg index af5fa96..8e710cb 100644 --- a/testfiles-old/table-001.tlg +++ b/testfiles-old/table-001.tlg @@ -2,6 +2,9 @@ This is a generated file for the l3build validation system. Don't change this file in any respect. (tabularray.sty Package: tabularray ....-..-.. v... Typeset tabulars and arrays with LaTeX3 +(zutil.sty +Package: zutil ....-..-.. v... Z's utilities, l3seq part +) \l__tblr_a_int=\count... \l__tblr_dp_dim=\dimen... \l__tblr_ht_dim=\dimen... diff --git a/testfiles/loading-001.tlg b/testfiles/loading-001.tlg index 832ef26..33085a3 100644 --- a/testfiles/loading-001.tlg +++ b/testfiles/loading-001.tlg @@ -2,6 +2,9 @@ This is a generated file for the l3build validation system. Don't change this file in any respect. (tabularray.sty Package: tabularray ....-..-.. v... Typeset tabulars and arrays with LaTeX3 +(zutil.sty +Package: zutil ....-..-.. v... Z's utilities, l3seq part +) \l__tblr_a_int=\count... \l__tblr_dp_dim=\dimen... \l__tblr_ht_dim=\dimen... diff --git a/zutil.sty b/zutil.sty new file mode 100644 index 0000000..31ce610 --- /dev/null +++ b/zutil.sty @@ -0,0 +1,52 @@ +\ProvidesExplPackage {zutil} {2024-11-15} {0.1} + {Z's utilities, l3seq part} + +%% +%% l3seq extras +%% +\msg_new:nnnn { zutil } { seq/empty-delimiter } + { Empty~delimiter~is~not~supported~in~#1. } + { I~will~skip~setting~#2. } + +\cs_new_protected:Npn \zutil_seq_set_split_keep_braces:Nnn #1 + { + \__zutil_seq_set_split:NNNNnn + \__kernel_tl_set:Nx \__zutil_seq_trim_spaces:n #1 + \zutil_seq_set_split_keep_braces:Nnn + } +\cs_generate_variant:Nn \zutil_seq_set_split_keep_braces:Nnn { NnV } + +% This implementation is quicker than adding another \prg_do_nothing: +% and \exp_args:No trick to \__zutil_seq_set_split:Nw and +% \__zutil_seq_set_split:w, resp. +\cs_new:Npn \__zutil_seq_trim_spaces:n #1 { { \tl_trim_spaces:n {#1} } } + +% Compared to \__seq_set_split:NNNnn, a forth N-arg is added which +% holds the user function, i.e. \zutil_seq_set_split_keep_braces:Nnn, +% for use in error message. +% +% l3seq internals \__seq_set_split:Nw, \__seq_set_split_end:, and +% \l__seq_internal_a_tl are used. +\cs_new_protected:Npn \__zutil_seq_set_split:NNNNnn #1#2#3#4#5#6 + { + \tl_if_empty:nTF {#5} + { + \msg_error:nnnn { zutil } { seq/empty-delimiter } {#4} {#3} + } + { + \tl_set:Nn \l__seq_internal_a_tl + { + \__seq_set_split:Nw #2 \prg_do_nothing: + #6 + \__seq_set_split_end: + } + \tl_replace_all:Nnn \l__seq_internal_a_tl {#5} + { + \__seq_set_split_end: + \__seq_set_split:Nw #2 \prg_do_nothing: + } + \__kernel_tl_set:Nx \l__seq_internal_a_tl { \l__seq_internal_a_tl } + #1 #3 { \s__seq \l__seq_internal_a_tl } + } + } +