Skip to content

Commit eefbcd7

Browse files
committed
child selector: avoid l3regex and parse entire child list (#553, #577)
1 parent 839ea60 commit eefbcd7

1 file changed

Lines changed: 127 additions & 61 deletions

File tree

tabularray.sty

Lines changed: 127 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484

8585
\cs_generate_variant:Nn \msg_error:nnnnn { nnnVV }
8686
\cs_generate_variant:Nn \seq_map_indexed_inline:Nn { cn }
87+
\cs_generate_variant:Nn \seq_set_split:Nnn { NVe }
8788
\cs_generate_variant:Nn \seq_set_split_keep_spaces:Nnn { Ne }
8889
\cs_generate_variant:Nn \seq_use:Nn { Ne }
8990
\cs_generate_variant:Nn \tl_gput_right:Nn { Nf }
@@ -107,7 +108,8 @@
107108
\cs_generate_variant:Nn \tl_put_left:Nn { Ne, Nv }
108109
\cs_generate_variant:Nn \tl_put_right:Nn { Ne }
109110
\cs_generate_variant:Nn \tl_set:Nn { Ne, ce }
110-
\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nne }
111+
\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nne, NnV }
112+
\cs_generate_variant:Nn \tl_to_str:n { e }
111113
\prg_generate_conditional_variant:Nnn \prop_if_in:Nn { c } { T }
112114
\prg_generate_conditional_variant:Nnn \regex_match:Nn { NV } { TF }
113115
\prg_generate_conditional_variant:Nnn \tl_if_eq:nn { en } { T, TF }
@@ -201,6 +203,42 @@
201203
\vbox_set:Nn #1 {#2}
202204
}
203205

206+
%%% --------------------------------------------------------
207+
%%> \section{Functions for splitting, extracting and matching}
208+
%%% --------------------------------------------------------
209+
210+
\str_const:Nn \c__tblr_comma_str { , }
211+
\str_const:Nn \c__tblr_left_bracket_str { [ }
212+
213+
\cs_new_protected:Npn \__tblr_split_before_brace:NNn #1 #2 #3
214+
{
215+
\__tblr_split_before:NNVn #1 #2 \c_left_brace_str {#3}
216+
}
217+
218+
\cs_new_protected:Npn \__tblr_split_before_bracket:NNn #1 #2 #3
219+
{
220+
\__tblr_split_before:NNVn #1 #2 \c__tblr_left_bracket_str {#3}
221+
}
222+
\cs_generate_variant:Nn \__tblr_split_before_bracket:NNn { NNV }
223+
224+
%% Split tl #2 as two parts: sub tl before first #3 and sub tl from first #1.
225+
%% And the results are stored in tl vars #1 and #2, respectively.
226+
\cs_new_protected:Npn \__tblr_split_before:NNnn #1 #2 #3 #4
227+
{
228+
\cs_set_protected:Npn \__tblr_split_before_auxa:ww ##1 #3 ##2 \q_stop
229+
{
230+
\tl_set:Nn #1 { ##1 }
231+
\tl_if_empty:nTF { ##2 }
232+
{ \tl_set:Nn #2 { ##2 } } { \__tblr_split_before_auxb:w ##2 \q_stop }
233+
}
234+
\cs_set_protected:Npn \__tblr_split_before_auxb:w ##1 #3 \q_stop
235+
{
236+
\tl_set:Nn #2 { #3 ##1 }
237+
}
238+
\__tblr_split_before_auxa:ww #4 #3 \q_stop
239+
}
240+
\cs_generate_variant:Nn \__tblr_split_before:NNnn { NNV }
241+
204242
%%% --------------------------------------------------------
205243
%%> \section{Declare and Set tabularray Keys}
206244
%%% --------------------------------------------------------
@@ -1067,8 +1105,11 @@
10671105

10681106
\tl_new:N \l__tblr_childs_arg_spec_tl
10691107

1108+
\msg_new:nnn { tabularray } { invalid-child-selector }
1109+
{ Could ~ not ~ define ~ single-letter ~ selector ~ '#1'. }
1110+
10701111
\msg_new:nnn { tabularray } { used-child-selector }
1071-
{ Child ~ selector ~ name ~ "#1" ~ has ~ been ~ used! }
1112+
{ Child ~ selector ~ name ~ '#1' ~ has ~ been ~ used. }
10721113

10731114
\NewDocumentCommand \NewChildSelector { m O{0} o m }
10741115
{
@@ -1077,16 +1118,22 @@
10771118

10781119
\cs_new_protected:Npn \__tblr_new_child_selector_aux:nnnn #1 #2 #3 #4
10791120
{
1080-
\clist_if_in:NnTF \gTblrUsedChildSelectorsClist { #1 }
1121+
\int_compare:nNnTF { \tl_count:n {#1} } < { 2 }
10811122
{
1082-
\msg_error:nnn { tabularray } { used-child-selector } { #1 }
1083-
\clist_log:N \gTblrUsedChildSelectorsClist
1123+
\msg_error:nnn { tabularray } { invalid-child-selector } { #1 }
10841124
}
10851125
{
1086-
\__tblr_make_xparse_arg_spec:nnN { #2 } { #3 } \l__tblr_childs_arg_spec_tl
1087-
\exp_args:NcV \NewDocumentCommand
1088-
{ __tblr_child_selector_ #1 :w } \l__tblr_childs_arg_spec_tl { #4 }
1089-
\clist_gput_right:Nn \gTblrUsedChildSelectorsClist { #1 }
1126+
\clist_if_in:NnTF \gTblrUsedChildSelectorsClist { #1 }
1127+
{
1128+
\msg_error:nnn { tabularray } { used-child-selector } { #1 }
1129+
\clist_log:N \gTblrUsedChildSelectorsClist
1130+
}
1131+
{
1132+
\__tblr_make_xparse_arg_spec:nnN { #2 } { #3 } \l__tblr_childs_arg_spec_tl
1133+
\exp_args:NcV \NewDocumentCommand
1134+
{ __tblr_child_selector_ #1 :w } \l__tblr_childs_arg_spec_tl { #4 }
1135+
\clist_gput_right:Nn \gTblrUsedChildSelectorsClist { #1 }
1136+
}
10901137
}
10911138
}
10921139
\cs_generate_variant:Nn \__tblr_new_child_selector_aux:nnnn { ennn }
@@ -1147,37 +1194,56 @@
11471194
{ \clist_put_right:Nn \lTblrChildClist {##1} }
11481195
}
11491196

1150-
\regex_const:Nn \c__tblr_split_selector_name_regex { ^ ( [A-Za-z] {2,} ) ( . * ) }
1151-
\seq_new:N \l__tblr_childs_split_seq
1152-
\seq_new:N \l__tblr_childs_regex_seq
1153-
\tl_new:N \l__tblr_childs_selector_tl
1197+
\clist_new:N \l__tblr_child_whole_clist
1198+
\tl_new:N \l__tblr_selector_name_tl
1199+
\tl_new:N \l__tblr_selector_oarg_tl
1200+
\tl_new:N \l__tblr_selector_marg_tl
1201+
\tl_new:N \l__tblr_selector_args_tl
11541202

11551203
%% #1, child specifications; #2, total number.
1156-
%% The result will be put into \lTblrChildClist
1157-
\cs_new_protected:Npn \__tblr_get_childs:nn #1 #2
1158-
{
1159-
\clist_clear:N \lTblrChildClist
1160-
\int_set:Nn \lTblrChildTotalInt {#2}
1161-
\regex_extract_once:NnNTF \c__tblr_split_selector_name_regex {#1}
1162-
\l__tblr_childs_regex_seq
1163-
{
1164-
\tl_set:No \l__tblr_childs_selector_tl
1165-
{
1166-
\cs:w
1167-
__tblr_child_selector_ \seq_item:Nn \l__tblr_childs_regex_seq {2} :w
1168-
\cs_end:
1204+
%% The result will be put into \l__tblr_child_whole_clist
1205+
\cs_new_protected:Npn \__tblr_child_parse:nn #1 #2
1206+
{
1207+
\clist_clear:N \l__tblr_child_whole_clist
1208+
\seq_set_split:NVe \l__child_spec_seq
1209+
\c__tblr_comma_str { \tl_to_str:n {#1} }
1210+
\seq_map_inline:Nn \l__child_spec_seq
1211+
{
1212+
\__tblr_split_before_brace:NNn
1213+
\l_tmpa_tl \l__tblr_selector_marg_tl {##1}
1214+
\__tblr_split_before_bracket:NNV
1215+
\l__tblr_selector_name_tl \l__tblr_selector_oarg_tl \l_tmpa_tl
1216+
\tl_set_rescan:NnV \l__tblr_selector_name_tl {} \l__tblr_selector_name_tl
1217+
\clist_clear:N \lTblrChildClist
1218+
\int_set:Nn \lTblrChildTotalInt {#2}
1219+
\clist_if_in:NVTF \gTblrUsedChildSelectorsClist \l__tblr_selector_name_tl
1220+
{
1221+
\tl_set_rescan:Nne \l__tblr_selector_args_tl {}
1222+
{
1223+
\exp_not:V \l__tblr_selector_oarg_tl
1224+
\exp_not:V \l__tblr_selector_marg_tl
1225+
}
1226+
\exp_last_unbraced:Nno
1227+
\use:c { __tblr_child_selector_ \l__tblr_selector_name_tl :w }
1228+
{ \l__tblr_selector_args_tl }
11691229
}
1170-
\exp_last_unbraced:Ne \l__tblr_childs_selector_tl
1171-
{ \seq_item:Nn \l__tblr_childs_regex_seq{3} }
1230+
{ \l__tblr_child_parse_normal:Vn \l__tblr_selector_name_tl {#2} }
1231+
\clist_concat:NNN \l__tblr_child_whole_clist
1232+
\l__tblr_child_whole_clist \lTblrChildClist
11721233
}
1173-
{
1174-
\tl_if_eq:nnTF {#1} {-}
1175-
{ \__tblr_get_childs_normal:nn {1-#2} {#2} }
1176-
{ \__tblr_get_childs_normal:nn {#1} {#2} }
1177-
}
1178-
%\clist_log:N \lTblrChildClist
1234+
%\clist_log:N \l__tblr_child_whole_clist
11791235
}
1180-
\cs_generate_variant:Nn \__tblr_get_childs:nn { ne }
1236+
\cs_generate_variant:Nn \__tblr_child_parse:nn { ne }
1237+
1238+
\cs_new_protected:Npn \l__tblr_child_parse_normal:nn #1 #2
1239+
{
1240+
\tl_if_eq:nnTF {#1} {-}
1241+
{ \__tblr_get_childs_normal:nn {1-#2} {#2} }
1242+
{ \__tblr_get_childs_normal:nn {#1} {#2} }
1243+
}
1244+
\cs_generate_variant:Nn \l__tblr_child_parse_normal:nn { Vn }
1245+
1246+
\seq_new:N \l__tblr_childs_split_seq
11811247

11821248
\cs_new_protected:Npn \__tblr_get_childs_normal:nn #1 #2
11831249
{
@@ -1198,15 +1264,15 @@
11981264
{ \clist_put_right:Nn \lTblrChildClist {##1} }
11991265
}
12001266

1201-
\regex_const:Nn \c__tblr_child_name_regex { ^ [U-Z] $ }
1267+
\clist_const:Nn \c__tblr_child_name_clist { U, V, W, X, Y, Z }
12021268

12031269
\msg_new:nnn { tabularray } { named-index-out-of-bound }
12041270
{ Named ~ index ~ ``#1'' ~ (#2) ~ out ~ of ~ bound ~ [1, ~ #3]. }
12051271

12061272
%% Convert U, V, W, X, Y, Z to the indexes of the last six childs, respectively
12071273
\cs_new_protected_nopar:Npn \__tblr_child_name_to_index:nN #1 #2
12081274
{
1209-
\regex_match:NnTF \c__tblr_child_name_regex {#1}
1275+
\clist_if_in:NnTF \c__tblr_child_name_clist {#1}
12101276
{
12111277
\tl_set:Ne #2
12121278
{ \int_eval:n { \lTblrChildTotalInt + \int_from_alph:n {#1} - 26 } }
@@ -1513,8 +1579,8 @@
15131579
\cs_new_protected:Npn \tblr_set_hline:nnnn #1 #2 #3 #4
15141580
{
15151581
\group_begin:
1516-
\__tblr_get_childs:ne {#1} { \int_eval:n { \c@rowcount + 1 } }
1517-
\clist_map_inline:Nn \lTblrChildClist
1582+
\__tblr_child_parse:ne {#1} { \int_eval:n { \c@rowcount + 1 } }
1583+
\clist_map_inline:Nn \l__tblr_child_whole_clist
15181584
{
15191585
\int_set:Nn \c@rownum {##1}
15201586
\tblr_set_hline:nnn {#2} {#3} {#4}
@@ -1610,8 +1676,8 @@
16101676

16111677
\cs_new_protected_nopar:Npn \__tblr_set_hline_cmd:n #1
16121678
{
1613-
\__tblr_get_childs:ne {#1} { \int_use:N \c@colcount }
1614-
\clist_map_inline:Nn \lTblrChildClist
1679+
\__tblr_child_parse:ne {#1} { \int_use:N \c@colcount }
1680+
\clist_map_inline:Nn \l__tblr_child_whole_clist
16151681
{
16161682
% prevent expansion of vline text (see issue #303)
16171683
\__tblr_set_hline_option:nnn { ##1 } { @dash }
@@ -1630,12 +1696,12 @@
16301696
\bool_if:NTF \l__tblr_hline_endpos_bool
16311697
{
16321698
\__tblr_set_hline_option:nnn
1633-
{ \clist_item:Nn \lTblrChildClist {1} }
1699+
{ \clist_item:Nn \l__tblr_child_whole_clist {1} }
16341700
{ leftpos }
16351701
{ \l__tblr_hline_leftpos_tl }
16361702
}
16371703
{
1638-
\clist_map_inline:Nn \lTblrChildClist
1704+
\clist_map_inline:Nn \l__tblr_child_whole_clist
16391705
{
16401706
\__tblr_set_hline_option:nnn
16411707
{ ##1 } { leftpos } { \l__tblr_hline_leftpos_tl }
@@ -1647,12 +1713,12 @@
16471713
\bool_if:NTF \l__tblr_hline_endpos_bool
16481714
{
16491715
\__tblr_set_hline_option:nnn
1650-
{ \clist_item:Nn \lTblrChildClist {-1} }
1716+
{ \clist_item:Nn \l__tblr_child_whole_clist {-1} }
16511717
{ rightpos }
16521718
{ \l__tblr_hline_rightpos_tl }
16531719
}
16541720
{
1655-
\clist_map_inline:Nn \lTblrChildClist
1721+
\clist_map_inline:Nn \l__tblr_child_whole_clist
16561722
{
16571723
\__tblr_set_hline_option:nnn
16581724
{ ##1 } { rightpos } { \l__tblr_hline_rightpos_tl }
@@ -1758,8 +1824,8 @@
17581824
\cs_new_protected:Npn \tblr_set_vline:nnnn #1 #2 #3 #4
17591825
{
17601826
\group_begin:
1761-
\__tblr_get_childs:ne {#1} { \int_eval:n { \c@colcount + 1} }
1762-
\clist_map_inline:Nn \lTblrChildClist
1827+
\__tblr_child_parse:ne {#1} { \int_eval:n { \c@colcount + 1} }
1828+
\clist_map_inline:Nn \l__tblr_child_whole_clist
17631829
{
17641830
\int_set:Nn \c@colnum {##1}
17651831
\tblr_set_vline:nnn {#2} {#3} {#4}
@@ -1848,8 +1914,8 @@
18481914

18491915
\cs_new_protected_nopar:Npn \__tblr_set_vline_cmd:n #1
18501916
{
1851-
\__tblr_get_childs:ne {#1} { \int_use:N \c@rowcount }
1852-
\clist_map_inline:Nn \lTblrChildClist
1917+
\__tblr_child_parse:ne {#1} { \int_use:N \c@rowcount }
1918+
\clist_map_inline:Nn \l__tblr_child_whole_clist
18531919
{
18541920
\__tblr_spec_gput:nee { vline }
18551921
{ [##1][\int_use:N \c@colnum](\l__tblr_vline_num_tl) / @dash }
@@ -1897,8 +1963,8 @@
18971963
\cs_new_protected:Npn \tblr_set_hborder:nn #1 #2
18981964
{
18991965
\group_begin:
1900-
\__tblr_get_childs:ne {#1} { \int_eval:n { \c@rowcount + 1 } }
1901-
\clist_map_inline:Nn \lTblrChildClist
1966+
\__tblr_child_parse:ne {#1} { \int_eval:n { \c@rowcount + 1 } }
1967+
\clist_map_inline:Nn \l__tblr_child_whole_clist
19021968
{
19031969
\int_set:Nn \c@rownum {##1}
19041970
\tblr_set_hborder:n {#2}
@@ -1954,8 +2020,8 @@
19542020
\cs_new_protected:Npn \tblr_set_vborder:nn #1 #2
19552021
{
19562022
\group_begin:
1957-
\__tblr_get_childs:ne {#1} { \int_eval:n { \c@colcount + 1 } }
1958-
\clist_map_inline:Nn \lTblrChildClist
2023+
\__tblr_child_parse:ne {#1} { \int_eval:n { \c@colcount + 1 } }
2024+
\clist_map_inline:Nn \l__tblr_child_whole_clist
19592025
{
19602026
\int_set:Nn \c@colnum {##1}
19612027
\tblr_set_vborder:n {#2}
@@ -2040,10 +2106,10 @@
20402106
\cs_new_protected:Npn \tblr_set_cell:nnnn #1 #2 #3 #4
20412107
{
20422108
\group_begin:
2043-
\__tblr_get_childs:ne {#1} { \int_use:N \c@rowcount }
2044-
\clist_set_eq:NN \l_tmpa_clist \lTblrChildClist
2045-
\__tblr_get_childs:ne {#2} { \int_use:N \c@colcount }
2046-
\clist_set_eq:NN \l_tmpb_clist \lTblrChildClist
2109+
\__tblr_child_parse:ne {#1} { \int_use:N \c@rowcount }
2110+
\clist_set_eq:NN \l_tmpa_clist \l__tblr_child_whole_clist
2111+
\__tblr_child_parse:ne {#2} { \int_use:N \c@colcount }
2112+
\clist_set_eq:NN \l_tmpb_clist \l__tblr_child_whole_clist
20472113
\clist_map_inline:Nn \l_tmpa_clist
20482114
{
20492115
\int_set:Nn \c@rownum {##1}
@@ -2284,8 +2350,8 @@
22842350
\cs_new_protected:Npn \tblr_set_column:nnn #1 #2 #3
22852351
{
22862352
\group_begin:
2287-
\__tblr_get_childs:ne {#1} { \int_use:N \c@colcount }
2288-
\clist_map_inline:Nn \lTblrChildClist
2353+
\__tblr_child_parse:ne {#1} { \int_use:N \c@colcount }
2354+
\clist_map_inline:Nn \l__tblr_child_whole_clist
22892355
{
22902356
\int_set:Nn \c@colnum {##1}
22912357
\tblr_set_column:nn {#2} {#3}
@@ -2452,8 +2518,8 @@
24522518
\cs_new_protected:Npn \tblr_set_row:nnn #1 #2 #3
24532519
{
24542520
\group_begin:
2455-
\__tblr_get_childs:ne {#1} { \int_use:N \c@rowcount }
2456-
\clist_map_inline:Nn \lTblrChildClist
2521+
\__tblr_child_parse:ne {#1} { \int_use:N \c@rowcount }
2522+
\clist_map_inline:Nn \l__tblr_child_whole_clist
24572523
{
24582524
\int_set:Nn \c@rownum {##1}
24592525
\tblr_set_row:nn {#2} {#3}

0 commit comments

Comments
 (0)