diff options
author | Karl Berry <karl@freefriends.org> | 2021-07-01 21:36:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-07-01 21:36:51 +0000 |
commit | 25b9b4a44ec5c9b59661fdf1786015e62a311c1b (patch) | |
tree | 9a1a6c00259c761757826a5592ccb185bc997bb4 /Master/texmf-dist/tex | |
parent | f084a938e2c2bc53c7108c794da689f82865993b (diff) |
tabularray (1jul21)
git-svn-id: svn://tug.org/texlive/trunk@59797 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/tabularray/tabularray.sty | 2143 |
1 files changed, 1758 insertions, 385 deletions
diff --git a/Master/texmf-dist/tex/latex/tabularray/tabularray.sty b/Master/texmf-dist/tex/latex/tabularray/tabularray.sty index 8e5c2b93694..0a12e61ba5f 100644 --- a/Master/texmf-dist/tex/latex/tabularray/tabularray.sty +++ b/Master/texmf-dist/tex/latex/tabularray/tabularray.sty @@ -12,11 +12,16 @@ \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} -\ProvidesExplPackage{tabularray}{2021-06-05}{2021K} +\ProvidesExplPackage{tabularray}{2021-07-01}{2021L} {Typeset tabulars and arrays with LaTeX3} \RequirePackage{xparse} -\AtBeginDocument{\@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{}} + +\AtBeginDocument + { + \@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{} + \@ifpackageloaded{hyperref}{\hypersetup{pdfborder={0 0 0}}}{} + } \ExplSyntaxOn @@ -57,6 +62,7 @@ \prg_generate_conditional_variant:Nnn \prop_if_in:Nn { c } { T } \prg_generate_conditional_variant:Nnn \str_if_eq:nn { xn } { TF } \prg_generate_conditional_variant:Nnn \tl_if_eq:nn { en } { T, TF } +\prg_generate_conditional_variant:Nnn \tl_if_head_eq_catcode:nN { VN } { TF } \prg_generate_conditional_variant:Nnn \tl_if_head_eq_meaning:nN { VN } { T, TF } \tl_new:N \l__tblr_a_tl @@ -97,12 +103,26 @@ \box_new:N \l__tblr_c_box % for cell box \box_new:N \l__tblr_d_box +%% Total number of tblr tables +\int_new:N \g__tblr_table_count_int + +%% Some commands for horizontal alignment +\cs_new_eq:NN \__tblr_halign_command_l: \raggedright +\cs_new_eq:NN \__tblr_halign_command_c: \centering +\cs_new_eq:NN \__tblr_halign_command_r: \raggedleft + %% Some counters for row and column numbering \newcounter{rownum} \newcounter{colnum} \newcounter{rowcount} \newcounter{colcount} +%% Some dimensions for row and column spacing +\dim_new:N \abovesep +\dim_new:N \belowsep +\dim_new:N \leftsep +\dim_new:N \rightsep + %%% -------------------------------------------------------- %% \section{Data Structures Based on Property Lists} %%% -------------------------------------------------------- @@ -113,7 +133,10 @@ { \prop_gclear_new:c { g__tblr_text_ \int_use:N \g_tblr_level_int _prop } \prop_gclear_new:c { g__tblr_command_ \int_use:N \g_tblr_level_int _prop } - \prop_gclear_new:c { g__tblr_table_ \int_use:N \g_tblr_level_int _prop } + \prop_gclear_new:c { g__tblr_inner_ \int_use:N \g_tblr_level_int _prop } + \prop_gclear_new:c { g__tblr_note_ \int_use:N \g_tblr_level_int _prop } + \prop_gclear_new:c { g__tblr_remark_ \int_use:N \g_tblr_level_int _prop } + \prop_gclear_new:c { g__tblr_more_ \int_use:N \g_tblr_level_int _prop } \prop_gclear_new:c { g__tblr_row_ \int_use:N \g_tblr_level_int _prop } \prop_gclear_new:c { g__tblr_column_ \int_use:N \g_tblr_level_int _prop } \prop_gclear_new:c { g__tblr_cell_ \int_use:N \g_tblr_level_int _prop } @@ -184,7 +207,7 @@ { \dim_compare_p:nNn { #3 } > { \l__tblr_put_if_larger_tl } } { \prop_put:Nnn #1 { #2 } { #3 } } } -\cs_generate_variant:Nn \__tblr_put_if_larger:Nnn { Nnx, Nxn, Nxx } +\cs_generate_variant:Nn \__tblr_put_if_larger:Nnn { Nnx, Nxn, Nxx, NnV } \cs_new_protected:Npn \__tblr_gput_if_larger:Nnn #1 #2 #3 { @@ -215,63 +238,78 @@ %% \section{Data Structures Based on Token Lists} %%% -------------------------------------------------------- -\cs_new_protected:Npn \__tblr_clear_text_lists: +\cs_new_protected:Npn \__tblr_clear_spec_lists: { - \__tblr_clear_one_text_lists:n { text } - \__tblr_clear_one_text_lists:n { hline } - \__tblr_clear_one_text_lists:n { vline } + %\__tblr_clear_one_spec_lists:n { row } + %\__tblr_clear_one_spec_lists:n { column } + %\__tblr_clear_one_spec_lists:n { cell } + \__tblr_clear_one_spec_lists:n { text } + \__tblr_clear_one_spec_lists:n { hline } + \__tblr_clear_one_spec_lists:n { vline } + \__tblr_clear_one_spec_lists:n { outer } } -\cs_new_protected:Npn \__tblr_clear_one_text_lists:n #1 +\cs_new_protected:Npn \__tblr_clear_one_spec_lists:n #1 { \clist_if_exist:cTF { g__tblr_#1_ \int_use:N \g_tblr_level_int _clist } { \clist_map_inline:cn { g__tblr_#1_ \int_use:N \g_tblr_level_int _clist } { - \tl_gclear:c { g__tblr_text_ \int_use:N \g_tblr_level_int _#1_##1_tl } + \tl_gclear:c { g__tblr_spec_ \int_use:N \g_tblr_level_int _#1_##1_tl } } } { \clist_new:c { g__tblr_#1_ \int_use:N \g_tblr_level_int _clist } } } -\cs_new_protected:Npn \__tblr_text_gput:nnn #1 #2 #3 +\cs_new_protected:Npn \__tblr_spec_gput:nnn #1 #2 #3 { \tl_gset:cn - { g__tblr_text_ \int_use:N \g_tblr_level_int _#1_#2_tl } {#3} + { g__tblr_spec_ \int_use:N \g_tblr_level_int _#1_#2_tl } {#3} \clist_gput_right:cx { g__tblr_#1_ \int_use:N \g_tblr_level_int _clist } {#2} } -\cs_generate_variant:Nn \__tblr_text_gput:nnn { nne, nnV, nen, nee, neV } +\cs_generate_variant:Nn \__tblr_spec_gput:nnn { nne, nnV, nen, nee, neV } -\cs_new:Npn \__tblr_text_item:nn #1 #2 +\cs_new:Npn \__tblr_spec_item:nn #1 #2 { - \tl_if_exist:cT { g__tblr_text_ \int_use:N \g_tblr_level_int _#1_#2_tl } + \tl_if_exist:cT { g__tblr_spec_ \int_use:N \g_tblr_level_int _#1_#2_tl } { \exp_args:Nv \exp_not:n - { g__tblr_text_ \int_use:N \g_tblr_level_int _#1_#2_tl } + { g__tblr_spec_ \int_use:N \g_tblr_level_int _#1_#2_tl } } } -\cs_generate_variant:Nn \__tblr_text_item:nn { ne } +\cs_generate_variant:Nn \__tblr_spec_item:nn { ne } -\cs_new_protected:Npn \__tblr_text_gput_if_larger:nnn #1 #2 #3 +\cs_new_protected:Npn \__tblr_spec_gput_if_larger:nnn #1 #2 #3 { - \tl_set:Nx \l__tblr_put_if_larger_tl { \__tblr_text_item:nn {#1} {#2} } + \tl_set:Nx \l__tblr_put_if_larger_tl { \__tblr_spec_item:nn {#1} {#2} } \bool_lazy_or:nnT { \tl_if_empty_p:N \l__tblr_put_if_larger_tl } { \dim_compare_p:nNn {#3} > { \l__tblr_put_if_larger_tl } } - { \__tblr_text_gput:nnn {#1} {#2} {#3} } + { \__tblr_spec_gput:nnn {#1} {#2} {#3} } + } +\cs_generate_variant:Nn \__tblr_spec_gput_if_larger:nnn { nne, nnV, nen, nee, neV } + +\cs_new_protected:Npn \__tblr_spec_gadd_dimen_value:nnn #1 #2 #3 + { + \__tblr_spec_gput:nne {#1} {#2} + { \dim_eval:n { \__tblr_spec_item:ne {#1} {#2} + #3 } } } -\cs_generate_variant:Nn \__tblr_text_gput_if_larger:nnn { nne, nnV, nen, nee, neV } +\cs_generate_variant:Nn \__tblr_spec_gadd_dimen_value:nnn { nne, nnV, nen, nee } -\cs_new_protected:Npn \__tblr_text_log:n #1 +\cs_new_protected:Npn \__tblr_spec_log:n #1 { \clist_gremove_duplicates:c { g__tblr_#1_ \int_use:N \g_tblr_level_int _clist } - \tl_log:n { ----------~----------~----------~----------~---------- } + \tl_log:x + { + The ~ spec ~ list ~ #1 _ \int_use:N \g_tblr_level_int + \space contains ~ the ~ pairs: + } \clist_map_inline:cn { g__tblr_#1_ \int_use:N \g_tblr_level_int _clist } { \tl_log:x { - \space { #1 ##1 } ~\space=>~\space { \__tblr_text_item:nn {#1} {##1} } + \space { ##1 } ~\space=>~\space { \__tblr_spec_item:nn {#1} {##1} } } } } @@ -336,6 +374,7 @@ \__tblr_data_new_key:nnn { cell } { halign } { str } \__tblr_data_new_key:nnn { cell } { valign } { str } \__tblr_data_new_key:nnn { cell } { background } { str } +\__tblr_data_new_key:nnn { cell } { font } { str } \__tblr_data_new_key:nnn { cell } { omit } { int } \__tblr_data_new_key:nnn { cell } { @cell-width } { dim } \__tblr_data_new_key:nnn { cell } { @cell-height } { dim } @@ -350,12 +389,12 @@ \tl_const:Nn \g__tblr_data_cell_index_number_tl {2} \int_new:N \g__tblr_array_int -\cs_new_protected:Npn \__tblr_initial_table_data: +\cs_new_protected:Npn \__tblr_init_table_data: { - \clist_map_function:NN \g__tblr_data_clist \__tblr_initial_one_data:n + \clist_map_function:NN \g__tblr_data_clist \__tblr_init_one_data:n } -\cs_new_protected:Npn \__tblr_initial_one_data:n #1 +\cs_new_protected:Npn \__tblr_init_one_data:n #1 { \int_gincr:N \g__tblr_array_int \intarray_new:cn { g__tblr_#1_ \int_use:N \g__tblr_array_int _intarray } @@ -507,18 +546,18 @@ \cs_new_protected:Npn \__tblr_data_int_from_str:n #1 { - \tl_if_exist:cTF { g__tblr_data_#1_to_int_tl } + \tl_if_exist:cTF { g__tblr_data_ \tl_to_str:n {#1} _to_int_tl } { \tl_gset_eq:Nc \g__tblr_data_int_from_value_tl - { g__tblr_data_#1_to_int_tl } + { g__tblr_data_ \tl_to_str:n {#1} _to_int_tl } } { \int_gincr:N \g__tblr_data_str_value_count_int - \tl_gset:cx { g__tblr_data_#1_to_int_tl } + \tl_gset:cx { g__tblr_data_ \tl_to_str:n {#1} _to_int_tl } { \int_use:N \g__tblr_data_str_value_count_int } - \tl_gset:cx + \tl_gset:cn { g__tblr_data_ \int_use:N \g__tblr_data_str_value_count_int _to_str_tl } - { #1 } + { \exp_not:n {#1} } \tl_gset:Nx \g__tblr_data_int_from_value_tl { \int_use:N \g__tblr_data_str_value_count_int } } @@ -661,7 +700,8 @@ { \__tblr_data_key_to_int:nnn {#1} {#2} {#3} } { \g__tblr_data_int_from_value_tl } } -\cs_generate_variant:Nn \__tblr_data_gadd_dimen_value:nnnn { nnne, nnnV, nene } +\cs_generate_variant:Nn \__tblr_data_gadd_dimen_value:nnnn + { nnne, nnnV, nenn, nene } \cs_new_protected:Npn \__tblr_array_gadd_value:Nnn #1 #2 #3 { @@ -678,39 +718,39 @@ { \cs_set_protected:Npn \__tblr_data_gput:nnnn #1 #2 #3 #4 { - \__tblr_prop_gput:nnn {#1} { [#2] / #3 } {#4} + \__tblr_spec_gput:nnn {#1} { [#2] / #3 } {#4} } \cs_set_protected:Npn \__tblr_data_gput:nnnnn #1 #2 #3 #4 #5 { - \__tblr_prop_gput:nnn {#1} { [#2][#3] / #4 } {#5} + \__tblr_spec_gput:nnn {#1} { [#2][#3] / #4 } {#5} } \cs_set:Npn \__tblr_data_item:nnn #1 #2 #3 { - \__tblr_prop_item:nn {#1} { [#2] / #3 } + \__tblr_spec_item:nn {#1} { [#2] / #3 } } \cs_set:Npn \__tblr_data_item:nnnn #1 #2 #3 #4 { - \__tblr_prop_item:nn {#1} { [#2][#3] / #4 } + \__tblr_spec_item:nn {#1} { [#2][#3] / #4 } } \cs_set_protected:Npn \__tblr_data_log:n #1 { - \__tblr_prop_log:n {#1} + \__tblr_spec_log:n {#1} } \cs_set_protected:Npn \__tblr_data_gput_if_larger:nnnn #1 #2 #3 #4 { - \__tblr_prop_gput_if_larger:nnn {#1} { [#2] / #3 } {#4} + \__tblr_spec_gput_if_larger:nnn {#1} { [#2] / #3 } {#4} } \cs_set_protected:Npn \__tblr_data_gput_if_larger:nnnnn #1 #2 #3 #4 #5 { - \__tblr_prop_gput_if_larger:nnn {#1} { [#2][#3] / #4 } {#5} + \__tblr_spec_gput_if_larger:nnn {#1} { [#2][#3] / #4 } {#5} } \cs_set_protected:Npn \__tblr_data_gadd_dimen_value:nnnn #1 #2 #3 #4 { - \__tblr_prop_gadd_dimen_value:nnn {#1} { [#2] / #3 } {#4} + \__tblr_spec_gadd_dimen_value:nnn {#1} { [#2] / #3 } {#4} } \cs_set_protected:Npn \__tblr_data_gadd_dimen_value:nnnnn #1 #2 #3 #4 #5 { - \__tblr_prop_gadd_dimen_value:nnn {#1} { [#2][#3] / #4 } {#5} + \__tblr_spec_gadd_dimen_value:nnn {#1} { [#2][#3] / #4 } {#5} } } } @@ -890,6 +930,40 @@ } %%% -------------------------------------------------------- +%%> \section{New Content Commands} +%%% -------------------------------------------------------- + +%% We need to emulate or fix some commands such as \diagbox in other packages +%% These commands must be defined with \NewContentCommand command +%% We only enable them inside tblr environment to avoid potential conflict + +\clist_new:N \g__tblr_content_commands_clist + +\msg_new:nnn { tabularray } { defined-content-command } + { Content ~ commnad ~ #1 has ~ been ~ defined! } + +\NewDocumentCommand \NewContentCommand { m O{0} o m } + { + \clist_if_in:NnTF \g__tblr_content_commands_clist { #1 } + { + \msg_warning:nnn { tabularray } { defined-content-command } { #1 } + \clist_log:N \g__tblr_content_commands_clist + } + { + \__tblr_make_xparse_arg_spec:nnN { #2 } { #3 } \l__tblr_a_tl + \exp_args:NcV \NewDocumentCommand + { __tblr_content_command_ \cs_to_str:N #1 :w } \l__tblr_a_tl { #4 } + \clist_gput_right:Nn \g__tblr_content_commands_clist { #1 } + } + } + +\cs_new_protected:Npn \__tblr_enable_content_commands: + { + \clist_map_inline:Nn \g__tblr_content_commands_clist + { \cs_set_eq:Nc ##1 { __tblr_content_command_ \cs_to_str:N ##1 :w } } + } + +%%% -------------------------------------------------------- %% \section{New Dash Styles} %%% -------------------------------------------------------- @@ -1068,12 +1142,12 @@ { \tl_clear:N \l__tblr_hline_num_tl \tl_set:Nx \l__tblr_hline_count_tl - { \__tblr_text_item:ne { hline } { [\int_use:N \c@rownum] / @hline-count } } + { \__tblr_spec_item:ne { hline } { [\int_use:N \c@rownum] / @hline-count } } %% \l__tblr_hline_count_tl may be empty when rowspec has extra |'s \int_compare:nNnTF { \l__tblr_hline_count_tl + 0 } = {0} { \tl_set:Nx \l__tblr_hline_num_tl { 1 } - \__tblr_text_gput:nen { hline } + \__tblr_spec_gput:nen { hline } { [\int_use:N \c@rownum] / @hline-count } { 1 } } { @@ -1095,7 +1169,7 @@ { \tl_set:Nx \l__tblr_hline_count_tl { \int_eval:n { \l__tblr_hline_count_tl + 1 } } - \__tblr_text_gput:nee { hline } + \__tblr_spec_gput:nee { hline } { [\int_use:N \c@rownum] / @hline-count } { \l__tblr_hline_count_tl } \tl_set_eq:NN \l__tblr_hline_num_tl \l__tblr_hline_count_tl } @@ -1131,18 +1205,18 @@ \__tblr_get_childs:nx {#1} { \int_use:N \c@colcount } \clist_map_inline:Nn \l_tblr_childs_clist { - \__tblr_text_gput:nee { hline } + \__tblr_spec_gput:nee { hline } { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / @dash } { \l__tblr_hline_dash_tl } \tl_if_empty:NF \l__tblr_hline_wd_tl { - \__tblr_text_gput:nee { hline } + \__tblr_spec_gput:nee { hline } { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / wd } { \l__tblr_hline_wd_tl } } \tl_if_empty:NF \l__tblr_hline_fg_tl { - \__tblr_text_gput:nee { hline } + \__tblr_spec_gput:nee { hline } { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / fg } { \l__tblr_hline_fg_tl } } @@ -1156,13 +1230,13 @@ { \tl_if_eq:nnTF {#1} {above} { - \__tblr_prop_gput:nnx { table } + \__tblr_prop_gput:nnx { inner } { baseline } { \int_eval:n { \c@rownum - 1 } } } { \tl_if_eq:nnT {#1} {below} { - \__tblr_prop_gput:nnx { table } { baseline } { \int_use:N \c@rownum } + \__tblr_prop_gput:nnx { inner } { baseline } { \int_use:N \c@rownum } } } } @@ -1267,12 +1341,12 @@ { \tl_clear:N \l__tblr_vline_num_tl \tl_set:Nx \l__tblr_vline_count_tl - { \__tblr_text_item:ne { vline } { [\int_use:N \c@colnum] / @vline-count } } + { \__tblr_spec_item:ne { vline } { [\int_use:N \c@colnum] / @vline-count } } %% \l__tblr_vline_count_tl may be empty when colspec has extra |'s \int_compare:nNnTF { \l__tblr_vline_count_tl + 0 } = {0} { \tl_set:Nx \l__tblr_vline_num_tl { 1 } - \__tblr_text_gput:nen { vline } + \__tblr_spec_gput:nen { vline } { [\int_use:N \c@colnum] / @vline-count } { 1 } } { @@ -1294,7 +1368,7 @@ { \tl_set:Nx \l__tblr_vline_count_tl { \int_eval:n { \l__tblr_vline_count_tl + 1 } } - \__tblr_text_gput:nee { vline } + \__tblr_spec_gput:nee { vline } { [\int_use:N \c@colnum] / @vline-count } { \l__tblr_vline_count_tl } \tl_set_eq:NN \l__tblr_vline_num_tl \l__tblr_vline_count_tl } @@ -1329,18 +1403,18 @@ \__tblr_get_childs:nx {#1} { \int_use:N \c@rowcount } \clist_map_inline:Nn \l_tblr_childs_clist { - \__tblr_text_gput:nee { vline } + \__tblr_spec_gput:nee { vline } { [##1][\int_use:N \c@colnum](\l__tblr_vline_num_tl) / @dash } { \l__tblr_vline_dash_tl } \tl_if_empty:NF \l__tblr_vline_wd_tl { - \__tblr_text_gput:nee { vline } + \__tblr_spec_gput:nee { vline } { [##1][\int_use:N \c@colnum](\l__tblr_vline_num_tl) / wd } { \l__tblr_vline_wd_tl } } \tl_if_empty:NF \l__tblr_vline_fg_tl { - \__tblr_text_gput:nee { vline } + \__tblr_spec_gput:nee { vline } { [##1][\int_use:N \c@colnum](\l__tblr_vline_num_tl) / fg } { \l__tblr_vline_fg_tl } } @@ -1440,36 +1514,41 @@ \keys_define:nn { tblr-cell-spec } { - l .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { halign } {l}, - c .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { halign } {c}, - r .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { halign } {r}, - t .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { valign} {t}, - p .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { valign} {t}, - m .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { valign} {m}, - b .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { valign} {b}, - h .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { valign} {h}, - f .code:n = \__tblr_data_gput:neenn { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { valign} {f}, - wd .code:n = \__tblr_data_gput:neene { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } { width } {#1}, - bg .code:n = \__tblr_data_gput:neene { cell } - { \int_use:N \c@rownum } { \int_use:N \c@colnum } - { background } {#1}, - preto .code:n = \__tblr_cell_preto_text:n {#1}, - appto .code:n = \__tblr_cell_appto_text:n {#1}, - fg .code:n = \__tblr_cell_preto_text:n { \color{#1} }, - font .code:n = \__tblr_cell_preto_text:n { #1 \selectfont }, + halign .code:n = \__tblr_cell_gput:nn { halign } {#1}, + valign .code:n = \__tblr_cell_gput:nn { valign } {#1}, + l .meta:n = { halign = l }, + c .meta:n = { halign = c }, + r .meta:n = { halign = r }, + t .meta:n = { valign = t }, + p .meta:n = { valign = t }, + m .meta:n = { valign = m }, + b .meta:n = { valign = b }, + h .meta:n = { valign = h }, + f .meta:n = { valign = f }, + wd .code:n = \__tblr_cell_gput:ne { width } {#1}, + bg .code:n = \__tblr_cell_gput:ne { background } {#1}, + preto .code:n = \__tblr_cell_preto_text:n {#1}, + appto .code:n = \__tblr_cell_appto_text:n {#1}, + cmd .code:n = \__tblr_cell_process_text:n {#1}, + fg .code:n = \__tblr_cell_preto_text:n { \color{#1} }, + font .code:n = \__tblr_cell_gput:nn { font } { #1 \selectfont }, unknown .code:n = \__tblr_cell_unknown_key:V \l_keys_key_str, } +\cs_new_protected:Npn \__tblr_cell_gput:nn #1 #2 + { + \__tblr_data_gput:neenn { cell } + { \int_use:N \c@rownum } { \int_use:N \c@colnum } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_cell_gput:nn { ne } + +\cs_new_protected:Npn \__tblr_cell_gput:nnnn #1 #2 #3 #4 + { + \__tblr_data_gput:nnnnn { cell } {#1} {#2} {#3} {#4} + } +\cs_generate_variant:Nn \__tblr_cell_gput:nnnn + { nenn, ennn, eenn, nene, enne, eene } + \tl_new:N \l__tblr_cell_text_tl \cs_new_protected:Npn \__tblr_cell_preto_text:n #1 @@ -1480,9 +1559,9 @@ \cs_new_protected:Npn \__tblr_cell_preto_text:nnn #1 #2 #3 { - \tl_set:Nx \l__tblr_cell_text_tl { \__tblr_text_item:nn { text } { [#1][#2] } } + \tl_set:Nx \l__tblr_cell_text_tl { \__tblr_spec_item:nn { text } { [#1][#2] } } \tl_put_left:Nn \l__tblr_cell_text_tl {#3} - \__tblr_text_gput:nnV { text } { [#1][#2] } \l__tblr_cell_text_tl + \__tblr_spec_gput:nnV { text } { [#1][#2] } \l__tblr_cell_text_tl } \cs_generate_variant:Nn \__tblr_cell_preto_text:nnn { nen, enn, een } @@ -1494,12 +1573,29 @@ \cs_new_protected:Npn \__tblr_cell_appto_text:nnn #1 #2 #3 { - \tl_set:Nx \l__tblr_cell_text_tl { \__tblr_text_item:ne { text } { [#1][#2] } } + \tl_set:Nx \l__tblr_cell_text_tl { \__tblr_spec_item:ne { text } { [#1][#2] } } \tl_put_right:Nn \l__tblr_cell_text_tl {#3} - \__tblr_text_gput:neV { text } { [#1][#2] } \l__tblr_cell_text_tl + \__tblr_spec_gput:neV { text } { [#1][#2] } \l__tblr_cell_text_tl } \cs_generate_variant:Nn \__tblr_cell_appto_text:nnn { nen, enn, een } +\cs_new_protected:Npn \__tblr_cell_process_text:n #1 + { + \__tblr_cell_process_text:een + { \int_use:N \c@rownum } { \int_use:N \c@colnum } {#1} + } + +\cs_new_protected:Npn \__tblr_cell_process_text:nnn #1 #2 #3 + { + \tl_set:Nx \l__tblr_cell_text_tl + { + { \__tblr_spec_item:nn { text } { [#1][#2] } } + } + \tl_put_left:Nn \l__tblr_cell_text_tl {#3} + \__tblr_spec_gput:nnV { text } { [#1][#2] } \l__tblr_cell_text_tl + } +\cs_generate_variant:Nn \__tblr_cell_process_text:nnn { nen, enn, een } + \cs_new_protected:Npn \__tblr_cell_unknown_key:n #1 { \regex_match:NnTF \c__tblr_is_color_key_regex {#1} @@ -1520,13 +1616,13 @@ { \int_compare:nNnT { #1 } > { 1 } { - \__tblr_prop_gput:nnn {table} {rowspan} {true} + \__tblr_prop_gput:nnn { inner } { rowspan } { true } \__tblr_data_gput:neenn { cell } { \int_use:N \c@rownum } { \int_use:N \c@colnum } { rowspan } {#1} } \int_compare:nNnT { #2 } > { 1 } { - \__tblr_prop_gput:nnn {table} {colspan} {true} + \__tblr_prop_gput:nnn { inner } { colspan } { true } \__tblr_data_gput:neenn { cell } { \int_use:N \c@rownum } { \int_use:N \c@colnum } { colspan } {#2} } @@ -1546,12 +1642,12 @@ } \int_compare:nNnF { \l__tblr_i_tl } = { \c@rownum } { - \__tblr_text_gput:nen { hline } + \__tblr_spec_gput:nen { hline } { [\l__tblr_i_tl][\l__tblr_j_tl] / omit } {true} } \int_compare:nNnF { \l__tblr_j_tl } = { \c@colnum } { - \__tblr_text_gput:nee { vline } + \__tblr_spec_gput:nee { vline } { [\l__tblr_i_tl][\l__tblr_j_tl] / omit } {true} } } @@ -1678,53 +1774,59 @@ \keys_define:nn { tblr-column } { - l .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { halign } {l}, - c .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { halign } {c}, - r .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { halign } {r}, - t .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { valign } {t}, - p .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { valign } {t}, - m .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { valign } {m}, - b .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { valign } {b}, - h .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { valign } {h}, - f .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { valign } {f}, - bg .code:n = \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { background } {#1}, - fg .code:n = \__tblr_preto_text_for_every_column_cell:n { \color{#1} }, - font .code:n = \__tblr_preto_text_for_every_column_cell:n { #1 \selectfont }, - wd .code:n = \__tblr_data_gput:nene { column } - { \int_use:N \c@colnum } { width } { \dim_eval:n {#1} }, - co .code:n = \__tblr_data_gput:nene { column } - { \int_use:N \c@colnum } { coefficient } {#1}, - leftsep .code:n = \__tblr_data_gput:nene { column } - { \int_use:N \c@colnum } { leftsep } { \dim_eval:n {#1} }, - rightsep .code:n = \__tblr_data_gput:nene { column } - { \int_use:N \c@colnum } { rightsep } { \dim_eval:n {#1} }, - colsep .meta:n = { leftsep = #1, rightsep = #1}, - leftsep+ .code:n = \__tblr_data_gadd_dimen_value:nene { column } - { \int_use:N \c@colnum } { leftsep } { \dim_eval:n {#1} }, - rightsep+ .code:n = \__tblr_data_gadd_dimen_value:nene { column } - { \int_use:N \c@colnum } { rightsep } { \dim_eval:n {#1} }, - colsep+ .meta:n = { leftsep+ = #1, rightsep+ = #1}, - unknown .code:n = \__tblr_column_unknown_key:V \l_keys_key_str, - } - -%% #1: column number; #2: key; #3: value -\cs_new_protected:Npn \__tblr_set_key_for_every_column_cell:nnn #1 #2 #3 + halign .code:n = \__tblr_column_gput_cell:nn { halign } {#1}, + valign .code:n = \__tblr_column_gput_cell:nn { valign } {#1}, + l .meta:n = { halign = l }, + c .meta:n = { halign = c }, + r .meta:n = { halign = r }, + t .meta:n = { valign = t }, + p .meta:n = { valign = t }, + m .meta:n = { valign = m }, + b .meta:n = { valign = b }, + h .meta:n = { valign = h }, + f .meta:n = { valign = f }, + bg .code:n = \__tblr_column_gput_cell:nn { background } {#1}, + fg .code:n = \__tblr_preto_text_for_every_column_cell:n { \color{#1} }, + font .code:n = \__tblr_column_gput_cell:nn { font } { #1 \selectfont }, + wd .code:n = \__tblr_column_gput:ne { width } { \dim_eval:n {#1} }, + co .code:n = \__tblr_column_gput:ne { coefficient } {#1}, + preto .code:n = \__tblr_preto_text_for_every_column_cell:n {#1}, + appto .code:n = \__tblr_appto_text_for_every_column_cell:n {#1}, + cmd .code:n = \__tblr_process_text_for_every_column_cell:n {#1}, + leftsep .code:n = \__tblr_column_gput:ne { leftsep } { \dim_eval:n {#1} }, + rightsep .code:n = \__tblr_column_gput:ne { rightsep } { \dim_eval:n {#1} }, + colsep .meta:n = { leftsep = #1, rightsep = #1}, + leftsep+ .code:n = \__tblr_column_gadd_dimen:ne + { leftsep } { \dim_eval:n {#1} }, + rightsep+ .code:n = \__tblr_column_gadd_dimen:ne + { rightsep } { \dim_eval:n {#1} }, + colsep+ .meta:n = { leftsep+ = #1, rightsep+ = #1}, + unknown .code:n = \__tblr_column_unknown_key:V \l_keys_key_str, + } + +%% #1: key; #2: value +\cs_new_protected:Npn \__tblr_column_gput:nn #1 #2 + { + \__tblr_data_gput:nenn { column } { \int_use:N \c@colnum } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_column_gput:nn { ne } + +\cs_new_protected:Npn \__tblr_column_gadd_dimen:nn #1 #2 + { + \__tblr_data_gadd_dimen_value:nenn { column } + { \int_use:N \c@colnum } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_column_gadd_dimen:nn { ne } + +%% #1: key; #2: value +\cs_new_protected:Npn \__tblr_column_gput_cell:nn #1 #2 { \int_step_inline:nn { \c@rowcount } { - \__tblr_data_gput:neenn { cell } {##1} {#1} {#2} {#3} + \__tblr_cell_gput:nenn {##1} { \int_use:N \c@colnum } {#1} {#2} } } +\cs_generate_variant:Nn \__tblr_column_gput_cell:nn { ne } \cs_new_protected:Npn \__tblr_preto_text_for_every_column_cell:n #1 { @@ -1742,25 +1844,26 @@ } } +\cs_new_protected:Npn \__tblr_process_text_for_every_column_cell:n #1 + { + \int_step_inline:nn { \c@rowcount } + { + \__tblr_cell_process_text:nen {##1} { \int_use:N \c@colnum } {#1} + } + } + \regex_const:Nn \c__tblr_is_number_key_regex { ^[\+\-]? (\d+|\d*\.\d+)$ } \cs_new_protected:Npn \__tblr_column_unknown_key:n #1 { \regex_match:NnTF \c__tblr_is_number_key_regex {#1} - { - \__tblr_data_gput:nene { column } - { \int_use:N \c@colnum } { coefficient } {#1} - } + { \__tblr_column_gput:ne { coefficient } {#1} } { \regex_match:NnTF \c__tblr_is_color_key_regex {#1} - { - \__tblr_set_key_for_every_column_cell:nnn - { \int_use:N \c@colnum } { background } {#1} - } + { \__tblr_column_gput_cell:nn { background } {#1} } { \tl_set_rescan:Nnn \l__tblr_v_tl {} {#1} - \__tblr_data_gput:nene { column } - { \int_use:N \c@colnum } { width } { \dim_eval:n { \l__tblr_v_tl } } + \__tblr_column_gput:ne { width } { \dim_eval:n { \l__tblr_v_tl } } } } } @@ -1830,55 +1933,58 @@ \keys_define:nn { tblr-row } { - l .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { halign } {l}, - c .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { halign } {c}, - r .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { halign } {r}, - t .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { valign } {t}, - p .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { valign } {t}, - m .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { valign } {m}, - b .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { valign } {b}, - h .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { valign } {h}, - f .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { valign } {f}, - bg .code:n = \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { background } {#1}, - fg .code:n = \__tblr_preto_text_for_every_row_cell:n { \color{#1} }, - font .code:n = \__tblr_preto_text_for_every_row_cell:n { #1 \selectfont }, - ht .code:n = \__tblr_data_gput:nene { row } { \int_use:N \c@rownum } - { height } { \dim_eval:n {#1} }, - co .code:n = \__tblr_data_gput:nene { row } { \int_use:N \c@rownum } - { coefficient } {#1}, - abovesep .code:n = \__tblr_data_gput:nene { row } { \int_use:N \c@rownum } - { abovesep } { \dim_eval:n {#1} }, - belowsep .code:n = \__tblr_data_gput:nene { row } { \int_use:N \c@rownum } - { belowsep } { \dim_eval:n {#1} }, - rowsep .meta:n = { abovesep = #1, belowsep = #1}, - abovesep+ .code:n = \__tblr_data_gadd_dimen_value:nene { row } - { \int_use:N \c@rownum } { abovesep } { \dim_eval:n {#1} }, - belowsep+ .code:n = \__tblr_data_gadd_dimen_value:nene { row } - { \int_use:N \c@rownum } { belowsep } { \dim_eval:n {#1} }, - rowsep+ .meta:n = { abovesep+ = #1, belowsep+ = #1}, - nobreak .code:n = \__tblr_prop_gput:nxx { row } - { [\int_eval:n {\c@rownum - 1}] / nobreak } { true }, - unknown .code:n = \__tblr_row_unknown_key:V \l_keys_key_str, - } - -%% #1: row number; #2: key; #3: value -\cs_new_protected:Npn \__tblr_set_key_for_every_row_cell:nnn #1 #2 #3 + halign .code:n = \__tblr_row_gput_cell:nn { halign } {#1}, + valign .code:n = \__tblr_row_gput_cell:nn { valign } {#1}, + l .meta:n = { halign = l }, + c .meta:n = { halign = c }, + r .meta:n = { halign = r }, + t .meta:n = { valign = t }, + p .meta:n = { valign = t }, + m .meta:n = { valign = m }, + b .meta:n = { valign = b }, + h .meta:n = { valign = h }, + f .meta:n = { valign = f }, + bg .code:n = \__tblr_row_gput_cell:nn { background } {#1}, + fg .code:n = \__tblr_preto_text_for_every_row_cell:n { \color{#1} }, + font .code:n = \__tblr_row_gput_cell:nn { font } { #1 \selectfont }, + ht .code:n = \__tblr_row_gput:ne { height } { \dim_eval:n {#1} }, + co .code:n = \__tblr_row_gput:ne { coefficient } {#1}, + preto .code:n = \__tblr_preto_text_for_every_row_cell:n {#1}, + appto .code:n = \__tblr_appto_text_for_every_row_cell:n {#1}, + cmd .code:n = \__tblr_process_text_for_every_row_cell:n {#1}, + abovesep .code:n = \__tblr_row_gput:ne { abovesep } { \dim_eval:n {#1} }, + belowsep .code:n = \__tblr_row_gput:ne { belowsep } { \dim_eval:n {#1} }, + rowsep .meta:n = { abovesep = #1, belowsep = #1}, + abovesep+ .code:n = \__tblr_row_gadd_dimen:ne { abovesep } { \dim_eval:n {#1} }, + belowsep+ .code:n = \__tblr_row_gadd_dimen:ne { belowsep } { \dim_eval:n {#1} }, + rowsep+ .meta:n = { abovesep+ = #1, belowsep+ = #1}, + nobreak .code:n = \__tblr_prop_gput:nxx { row } + { [\int_eval:n {\c@rownum - 1}] / nobreak } { true }, + unknown .code:n = \__tblr_row_unknown_key:V \l_keys_key_str, + } + +%% #1: key; #2: value +\cs_new_protected:Npn \__tblr_row_gput:nn #1 #2 + { + \__tblr_data_gput:nenn { row } { \int_use:N \c@rownum } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_row_gput:nn { ne } + +\cs_new_protected:Npn \__tblr_row_gadd_dimen:nn #1 #2 + { + \__tblr_data_gadd_dimen_value:nenn { row } { \int_use:N \c@rownum } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_row_gadd_dimen:nn { ne } + +%% #1: key; #2: value +\cs_new_protected:Npn \__tblr_row_gput_cell:nn #1 #2 { \int_step_inline:nn { \c@colcount } { - \__tblr_data_gput:neenn { cell } {#1} {##1} {#2} {#3} + \__tblr_cell_gput:ennn { \int_use:N \c@rownum } {##1} {#1} {#2} } } +\cs_generate_variant:Nn \__tblr_row_gput_cell:nn { ne } \cs_new_protected:Npn \__tblr_preto_text_for_every_row_cell:n #1 { @@ -1896,6 +2002,14 @@ } } +\cs_new_protected:Npn \__tblr_process_text_for_every_row_cell:n #1 + { + \int_step_inline:nn { \c@colcount } + { + \__tblr_cell_process_text:enn { \int_use:N \c@rownum } {##1} {#1} + } + } + \cs_new_protected:Npn \__tblr_row_unknown_key:n #1 { \regex_match:NnTF \c__tblr_is_number_key_regex {#1} @@ -1905,14 +2019,10 @@ } { \regex_match:NnTF \c__tblr_is_color_key_regex {#1} + { \__tblr_row_gput_cell:nn { background } {#1} } { - \__tblr_set_key_for_every_row_cell:nnn - { \int_use:N \c@rownum } { background } {#1} - } - { - \tl_set_rescan:Nnn \l__tblr_v_tl {} {#1} - \__tblr_data_gput:nene { row } { \int_use:N \c@rownum } - { height } { \dim_eval:n { \l__tblr_v_tl } } + \tl_set_rescan:Nnn \l__tblr_v_tl {} {#1} + \__tblr_row_gput:ne { height } { \dim_eval:n { \l__tblr_v_tl } } } } } @@ -2205,43 +2315,100 @@ } %%% -------------------------------------------------------- -%% \section{Tabularray Environments} +%% \section{Set Environments and New Environments} %%% -------------------------------------------------------- +\tl_new:N \l__tblr_initial_tblr_outer_tl +\tl_set:Nn \l__tblr_initial_tblr_outer_tl + { + halign = c, valign = m, headsep = 6pt, footsep = 6pt, + presep = 1.5\bigskipamount, postsep = 1.5\bigskipamount, + } + +%% #1: env name; #2: specifications +\NewDocumentCommand \SetTblrInner { O{tblr} m } + { + \tl_put_right:cn { l__tblr_default_ #1 _inner_tl } { , #2 } + \ignorespaces + } +\cs_new_eq:NN \SetTblrDefault \SetTblrInner + +%% #1: env name; #2: specifications +\NewDocumentCommand \SetTblrOuter { O{tblr} m } + { + \tl_put_right:cn { l__tblr_default_ #1 _outer_tl } { , #2 } + \ignorespaces + } + +%% #1: env name +\NewDocumentCommand \NewTblrEnviron { m } + { + \tl_new:c { l__tblr_default_ #1 _outer_tl } + \tl_set_eq:cN { l__tblr_default_ #1 _outer_tl } \l__tblr_initial_tblr_outer_tl + \tl_new:c { l__tblr_default_ #1 _inner_tl } + \NewDocumentEnvironment {#1} { O{c} m +b } + { + \__tblr_environ_code:nnnn {#1} {##1} {##2} {##3} + } { } + \ignorespaces + } + +%% Create tblr and longtblr environments +\NewTblrEnviron { tblr } +\NewTblrEnviron { longtblr } +\SetTblrOuter [ longtblr ] { long } + \tl_new:N \l__tblr_env_name_tl \bool_new:N \l__tblr_math_mode_bool -\NewDocumentEnvironment { tblr } { O{c} m +b } +%% Main environment code +\cs_new_protected:Npn \__tblr_environ_code:nnnn #1 #2 #3 #4 { - \tl_set:Nn \l__tblr_env_name_tl { tblr } + \int_gincr:N \g__tblr_table_count_int + \tl_set:Nn \l__tblr_env_name_tl {#1} \mode_if_math:TF { \bool_set_true:N \l__tblr_math_mode_bool } { \bool_set_false:N \l__tblr_math_mode_bool } - \buildtblr {#1} {#2} {#3} - } { } + \__tblr_builder:nnn {#2} {#3} {#4} + } %% Read, split and build the table - -\cs_new_protected:Npn \buildtblr #1 #2 #3 +\cs_new_protected:Npn \__tblr_builder:nnn #1 #2 #3 { - \mode_leave_vertical: \int_gincr:N \g_tblr_level_int \__tblr_clear_prop_lists: - \__tblr_clear_text_lists: + \__tblr_clear_spec_lists: \__tblr_enable_table_commands: - \__tblr_split_table:n { #3 } + \LogTblrTracing { step = split ~ table} + \__tblr_split_table:n {#3} \LogTblrTracing { command } - \bool_if:NT \g__tblr_use_intarray_bool { \__tblr_initial_table_data: } - \__tblr_initial_table_spec: - \LogTblrTracing { table } - \__tblr_parse_table_spec:n { #2 } + \LogTblrTracing { step = init ~ table ~ outer ~ spec} + \__tblr_init_table_outer_spec: + \LogTblrTracing { outer } + \LogTblrTracing { step = parse ~ table ~ options } + \__tblr_parse_table_option:n {#1} + \LogTblrTracing { option } + \bool_if:NT \g__tblr_use_intarray_bool { \__tblr_init_table_data: } + \LogTblrTracing { step = init ~ table ~ inner ~ spec} + \__tblr_init_table_inner_spec: + \LogTblrTracing { inner } + \LogTblrTracing { step = parse ~ table ~ inner ~ spec} + \__tblr_parse_table_spec:n {#2} + \LogTblrTracing { step = execute ~ table ~ commands} \__tblr_execute_table_commands: \__tblr_disable_table_commands: + \LogTblrTracing { step = calculate ~ cell ~ and ~ line ~ sizes} + \__tblr_enable_content_commands: \__tblr_calc_cell_and_line_sizes: - \__tblr_build_whole:n { #1 } + \LogTblrTracing { step = build ~ the ~ whole ~ table} + \__tblr_build_whole: \int_gdecr:N \g_tblr_level_int } +%%% -------------------------------------------------------- +%% \section{Split Table Contents} +%%% -------------------------------------------------------- + %% Insert and remove braces for nesting environments inside cells %% These make line split and cell split workable %% We need to replace N times for N level nestings @@ -2348,7 +2515,7 @@ \__tblr_remove_braces:N \l_tmpa_tl \int_incr:N \c@colnum \__tblr_extract_table_commands:N \l_tmpa_tl - \__tblr_text_gput:neV { text } { [#1][\int_use:N \c@colnum] } \l_tmpa_tl + \__tblr_spec_gput:neV { text } { [#1][\int_use:N \c@colnum] } \l_tmpa_tl \__tblr_add_multicolumn_empty_cell: } %% Decrease row count by 1 if the last row has only one empty cell text @@ -2373,7 +2540,7 @@ \int_step_inline:nn { \l__multicolumn_cell_number_int - 1 } { \int_incr:N \c@colnum - \__tblr_text_gput:nen { text } + \__tblr_spec_gput:nen { text } { [\int_use:N \c@rownum][\int_use:N \c@colnum] } { } } } @@ -2395,7 +2562,7 @@ \tl_clear:N \l__tblr_saved_table_commands_before_cell_text_tl \tl_clear:N \l__tblr_saved_cell_text_after_table_commands_tl \int_set:Nn \l__multicolumn_cell_number_int {1} - \exp_last_unbraced:NV \__tblr_extract_table_commands_next:w #1 \scan_stop: + \exp_last_unbraced:NV \__tblr_extract_table_commands_next:w #1 \q_stop \tl_if_empty:NF \l__tblr_saved_table_commands_before_cell_text_tl { \__tblr_prop_gput:nxV { command } @@ -2420,7 +2587,7 @@ { \tl_if_single_token:nTF {#1} { - \token_if_eq_meaning:NNF #1 \scan_stop: + \token_if_eq_meaning:NNF #1 \q_stop { \__tblr_save_real_cell_text:w #1 } } { \__tblr_save_real_cell_text:w {#1} } @@ -2477,22 +2644,22 @@ \cs_new_protected:Npn \__tblr_last_unbraced:Nn #1 #2 { #1 #2 } %% The outermost set of braces of cell text #1 will be removed -\cs_new_protected:Npn \__tblr_save_real_cell_text:w #1 \scan_stop: +\cs_new_protected:Npn \__tblr_save_real_cell_text:w #1 \q_stop { \tl_set:Nn \l__tblr_saved_cell_text_after_table_commands_tl {#1} } %%% -------------------------------------------------------- -%% \section{Initial Table Specifications} +%% \section{Initialize Table Inner Specifications} %%% -------------------------------------------------------- -\prop_gset_from_keyval:Nn \g__tblr_default_tblr_table_prop +\prop_gset_from_keyval:Nn \g__tblr_initial_table_prop { stretch = 1, rulesep = 2pt, } -\prop_gset_from_keyval:Nn \g__tblr_default_tblr_rows_prop +\prop_gset_from_keyval:Nn \g__tblr_initial_rows_prop { abovesep = 2pt, belowsep = 2pt, @@ -2503,7 +2670,7 @@ @row-lower = 0pt, } -\prop_gset_from_keyval:Nn \g__tblr_default_tblr_columns_prop +\prop_gset_from_keyval:Nn \g__tblr_initial_columns_prop { leftsep = 6pt, rightsep = 6pt, @@ -2512,7 +2679,7 @@ @col-width = 0pt, } -\prop_gset_from_keyval:Nn \g__tblr_default_tblr_cells_prop +\prop_gset_from_keyval:Nn \g__tblr_initial_cells_prop { halign = l, valign = t, @@ -2522,96 +2689,85 @@ omit = 0, } -\prop_gset_from_keyval:Nn \g__tblr_default_tblr_hlines_prop +\prop_gset_from_keyval:Nn \g__tblr_initial_hlines_prop { @hline-count = 0, } -\prop_gset_from_keyval:Nn \g__tblr_default_tblr_vlines_prop +\prop_gset_from_keyval:Nn \g__tblr_initial_vlines_prop { @vline-count = 0, } -\cs_new_protected:Npn \__tblr_initial_table_spec: +\cs_new_protected:Npn \__tblr_init_table_inner_spec: { - \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _table_prop } + \prop_map_inline:Nn \g__tblr_initial_table_prop { - \__tblr_prop_gput:nxn { table } { ##1 } {##2} + \__tblr_prop_gput:nxn { inner } { ##1 } {##2} } \int_step_variable:nNn { \c@rowcount } \l__tblr_i_tl { - \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _rows_prop } + \prop_map_inline:Nn \g__tblr_initial_rows_prop { \__tblr_data_gput:nVnn { row } \l__tblr_i_tl {##1} {##2} } - \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _hlines_prop } + \prop_map_inline:Nn \g__tblr_initial_hlines_prop { - \__tblr_text_gput:nen { hline } { [\l__tblr_i_tl] / ##1 } {##2} + \__tblr_spec_gput:nen { hline } { [\l__tblr_i_tl] / ##1 } {##2} } \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl { - \prop_map_inline:cn - { g__tblr_default_ \l__tblr_env_name_tl _cells_prop } + \prop_map_inline:Nn \g__tblr_initial_cells_prop { \__tblr_data_gput:neeen { cell } { \l__tblr_i_tl } { \l__tblr_j_tl } {##1} {##2} } } } - \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _hlines_prop } + \prop_map_inline:Nn \g__tblr_initial_hlines_prop { - \__tblr_text_gput:nen { hline } + \__tblr_spec_gput:nen { hline } { [\int_eval:n { \c@rowcount + 1}] / ##1 } {##2} } \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl { - \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _columns_prop } + \prop_map_inline:Nn \g__tblr_initial_columns_prop { \__tblr_data_gput:nenn { column } { \l__tblr_j_tl } {##1} {##2} } - \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _vlines_prop } + \prop_map_inline:Nn \g__tblr_initial_vlines_prop { - \__tblr_text_gput:nen { vline } { [\l__tblr_j_tl] / ##1 } {##2} + \__tblr_spec_gput:nen { vline } { [\l__tblr_j_tl] / ##1 } {##2} } } - \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _vlines_prop } + \prop_map_inline:Nn \g__tblr_initial_vlines_prop { - \__tblr_text_gput:nen { vline } + \__tblr_spec_gput:nen { vline } { [\int_eval:n { \c@colcount + 1}] / ##1 } {##2} } - \keys_set:nv { tblr } { l__tblr_default_ \l__tblr_env_name_tl _tl } + \keys_set:nv { tblr } { l__tblr_default_ \l__tblr_env_name_tl _inner_tl } } -\tl_new:N \l__tblr_default_tblr_tl - -%% #1: env name; #2: options -\NewDocumentCommand \SetTabularrayDefault { O{tblr} m } - { - \tl_put_right:cn { l__tblr_default_ #1 _tl } { , #2 } - } -\cs_new_eq:NN \SetTblrDefault \SetTabularrayDefault - %%% -------------------------------------------------------- -%% \section{Parse Table Specifications} +%%> \section{Parse Table Inner Specifications} %%% -------------------------------------------------------- \clist_new:N \g__tblr_table_known_keys_clist \clist_gset:Nn \g__tblr_table_known_keys_clist { - long, colspec, rowspec, width, hspan, stretch, + colspec, rowspec, width, hspan, vspan, stretch, column, row, cell, vline, hline, columns, rows, cells, vlines, hlines, leftsep, rightsep, colsep, abovesep, belowsep, rowsep, rulesep, + rowhead, rowfoot, } -\bool_new:N \l__tblr_long_table_bool - \keys_define:nn { tblr } { - long .bool_set:N = \l__tblr_long_table_bool, colspec .code:n = \__tblr_parse_colrow_spec:nn { column } {#1}, rowspec .code:n = \__tblr_parse_colrow_spec:nn { row } {#1}, width .code:n = \__tblr_keys_gput:nx { width } { \dim_eval:n {#1} }, hspan .code:n = \__tblr_keys_gput:nn { hspan } {#1}, + vspan .code:n = \__tblr_keys_gput:nn { vspan } {#1}, stretch .code:n = \__tblr_keys_gput:nn { stretch } {#1}, columns .code:n = \__tblr_set_every_column_aux:n {#1}, rows .code:n = \__tblr_set_every_row_aux:n {#1}, @@ -2625,6 +2781,8 @@ belowsep .code:n = \tblr_set_every_row:nn { } { belowsep = #1 }, rowsep .meta:n = { abovesep = #1, belowsep = #1 }, rulesep .code:n = \__tblr_keys_gput:nn { rulesep } {#1}, + rowhead .code:n = \__tblr_keys_gput:nn { rowhead } {#1}, + rowfoot .code:n = \__tblr_keys_gput:nn { rowfoot } {#1}, unknown .code:n = \__tblr_table_special_key:Vn \l_keys_key_str {#1}, } @@ -2658,13 +2816,106 @@ { \__tblr_parse_colrow_spec:nn { column } {#1} } } -\cs_new_protected:Npn \__tblr_keys_gput:nn #1 #2 +\cs_new_protected:Npn \__tblr_keys_gput:nn #1 #2 { - \__tblr_prop_gput:nnn { table } {#1} {#2} + \__tblr_prop_gput:nnn { inner } {#1} {#2} } \cs_generate_variant:Nn \__tblr_keys_gput:nn { nx } %%% -------------------------------------------------------- +%% \section{Initialize and Parse Table Outer Specifications} +%%% -------------------------------------------------------- + +%% #1: theme names; #2: template and style commands +\NewDocumentCommand \NewTblrTheme { m +m } + { + \tl_set:cn { g__tblr_theme_ #1 _code_tl } {#2} + \ignorespaces + } + +\cs_new_protected:Npn \__tblr_use_theme:n #1 + { + \ignorespaces + \tl_use:c { g__tblr_theme_ #1 _code_tl } + } + +\cs_new_protected:Npn \__tblr_init_table_outer_spec: + { + \keys_set:nv { tblr-outer } { l__tblr_default_ \l__tblr_env_name_tl _outer_tl } + } + +\cs_new_protected:Npn \__tblr_parse_table_option:n #1 + { + \keys_set:nn { tblr-outer } {#1} + } + +\keys_define:nn { tblr-outer } + { + long .code:n = \__tblr_outer_gput_spec:nn { long } {true}, + halign .code:n = \__tblr_outer_gput_spec:nn { halign } {#1}, + valign .code:n = \__tblr_outer_gput_spec:nn { valign } {#1}, + l .meta:n = { halign = l }, + c .meta:n = { halign = c }, + r .meta:n = { halign = r }, + t .meta:n = { valign = t }, + m .meta:n = { valign = m }, + b .meta:n = { valign = b }, + headsep .code:n = \__tblr_outer_gput_spec:nn { headsep } {#1}, + footsep .code:n = \__tblr_outer_gput_spec:nn { footsep } {#1}, + presep .code:n = \__tblr_outer_gput_spec:nn { presep } {#1}, + postsep .code:n = \__tblr_outer_gput_spec:nn { postsep } {#1}, + theme .code:n = \__tblr_use_theme:n {#1}, + caption .code:n = \__tblr_outer_gput_spec:nn { caption } {#1}, + entry .code:n = \__tblr_outer_gput_spec:nn { entry } {#1}, + label .code:n = \__tblr_outer_gput_spec:nn { label } {#1}, + unknown .code:n = \__tblr_table_option_key:Vn \l_keys_key_str {#1}, + } + +\cs_new_protected:Npn \__tblr_outer_gput_spec:nn #1 #2 + { + \__tblr_spec_gput:nen { outer } {#1} {#2} + } + +\regex_const:Nn \c__tblr_option_key_name_regex { ^ [A-Za-z\-] + $ } + +\msg_new:nnn { tabularray } { unknown-outer-key } + { Unknown ~ outer ~ key ~ name ~ #1! } + +\cs_new_protected:Npn \__tblr_table_option_key:nn #1 #2 + { + \regex_match:NnTF \c__tblr_option_key_name_regex {#1} + { \msg_error:nnn { tabularray } { unknown-outer-key } {#1} } + { + \regex_extract_once:NnNT \c__tblr_split_key_name_regex {#1} \l_tmpa_seq + { + \tl_set:Nx \l__tblr_a_tl { \seq_item:Nn \l_tmpa_seq {2} } + \tl_set_rescan:Nnx \l__tblr_b_tl {} { \seq_item:Nn \l_tmpa_seq {3} } + \tl_set:Nx \l__tblr_c_tl { \tl_head:N \l__tblr_b_tl } + \use:c { __tblr_outer_gput_ \l__tblr_a_tl :Vn } \l__tblr_c_tl {#2} + } + } + } +\cs_generate_variant:Nn \__tblr_table_option_key:nn { Vn } + +\cs_new_protected:Npn \__tblr_outer_gput_note:nn #1 #2 + { + \__tblr_prop_gput:nnn { note } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_outer_gput_note:nn { Vn } + +\cs_new_protected:Npn \__tblr_outer_gput_remark:nn #1 #2 + { + \__tblr_prop_gput:nnn { remark } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_outer_gput_remark:nn { Vn } + +\cs_new_protected:Npn \__tblr_outer_gput_more:nn #1 #2 + { + \__tblr_prop_gput:nnn { more } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_outer_gput_more:nn { Vn } + +%%% -------------------------------------------------------- %% \section{Typeset and Calculate Sizes} %%% -------------------------------------------------------- @@ -2687,7 +2938,7 @@ \cs_new_protected:Npn \__tblr_make_strut_box: { - \tl_set:Nx \l__tblr_s_tl { \__tblr_prop_item:ne { table } { stretch } } + \tl_set:Nx \l__tblr_s_tl { \__tblr_prop_item:ne { inner } { stretch } } \hbox_set:Nn \l__tblr_strut_ht_box { \vrule height \l__tblr_s_tl \box_ht:N \strutbox width ~ 0pt } \hbox_set:Nn \l__tblr_strut_dp_box @@ -2725,11 +2976,11 @@ { \dim_zero:N \l__tblr_w_dim \tl_set:Nx \l__tblr_n_tl - { \__tblr_text_item:ne { vline } { [#2] / @vline-count } } + { \__tblr_spec_item:ne { vline } { [#2] / @vline-count } } \int_compare:nNnT { \l__tblr_n_tl } > {0} { \tl_set:Nx \l__tblr_s_tl - { \__tblr_prop_item:ne { table } { rulesep } } + { \__tblr_prop_item:ne { inner } { rulesep } } \int_step_inline:nn { \l__tblr_n_tl } { \vbox_set_to_ht:Nnn \l__tblr_b_box {1pt} @@ -2738,14 +2989,14 @@ {#1} {#2} {##1} {1pt} {1pt} } \tl_set:Nx \l__tblr_w_tl { \dim_eval:n { \box_wd:N \l__tblr_b_box } } - \__tblr_text_gput_if_larger:nee { vline } + \__tblr_spec_gput_if_larger:nee { vline } { [#2](##1) / @vline-width } { \l__tblr_w_tl } \dim_add:Nn \l__tblr_w_dim { \l__tblr_w_tl } \dim_add:Nn \l__tblr_w_dim { \l__tblr_s_tl } } \dim_add:Nn \l__tblr_w_dim { - \l__tblr_s_tl } } - \__tblr_text_gput_if_larger:nee { vline } + \__tblr_spec_gput_if_larger:nee { vline } { [#2]/ @vline-width } { \dim_use:N \l__tblr_w_dim } } @@ -2756,10 +3007,10 @@ { \group_begin: \tl_set:Nx \l__tblr_w_tl - { \__tblr_text_item:ne { vline } { [#1][#2](#3) / wd } } + { \__tblr_spec_item:ne { vline } { [#1][#2](#3) / wd } } \tl_if_empty:NF \l__tblr_w_tl { \dim_set:Nn \rulewidth { \l__tblr_w_tl } } \tl_set:Nx \l__tblr_d_tl - { \__tblr_text_item:ne { vline } { [#1][#2](#3) / @dash } } + { \__tblr_spec_item:ne { vline } { [#1][#2](#3) / @dash } } \tl_set:Nx \l__tblr_a_tl { \tl_head:N \l__tblr_d_tl } \tl_set:Nx \l__tblr_b_tl { \tl_tail:N \l__tblr_d_tl } \exp_args:NV \tl_if_eq:NNTF \l__tblr_a_tl \@tblr@dash @@ -2783,11 +3034,11 @@ { \dim_zero:N \l__tblr_h_dim \tl_set:Nx \l__tblr_n_tl - { \__tblr_text_item:ne { hline } { [#1] / @hline-count } } + { \__tblr_spec_item:ne { hline } { [#1] / @hline-count } } \int_compare:nNnT { \l__tblr_n_tl } > {0} { \tl_set:Nx \l__tblr_s_tl - { \__tblr_prop_item:ne { table } { rulesep } } + { \__tblr_prop_item:ne { inner } { rulesep } } \int_step_inline:nn { \l__tblr_n_tl } { \hbox_set_to_wd:Nnn \l__tblr_b_box {1pt} @@ -2797,14 +3048,14 @@ \dim_eval:n { \box_ht:N \l__tblr_b_box + \box_dp:N \l__tblr_b_box } } - \__tblr_text_gput_if_larger:nee { hline } + \__tblr_spec_gput_if_larger:nee { hline } { [#1](##1) / @hline-height } { \l__tblr_h_tl } \dim_add:Nn \l__tblr_h_dim { \l__tblr_h_tl } \dim_add:Nn \l__tblr_h_dim { \l__tblr_s_tl } } \dim_add:Nn \l__tblr_h_dim { - \l__tblr_s_tl } } - \__tblr_text_gput_if_larger:nee { hline } + \__tblr_spec_gput_if_larger:nee { hline } { [#1] / @hline-height } { \dim_use:N \l__tblr_h_dim } } @@ -2814,10 +3065,10 @@ { \group_begin: \tl_set:Nx \l__tblr_w_tl - { \__tblr_text_item:ne { hline } { [#1][#2](#3) / wd } } + { \__tblr_spec_item:ne { hline } { [#1][#2](#3) / wd } } \tl_if_empty:NF \l__tblr_w_tl { \dim_set:Nn \rulewidth { \l__tblr_w_tl } } \tl_set:Nx \l__tblr_d_tl - { \__tblr_text_item:ne { hline } { [#1][#2](#3) / @dash } } + { \__tblr_spec_item:ne { hline } { [#1][#2](#3) / @dash } } \tl_set:Nx \l__tblr_a_tl { \tl_head:N \l__tblr_d_tl } \tl_set:Nx \l__tblr_b_tl { \tl_tail:N \l__tblr_d_tl } \exp_args:NV \tl_if_eq:NNTF \l__tblr_a_tl \@tblr@dash @@ -2893,9 +3144,11 @@ { \int_incr:N \c@rownum \int_zero:N \c@colnum + \__tblr_update_rowsep_registers: \tl_set:Nx \l__tblr_h_tl - { \__tblr_data_item:nen { row } { \int_use:N \c@rownum } { height } } - \tl_if_empty:NF \l__tblr_h_tl + { \__tblr_data_item:nen { row } { \int_use:N \c@rownum } { height } } + %% We didn't initialize row heights with -1pt + \dim_compare:nNnF { \l__tblr_h_tl } = { 0pt } { \__tblr_data_gput:nenV { row } { \int_use:N \c@rownum } { @row-height } \l__tblr_h_tl @@ -2903,6 +3156,7 @@ \int_step_inline:nn { \c@colcount } { \int_incr:N \c@colnum + \__tblr_update_colsep_registers: \__tblr_measure_cell_update_sizes:nnNNNN { \int_use:N \c@rownum } { \int_use:N \c@colnum } @@ -2912,6 +3166,31 @@ \g__tblr_cell_foot_dim } } + \int_step_inline:nn { \c@colcount } + { + \tl_set:Nx \l__tblr_w_tl + { \__tblr_data_item:nen { column } {##1} { width } } + \dim_compare:nNnF { \l__tblr_w_tl } < { 0pt } + { + \__tblr_data_gput:nenV { column } {##1} { @col-width } \l__tblr_w_tl + } + } + } + +\cs_new_protected:Npn \__tblr_update_rowsep_registers: + { + \dim_set:Nn \abovesep + { \__tblr_data_item:nen { row } { \int_use:N \c@rownum } { abovesep } } + \dim_set:Nn \belowsep + { \__tblr_data_item:nen { row } { \int_use:N \c@rownum } { belowsep } } + } + +\cs_new_protected:Npn \__tblr_update_colsep_registers: + { + \dim_set:Nn \leftsep + { \__tblr_data_item:nen { column } { \int_use:N \c@colnum } { leftsep } } + \dim_set:Nn \rightsep + { \__tblr_data_item:nen { column } { \int_use:N \c@colnum } { rightsep } } } %% Measure and update natural dimensions of the row/column/cell @@ -2945,7 +3224,8 @@ \cs_new_protected:Npn \__tblr_get_cell_text_real:nn #1 #2 { \group_begin: - \tl_set:Nx \l__tblr_c_tl { \__tblr_text_item:ne { text } {[#1][#2]} } + \tl_set:Nx \l__tblr_c_tl { \__tblr_spec_item:ne { text } {[#1][#2]} } + \tl_set:Nx \l__tblr_f_tl { \__tblr_data_item:neen { cell } {#1} {#2} { font } } \tl_set:Nx \l__tblr_w_tl { \__tblr_data_item:neen { cell } {#1} {#2} { width } } \dim_compare:nNnT { \l__tblr_w_tl } < { 0pt } % cell width unset @@ -2972,12 +3252,13 @@ \seq_map_variable:NNn \l_tmpa_seq \l_tmpa_tl { \__tblr_remove_braces:N \l_tmpa_tl - \hbox_set:Nn \l_tmpa_box { \l_tmpa_tl } + \hbox_set:Nn \l_tmpa_box { \l__tblr_f_tl \l_tmpa_tl } \tl_set:Nx \l__tblr_w_tl { \dim_max:nn { \l__tblr_w_tl } { \box_wd:N \l_tmpa_box } } } } } + \tl_put_left:NV \l__tblr_c_tl \l__tblr_f_tl \__tblr_get_vcell_and_sizes:NN \l__tblr_c_tl \l__tblr_w_tl \group_end: } @@ -3029,16 +3310,13 @@ \group_end: } -\cs_new_eq:NN \__tlbr_halign_l: \raggedright -\cs_new_eq:NN \__tlbr_halign_c: \centering -\cs_new_eq:NN \__tlbr_halign_r: \raggedleft - %% #1: cell text; #2: box width +%% All halign commands are defined at the beginning of the file \cs_new_protected:Npn \__tblr_make_vcell_text:nN #1 #2 { \dim_set:Nn \tex_hsize:D { #2 } \@arrayparboxrestore - \cs:w __tlbr_halign_ \g__tblr_cell_halign_tl : \cs_end: + \cs:w __tblr_halign_command_ \g__tblr_cell_halign_tl : \cs_end: \mode_leave_vertical: \box_use:N \l__tblr_strut_ht_box \bool_if:NTF \l__tblr_math_mode_bool { $#1$ } { #1 } @@ -3238,7 +3516,7 @@ \cs_new_protected:Npn \__tblr_collect_extendable_column_width: { - \tl_set:Nx \l_tmpa_tl { \__tblr_prop_item:nn {table} {width} } + \tl_set:Nx \l_tmpa_tl { \__tblr_prop_item:nn { inner } { width } } \tl_if_empty:NTF \l_tmpa_tl { \dim_set_eq:NN \l__column_target_dim \linewidth } { \dim_set:Nn \l__column_target_dim { \l_tmpa_tl } } @@ -3271,7 +3549,7 @@ } { \dim_sub:Nn \l__column_target_dim { \l__tblr_a_tl } } \tl_set:Nx \l__tblr_a_tl - { \__tblr_text_item:ne { vline } { [\l__tblr_j_tl] / @vline-width } } + { \__tblr_spec_item:ne { vline } { [\l__tblr_j_tl] / @vline-width } } \tl_set:Nx \l__tblr_b_tl { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { leftsep } } \tl_set:Nx \l__tblr_c_tl @@ -3281,7 +3559,7 @@ } \tl_set:Nx \l__tblr_a_tl { - \__tblr_text_item:ne { vline } + \__tblr_spec_item:ne { vline } { [\int_eval:n {\c@colcount + 1}] / @vline-width } } \tl_if_empty:NF \l__tblr_a_tl @@ -3378,11 +3656,11 @@ \cs_new_protected:Npn \__tblr_adjust_sizes_for_span_cells: { - \__tblr_prop_if_in:nnT {table} {colspan} + \__tblr_prop_if_in:nnT { inner } { colspan } { \__tblr_collect_column_widths_skips: \str_if_eq:xnTF - { \__tblr_prop_item:ne {table} {hspan} } {minimal} + { \__tblr_prop_item:ne { inner } { hspan } } { minimal } { \__tblr_set_span_widths_from_column_widths: } @@ -3393,12 +3671,12 @@ \LogTblrTracing { column } \__tblr_calculate_cell_sizes: } - \__tblr_prop_if_in:nnT {table} {rowspan} + \__tblr_prop_if_in:nnT { inner } { rowspan } { \__tblr_collect_row_heights_skips: \__tblr_collect_span_heights: \__tblr_set_row_heights_from_span_heights: - \LogTblrTracing {row} + \LogTblrTracing { row } } } @@ -3421,7 +3699,7 @@ \__tblr_data_item:nen { column } { \int_eval:n { \l__tblr_j_tl - 1 } } { rightsep } + - \__tblr_text_item:ne { vline } + \__tblr_spec_item:ne { vline } { [\l__tblr_j_tl] / @vline-width } + \__tblr_data_item:nen { column } { \l__tblr_j_tl } { leftsep } @@ -3453,7 +3731,7 @@ \__tblr_data_item:nen { row } { \int_eval:n {\l__tblr_i_tl - 1} } { belowsep } + - \__tblr_text_item:ne { hline } + \__tblr_spec_item:ne { hline } { [\l__tblr_i_tl] / @hline-height } + \__tblr_data_item:nen { row } { \l__tblr_i_tl } { abovesep } @@ -3585,27 +3863,49 @@ %% Compute and set column widths from span widths \cs_new_protected:Npn \__tblr_set_column_widths_from_span_widths: { - \__tblr_calc_item_sizes_from_span_sizes:xNN - { \int_use:N \c@colcount } - \l__tblr_col_item_skip_size_prop - \l__tblr_col_span_size_prop + \str_if_eq:xnTF + { \__tblr_prop_item:ne { inner } { hspan } } + { even } + { + \__tblr_distribute_span_sizes_even:xNN + { \int_use:N \c@colcount } + \l__tblr_col_item_skip_size_prop + \l__tblr_col_span_size_prop + } + { + \__tblr_distribute_span_sizes_default:xNN + { \int_use:N \c@colcount } + \l__tblr_col_item_skip_size_prop + \l__tblr_col_span_size_prop + } \__tblr_set_all_column_widths: } %% Compute and set row heights from span heights \cs_new_protected:Npn \__tblr_set_row_heights_from_span_heights: { - \__tblr_calc_item_sizes_from_span_sizes:xNN - { \int_use:N \c@rowcount } - \l__tblr_row_item_skip_size_prop - \l__tblr_row_span_size_prop + \str_if_eq:xnTF + { \__tblr_prop_item:ne { inner } { vspan } } + { even } + { + \__tblr_distribute_span_sizes_even:nNN + { \int_use:N \c@rowcount } + \l__tblr_row_item_skip_size_prop + \l__tblr_row_span_size_prop + } + { + \__tblr_distribute_span_sizes_default:xNN + { \int_use:N \c@rowcount } + \l__tblr_row_item_skip_size_prop + \l__tblr_row_span_size_prop + } \__tblr_set_all_row_heights: } %% See page 245 in Chapter 22 of TeXbook %% #1: total number of items %% #2: prop list with item sizes and skip sizes; #3: prop list with span sizes -\cs_new_protected:Npn \__tblr_calc_item_sizes_from_span_sizes:nNN #1 #2 #3 +\cs_new_protected:Npn \__tblr_distribute_span_sizes_default:nNN #1 #2 #3 { \int_step_variable:nNn { #1 } \l__tblr_j_tl { @@ -3656,14 +3956,60 @@ } \__tblr_do_if_tracing:nn { cellspan } { \prop_log:N #2 } } -\cs_generate_variant:Nn \__tblr_calc_item_sizes_from_span_sizes:nNN { x } +\cs_generate_variant:Nn \__tblr_distribute_span_sizes_default:nNN { x } + +%% #1: total number of items +%% #2: prop list with item sizes and skip sizes; #3: prop list with span sizes +\cs_new_protected:Npn \__tblr_distribute_span_sizes_even:nNN #1 #2 #3 + { + \prop_clear:N \l_tmpa_prop + \prop_map_inline:Nn #3 + { + \__tblr_get_span_from_to:w ##1 + \dim_set:Nn \l_tmpa_dim {##2} + \dim_sub:Nn \l_tmpa_dim { \prop_item:Ne #2 { item[\l__tblr_a_tl] } } + \int_step_inline:nnn { \l__tblr_a_tl + 1 } { \l__tblr_b_tl } + { + \dim_sub:Nn \l_tmpa_dim + { + \prop_item:Ne #2 { skip[####1] } + \prop_item:Nn #2 { item[####1] } + } + } + \__tblr_do_if_tracing:nn { cellspan } + { + \tl_log:x { \l__tblr_a_tl -> \l__tblr_b_tl : ~ \dim_use:N \l_tmpa_dim } + } + \dim_compare:nNnT {\l_tmpa_dim} > {0pt} + { + \tl_set:Nx \l_tmpa_tl + { \dim_eval:n { \l_tmpa_dim / (\l__tblr_b_tl - \l__tblr_a_tl + 1) } } + \int_step_inline:nnn { \l__tblr_a_tl } { \l__tblr_b_tl } + { + \__tblr_put_if_larger:NnV \l_tmpa_prop {####1} \l_tmpa_tl + } + } + } + \__tblr_do_if_tracing:nn { cellspan } { \prop_log:N \l_tmpa_prop } + \prop_map_inline:Nn \l_tmpa_prop + { + \__tblr_add_dimen_value:Nnn #2 {item[##1]} {##2} + } + \__tblr_do_if_tracing:nn { cellspan } { \prop_log:N #2 } + } +\cs_generate_variant:Nn \__tblr_distribute_span_sizes_even:nNN { x } + +\cs_new_protected:Npn \__tblr_get_span_from_to:w (#1-#2) + { + \tl_set:Nn \l__tblr_a_tl {#1} + \tl_set:Nn \l__tblr_b_tl {#2} + } \cs_new_protected:Npn \__tblr_set_all_column_widths: { \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl { \__tblr_data_gput:nene { column } - { \l__tblr_j_tl } { @col-width } + { \l__tblr_j_tl } { width } { \prop_item:Ne \l__tblr_col_item_skip_size_prop { item[\l__tblr_j_tl] } } } } @@ -3690,12 +4036,6 @@ } } -\cs_new_protected:Npn \__tblr_get_span_key_row_col:w [#1][#2] - { - \tl_set:Nn \l__tblr_i_tl {#1} - \tl_set:Nn \l__tblr_j_tl {#2} - } - %% Compute and set span widths from column widths \cs_new_protected:Npn \__tblr_set_span_widths_from_column_widths: { @@ -3738,71 +4078,912 @@ \cs_generate_variant:Nn \__tblr_calc_span_widths:nnN { xxN } %%% -------------------------------------------------------- -%% \section{Build the Whole Table} +%%> \section{Header and Footer Styles} %%% -------------------------------------------------------- -\tl_new:N \__tlbr_vbox_align_tl -\tl_const:Nn \__tlbr_vbox_t_tl {t} -\tl_const:Nn \__tlbr_vbox_m_tl {m} -\tl_const:Nn \__tlbr_vbox_c_tl {c} -\tl_const:Nn \__tlbr_vbox_b_tl {b} +\prop_new:N \l__tblr_element_styles_prop -\box_new:N \l__tblr_table_box +\cs_new_protected:Npn \__tblr_style_put:nn #1 #2 + { + \prop_put:Nnn \l__tblr_element_styles_prop {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_style_put:nn { nV, ne, en } -%% #1: table alignment -\cs_new_protected:Npn \__tblr_build_whole:n #1 +\cs_new:Npn \__tblr_style_item:n #1 + { + \prop_item:Nn \l__tblr_element_styles_prop {#1} + } + +\cs_new_protected:Npn \__tblr_style_log: + { + \prop_log:N \l__tblr_element_styles_prop + } + +\tl_new:N \l__tblr_element_name_tl +\tl_new:N \l__tblr_element_styles_tl + +%% #1: list of element names; #2: element styles +\NewDocumentCommand \SetTblrStyle { m +m } + { + \tl_set:Nn \l__tblr_element_styles_tl {#2} + \keys_set:nn { tblr-element } {#1} + \ignorespaces + } + +\keys_define:nn { tblr-element } + { + head .meta:n = { firsthead, middlehead, lasthead }, + foot .meta:n = { firstfoot, middlefoot, lastfoot }, + unknown .code:n = \__tblr_set_element_styles:V \l_keys_key_str, + } + +\cs_new_protected:Npn \__tblr_set_element_styles:n #1 + { + \tl_set:Nn \l__tblr_element_name_tl {#1} + \keys_set:nV { tblr-style } \l__tblr_element_styles_tl + } +\cs_generate_variant:Nn \__tblr_set_element_styles:n { V } + +\keys_define:nn { tblr-style } + { + halign .code:n = \__tblr_element_gput_style:nn { halign } {#1}, + l .meta:n = { halign = l }, + c .meta:n = { halign = c }, + r .meta:n = { halign = r }, + fg .code:n = \__tblr_element_gput_style:nn { fg } {#1}, + font .code:n = \__tblr_element_gput_style:nn { font } {#1}, + hang .code:n = \__tblr_element_gput_style:nn { hang } {#1}, + indent .code:n = \__tblr_element_gput_style:nn { indent } {#1}, + unknown .code:n = \__tblr_element_unknown_key:Vn \l_keys_key_str {#1}, + } + +\cs_new_protected:Npn \__tblr_element_gput_style:nn #1 #2 + { + \__tblr_style_put:en { \l__tblr_element_name_tl / #1 } {#2} + } + +\cs_new_protected:Npn \__tblr_element_unknown_key:nn #1 #2 + { + \regex_match:NnTF \c__tblr_is_color_key_regex {#1} + { \__tblr_style_put:en { \l__tblr_element_name_tl / fg } {#1} } + { + %% unknown key name has been changed to string in \l_keys_key_str + \tl_set_rescan:Nnn \l__tblr_f_tl {} {#1} + \tl_if_head_eq_catcode:VNTF \l__tblr_f_tl \scan_stop: + { + \__tblr_style_put:en { \l__tblr_element_name_tl / font } \l__tblr_f_tl + } + { + \__tblr_style_put:en { \l__tblr_element_name_tl / #1 } {#2} + } + } + } +\cs_generate_variant:Nn \__tblr_element_unknown_key:nn { Vn } + +%%% -------------------------------------------------------- +%%> \section{Helper Functions for Templates} +%%% -------------------------------------------------------- + +\tl_new:N \l__tblr_template_name_tl +\tl_new:N \l__tblr_template_code_tl + +\keys_define:nn { tblr-def-template } + { + unknown .code:n = \__tblr_def_template:V \l_keys_key_str, + } + +%% #1: head/foot element; #2: template name; #3: template code +%% If the template name = default, we enable the template at once +%% Otherwise, we may enable the template by using \SetTblrTemplate command +\NewDocumentCommand \DefTblrTemplate { m m +m } + { + \tl_set:Nn \l__tblr_template_name_tl {#2} + \tl_set:Nn \l__tblr_template_code_tl {#3} + \keys_set:nn { tblr-def-template } {#1} + \ignorespaces + } + +\cs_new_protected:Npn \__tblr_def_template:n #1 + { + \tl_set_eq:cN { l__tblr_template_ #1 _ \l__tblr_template_name_tl _tl } + \l__tblr_template_code_tl + } +\cs_generate_variant:Nn \__tblr_def_template:n { V } + +\keys_define:nn { tblr-set-template } + { + unknown .code:n = \__tblr_set_template:V \l_keys_key_str, + } + +%% #1: head/foot element; #2: template name +\NewDocumentCommand \SetTblrTemplate { m m } + { + \tl_set:Nn \l__tblr_template_name_tl {#2} + \keys_set:nn { tblr-set-template } {#1} + \ignorespaces + } + +\cs_new_protected:Npn \__tblr_set_template:n #1 + { + \tl_set_eq:cc { l__tblr_template_ #1 _default_tl } + { l__tblr_template_ #1 _ \l__tblr_template_name_tl _tl } + } +\cs_generate_variant:Nn \__tblr_set_template:n { V } + +\NewExpandableDocumentCommand \GetTblrStyle { m m } + { + \__tblr_style_item:n { #1 / #2 } + } + +\NewDocumentCommand \UseTblrFont { m } + { + \GetTblrStyle {#1} { font } \selectfont + } + +\tl_new:N \l__tblr_use_color_tl + +\NewDocumentCommand \UseTblrColor { m } + { + \tl_set:Nx \l__tblr_use_color_tl { \GetTblrStyle {#1} { fg } } + \tl_if_empty:NF \l__tblr_use_color_tl { \color { \l__tblr_use_color_tl } } + } + +%% All halign commands are defined at the beginning of the file +\NewDocumentCommand \UseTblrAlign { m } + { + \use:c { __tblr_halign_command_ \GetTblrStyle {#1} { halign } : } + } + +\tl_new:N \l__tblr_use_hang_tl + +\NewDocumentCommand \UseTblrHang { m } + { + \tl_set:Nx \l__tblr_use_hang_tl { \GetTblrStyle {#1} { hang } } + \tl_if_empty:NF \l__tblr_use_hang_tl + { + \tl_put_left:Nn \l__tblr_use_hang_tl + { \hangafter = 1 \relax \hangindent = } + \tl_put_right:Nn \l__tblr_use_hang_tl { \relax } + \exp_args:NV \everypar \l__tblr_use_hang_tl + } + } + +\tl_new:N \l__tblr_use_indent_tl + +\NewDocumentCommand \UseTblrIndent { m } + { + \tl_set:Nx \l__tblr_use_indent_tl { \GetTblrStyle {#1} { indent } } + \tl_if_empty:NF \l__tblr_use_indent_tl + { \exp_args:NNV \setlength \parindent \l__tblr_use_indent_tl } + } + +\AtBeginDocument + { + \@ifpackageloaded{xcolor}{}{\RenewDocumentCommand \UseTblrColor {m} {}} + } + +%% #1: head/foot element; #2: template name +\NewExpandableDocumentCommand \ExpTblrTemplate { m m } + { + \tl_use:c { l__tblr_template_ #1 _ #2 _tl } + } + +%% #1: head/foot element; #2: template name +\NewDocumentCommand \UseTblrTemplate { m m } + { + \group_begin: + \UseTblrFont {#1} + \UseTblrColor {#1} + \tl_use:c { l__tblr_template_ #1 _ #2 _tl } + \group_end: + } + +\NewDocumentCommand \MapTblrNotes { +m } + { + \__tblr_prop_map_inline:nn { note } + { + \tl_set_rescan:Nnn \InsertTblrNoteTag {} {##1} + \tl_set:Nn \InsertTblrNoteText {##2} + #1 + } + } + +\NewDocumentCommand \MapTblrRemarks { +m } + { + \__tblr_prop_map_inline:nn { remark } + { + \tl_set_rescan:Nnn \InsertTblrRemarkTag {} {##1} + \tl_set:Nn \InsertTblrRemarkText {##2} + #1 + } + } + +\NewExpandableDocumentCommand \InsertTblrText { m } + { + \__tblr_spec_item:nn { outer } {#1} + } + +\NewExpandableDocumentCommand \InsertTblrMore { m } + { + \__tblr_prop_item:nn { more } {#1} + } + +%%% -------------------------------------------------------- +%%> \section{Table Continuation Templates} +%%% -------------------------------------------------------- + +\DefTblrTemplate { contfoot-text } { normal } { Continued ~ on ~ next ~ page } +\SetTblrTemplate { contfoot-text } { normal } + +\DefTblrTemplate { contfoot } { plain } + { + \noindent + \raggedleft + \UseTblrTemplate { contfoot-text } { default } + \par + } +\DefTblrTemplate { contfoot } { normal } + { + %% need to set parindent after alignment + \raggedleft + \UseTblrAlign { contfoot } + \UseTblrIndent { contfoot } + \UseTblrHang { contfoot } + \leavevmode + \UseTblrTemplate { contfoot-text } { default } + \par + } +\SetTblrTemplate { contfoot } { normal } + +\DefTblrTemplate { conthead-text } { normal } { ( Continued ) } +\SetTblrTemplate { conthead-text } { normal } + +\DefTblrTemplate { conthead } { plain } + { + \noindent + \raggedright + \UseTblrTemplate { conthead-text } { default } + \par + } +\DefTblrTemplate { conthead } { normal } + { + %% need to set parindent after alignment + \raggedright + \UseTblrAlign { conthead } + \UseTblrIndent { conthead } + \UseTblrHang { conthead } + \leavevmode + \UseTblrTemplate { conthead-text } { default } + \par + } +\SetTblrTemplate { conthead } { normal } + +%%% -------------------------------------------------------- +%%> \section{Table Caption Templates} +%%% -------------------------------------------------------- + +\tl_new:N \l__tblr_caption_short_tl + +\DefTblrTemplate { caption-lot } { normal } { - \bool_if:NTF \l__tblr_long_table_bool - { \__tblr_build_long_table:n {#1} } - { \__tblr_build_short_table:n {#1} } + \tl_set:Nx \l__tblr_caption_short_tl { \InsertTblrText { entry } } + \tl_if_empty:NT \l__tblr_caption_short_tl + { \tl_set:Nx \l__tblr_caption_short_tl { \InsertTblrText { caption } } } + \addcontentsline { lot } { table } + { \protect\numberline { \arabic { table } } { \l__tblr_caption_short_tl } } + } +\SetTblrTemplate { caption-lot } { normal } + +%% We need to use \hspace and \enskip, but not ~ or \space, +%% since we want a correct hangindent caption paragraph. + +\DefTblrTemplate { caption-tag } { normal } { Table \hspace{0.25em} \thetable } +\SetTblrTemplate { caption-tag } { normal } + +\DefTblrTemplate { caption-sep } { normal } { : \enskip } +\SetTblrTemplate { caption-sep } { normal } + +\DefTblrTemplate { caption-text } { normal } { \InsertTblrText { caption } } +\SetTblrTemplate { caption-text } { normal } + +\box_new:N \l__tblr_caption_box +\box_new:N \l__tblr_caption_left_box + +\DefTblrTemplate { caption } { plain } + { + \hbox_set:Nn \l__tblr_caption_box + { + \UseTblrTemplate { caption-tag } { default } + \UseTblrTemplate { caption-sep } { default } + \UseTblrTemplate { caption-text } { default } + } + \dim_compare:nNnTF { \box_wd:N \l__tblr_caption_box } > { \hsize } + { + \noindent + \hbox_unpack:N \l__tblr_caption_box + \par + } + { + \centering + \makebox [\hsize] [c] { \box_use:N \l__tblr_caption_box } + \par + } + } +\DefTblrTemplate { caption } { normal } + { + \hbox_set:Nn \l__tblr_caption_box + { + \UseTblrTemplate { caption-tag } { default } + \UseTblrTemplate { caption-sep } { default } + \UseTblrTemplate { caption-text } { default } + } + \dim_compare:nNnTF { \box_wd:N \l__tblr_caption_box } > { \hsize } + { + \UseTblrAlign { caption } + \UseTblrIndent { caption } + \hbox_set:Nn \l__tblr_caption_left_box + { + \UseTblrTemplate { caption-tag } { default } + \UseTblrTemplate { caption-sep } { default } + } + \hangindent = \box_wd:N \l__tblr_caption_left_box + \hangafter = 1 + \UseTblrHang { caption } + \leavevmode + \hbox_unpack:N \l__tblr_caption_box + \par + } + { + \centering + \makebox [\hsize] [c] { \box_use:N \l__tblr_caption_box } + \par + } + } +\SetTblrTemplate { caption } { normal } + +\DefTblrTemplate { capcont } { plain } + { + \hbox_set:Nn \l__tblr_caption_box + { + \UseTblrTemplate { caption-tag } { default } + \UseTblrTemplate { caption-sep } { default } + \UseTblrTemplate { caption-text } { default } + \space + \UseTblrTemplate { conthead-text } { default } + } + \dim_compare:nNnTF { \box_wd:N \l__tblr_caption_box } > { \hsize } + { + \noindent + \hbox_unpack:N \l__tblr_caption_box + \par + } + { + \centering + \makebox [\hsize] [c] { \box_use:N \l__tblr_caption_box } + \par + } + } +\DefTblrTemplate { capcont } { normal } + { + \hbox_set:Nn \l__tblr_caption_box + { + \UseTblrTemplate { caption-tag } { default } + \UseTblrTemplate { caption-sep } { default } + \UseTblrTemplate { caption-text } { default } + \space + \UseTblrTemplate { conthead-text } { default } + } + \dim_compare:nNnTF { \box_wd:N \l__tblr_caption_box } > { \hsize } + { + \UseTblrAlign { capcont } + \UseTblrIndent { capcont } + \hbox_set:Nn \l__tblr_caption_left_box + { + \UseTblrTemplate { caption-tag } { default } + \UseTblrTemplate { caption-sep } { default } + } + \hangindent = \box_wd:N \l__tblr_caption_left_box + \hangafter = 1 + \UseTblrHang { capcont } + \leavevmode + \hbox_unpack:N \l__tblr_caption_box + \par + } + { + \centering + \makebox [\hsize] [c] { \box_use:N \l__tblr_caption_box } + \par + } + } +\SetTblrTemplate { capcont} { normal } + +%%% -------------------------------------------------------- +%%> \section{Table Notes Templates} +%%% -------------------------------------------------------- + +%% By default the targets generated by \hypertarget are too low +%% Therefore we need to use \Hy@raisedlink command to fix this problem +%% See https://tex.stackexchange.com/questions/17057 +%% We also use \use:c in case the private command \Hy@raisedlink is removed +\cs_new_protected:Npn \__tblr_hyper_target:n #1 + { + \cs_if_exist:NT \hypertarget + { + \use:c { Hy@raisedlink } + { + \hypertarget + { tblr / \int_use:N \g__tblr_table_count_int / \tl_to_str:n {#1} } + { } + } + } + } +\cs_generate_variant:Nn \__tblr_hyper_target:n { V } + +\cs_new_protected:Npn \__tblr_hyper_link:nn #1 #2 + { + \cs_if_exist:NTF \hyperlink + { + \hyperlink + { tblr / \int_use:N \g__tblr_table_count_int / \tl_to_str:n {#1} } + { #2 } + } + { #2 } + } + +\NewDocumentCommand \TblrNote { m } + { + \__tblr_hyper_link:nn {#1} + { \textsuperscript { \sffamily \UseTblrFont { note-tag } #1 } } + } + +\DefTblrTemplate { note-tag } { normal } + { + \textsuperscript { \sffamily \UseTblrFont { note-tag } \InsertTblrNoteTag } + } +\SetTblrTemplate { note-tag } { normal } + +\DefTblrTemplate { note-target } { normal } + { + \__tblr_hyper_target:V \InsertTblrNoteTag + } +\SetTblrTemplate { note-target } { normal } + +\DefTblrTemplate { note-sep } { normal } { \space } +\SetTblrTemplate { note-sep } { normal } + +\DefTblrTemplate { note-text } { normal } { \InsertTblrNoteText } +\SetTblrTemplate { note-text } { normal } + +\DefTblrTemplate { note } { plain } + { + \MapTblrNotes + { + \noindent + \UseTblrTemplate { note-tag } { default } + \UseTblrTemplate { note-target } { default } + \UseTblrTemplate { note-sep } { default } + \UseTblrTemplate { note-text } { default } + \par + } + } +\DefTblrTemplate { note } { normal } + { + \UseTblrAlign { note } + \UseTblrIndent { note } + \MapTblrNotes + { + \hangindent = 0.7em + \hangafter = 1 + \UseTblrHang { note } + \leavevmode + \hbox_to_wd:nn { \the\hangindent } + { + \UseTblrTemplate { note-tag } { default } + \UseTblrTemplate { note-target } { default } + \hfil + } + \UseTblrTemplate { note-text } { default } + \par + } + } +\DefTblrTemplate { note } { inline } + { + \UseTblrAlign { note } + \UseTblrIndent { note } + \UseTblrHang { note } + \leavevmode + \MapTblrNotes + { + \UseTblrTemplate { note-tag } { default } + \UseTblrTemplate { note-target } { default } + \UseTblrTemplate { note-sep } { default } + \UseTblrTemplate { note-text } { default } + \quad + } + \par + } +\SetTblrTemplate { note } { normal } + +%%% -------------------------------------------------------- +%%> \section{Table Remarks Templates} +%%% -------------------------------------------------------- + +\DefTblrTemplate { remark-tag } { normal } + { + \itshape \UseTblrFont { remark-tag } \InsertTblrRemarkTag + } +\SetTblrTemplate { remark-tag } { normal } + +\DefTblrTemplate { remark-sep } { normal } { : \space } +\SetTblrTemplate { remark-sep } { normal } + +\DefTblrTemplate { remark-text } { normal } { \InsertTblrRemarkText } +\SetTblrTemplate { remark-text } { normal } + +\DefTblrTemplate { remark } { plain } + { + \MapTblrRemarks + { + \noindent + \UseTblrTemplate { remark-tag } { default } + \UseTblrTemplate { remark-sep } { default } + \UseTblrTemplate { remark-text } { default } + \par + } + } +\DefTblrTemplate { remark } { normal } + { + \UseTblrAlign { remark } + \UseTblrIndent { remark } + \MapTblrRemarks + { + \hangindent = 0.7em + \hangafter = 1 + \UseTblrHang { remark } + \leavevmode + \UseTblrTemplate { remark-tag } { default } + \UseTblrTemplate { remark-sep } { default } + \UseTblrTemplate { remark-text } { default } + \par + } + } +\DefTblrTemplate { remark } { inline } + { + \UseTblrAlign { remark } + \UseTblrIndent { remark } + \UseTblrHang { remark } + \leavevmode + \MapTblrRemarks + { + \UseTblrTemplate { remark-tag } { default } + \UseTblrTemplate { remark-sep } { default } + \UseTblrTemplate { remark-text } { default } + \quad + } + \par + } +\SetTblrTemplate { remark } { normal } + +%%% -------------------------------------------------------- +%%> \section{Header and Footer Templates} +%%% -------------------------------------------------------- + +\tl_new:N \g__tblr_template_firsthead_default_tl +\tl_new:N \g__tblr_template_middlehead_default_tl +\tl_new:N \g__tblr_template_lasthead_default_tl +\tl_new:N \g__tblr_template_firstfoot_default_tl +\tl_new:N \g__tblr_template_middlefoot_default_tl +\tl_new:N \g__tblr_template_lastfoot_default_tl + +\keys_define:nn { tblr-def-template } + { + head .meta:n = { firsthead, middlehead, lasthead }, + foot .meta:n = { firstfoot, middlefoot, lastfoot }, + } + +\keys_define:nn { tblr-set-template } + { + head .meta:n = { firsthead, middlehead, lasthead }, + foot .meta:n = { firstfoot, middlefoot, lastfoot }, + } + +\DefTblrTemplate { firsthead } { normal } + { + \UseTblrTemplate { caption } { default } + \UseTblrTemplate { caption-lot } { default } + } + +\DefTblrTemplate { middlehead, lasthead } { normal } + { + \UseTblrTemplate { capcont } { default } + } + +\DefTblrTemplate { firstfoot, middlefoot } { normal } + { + \UseTblrTemplate { contfoot } { default } + } + +\DefTblrTemplate { lastfoot } { normal } + { + \UseTblrTemplate { note } { default } + \UseTblrTemplate { remark } { default } + } + +\SetTblrTemplate { head } { normal } +\SetTblrTemplate { foot } { normal } + +%%% -------------------------------------------------------- +%%> \section{Build the Whole Table} +%%% -------------------------------------------------------- + +\cs_new:Npn \__tblr_box_height:N #1 + { + \dim_eval:n { \box_ht:N #1 + \box_dp:N #1 } + } + +\cs_new_protected:Npn \__tblr_build_head_foot: + { + \__tblr_build_row_head_foot: + \__tblr_build_table_head_foot: + } + +\tl_new:N \l__tblr_row_head_tl +\tl_new:N \l__tblr_row_foot_tl +\box_new:N \l__tblr_row_head_box +\box_new:N \l__tblr_row_foot_box +\dim_new:N \l__tblr_row_head_foot_dim + +\cs_new_protected:Npn \__tblr_build_row_head_foot: + { + %% \l__tblr_row_head_tl and \l__tblr_row_foot_tl may be empty + \tl_set:Nx \l__tblr_row_head_tl { \__tblr_prop_item:ne { inner } { rowhead } } + \int_compare:nNnTF { \l__tblr_row_head_tl + 0 } > { 0 } + { \__tblr_build_one_table:nn {1} { \l__tblr_row_head_tl } } + { \__tblr_build_one_hline:n {1} } + \box_set_eq:NN \l__tblr_row_head_box \l__tblr_table_box + \tl_set:Nx \l__tblr_row_foot_tl { \__tblr_prop_item:ne { inner } { rowfoot } } + \int_compare:nNnTF { \l__tblr_row_foot_tl + 0 } > { 0 } + { + \__tblr_build_one_table:nn + { \c@rowcount - \l__tblr_row_foot_tl + 1 } { \c@rowcount } + } + { \__tblr_build_one_hline:n { \int_eval:n { \c@rowcount + 1 } } } + \box_set_eq:NN \l__tblr_row_foot_box \l__tblr_table_box + \dim_set:Nn \l__tblr_row_head_foot_dim + { + \__tblr_box_height:N \l__tblr_row_head_box + + \__tblr_box_height:N \l__tblr_row_foot_box + } + } + +\dim_new:N \tablewidth + +\cs_new_protected:Npn \__tblr_get_table_width: + { + \dim_zero:N \tablewidth + \int_step_inline:nn { \c@colcount } + { + \dim_add:Nn \tablewidth + { + \__tblr_spec_item:nn { vline } { [##1] / @vline-width } + + + \__tblr_data_item:nnn { column } {##1} { leftsep } + + + \__tblr_data_item:nnn { column } {##1} { @col-width } + + + \__tblr_data_item:nnn { column } {##1} { rightsep } + } + } + \dim_add:Nn \tablewidth + { + \__tblr_spec_item:ne { vline } + { [\int_eval:n { \c@colcount + 1 }] / @vline-width } + } + } + +\box_new:N \l__tblr_table_firsthead_box +\box_new:N \l__tblr_table_middlehead_box +\box_new:N \l__tblr_table_lasthead_box +\box_new:N \l__tblr_table_firstfoot_box +\box_new:N \l__tblr_table_middlefoot_box +\box_new:N \l__tblr_table_lastfoot_box + +\cs_new_protected:Npn \__tblr_build_table_head_foot: + { + \__tblr_get_table_width: + \__tblr_build_table_head_aux:Nn \l__tblr_table_firsthead_box + { + \tl_set:Nn \l_tmpa_tl { \InsertTblrText { label } } + \tl_if_empty:NF \l_tmpa_tl { \exp_args:NV \label \l_tmpa_tl } + \UseTblrTemplate { firsthead } { default } + } + \__tblr_build_table_head_aux:Nn + \l__tblr_table_middlehead_box { \UseTblrTemplate { middlehead } { default } } + \__tblr_build_table_head_aux:Nn + \l__tblr_table_lasthead_box { \UseTblrTemplate { lasthead } { default } } + \__tblr_build_table_foot_aux:Nn + \l__tblr_table_firstfoot_box { \UseTblrTemplate { firstfoot } { default } } + \__tblr_build_table_foot_aux:Nn + \l__tblr_table_middlefoot_box { \UseTblrTemplate { middlefoot } { default } } + \__tblr_build_table_foot_aux:Nn + \l__tblr_table_lastfoot_box { \UseTblrTemplate { lastfoot } { default } } + } + +\cs_new_protected:Npn \__tblr_build_table_head_aux:Nn #1 #2 + { + \vbox_set:Nn #1 + { + \hsize = \tablewidth + \parindent = 0pt \relax + \vbox:n {#2} + \skip_vertical:n { \__tblr_spec_item:nn { outer } { headsep } } + } + } + +\cs_new_protected:Npn \__tblr_build_table_foot_aux:Nn #1 #2 + { + \vbox_set:Nn #1 + { + \hsize = \tablewidth + \skip_vertical:n { \__tblr_spec_item:nn { outer } { footsep } } + \parindent = 0pt \relax + \vbox:n {#2} + } + } + +\cs_new_protected:Npn \__tblr_build_whole: + { + \tl_if_eq:enTF { \__tblr_spec_item:nn { outer } { long } } { true } + { \__tblr_build_long_table:e { \__tblr_spec_item:nn { outer } { halign } } } + { \__tblr_build_short_table:e { \__tblr_spec_item:nn { outer } { valign } } } } \dim_new:N \l__tblr_remain_height_dim \tl_new:N \l__tblr_long_from_tl +\tl_new:N \l__tblr_long_to_tl +\int_new:N \l__tblr_table_page_int +\bool_new:N \l__tblr_table_page_break_bool +%% #1: table alignment +%% For long table, we need to leave hmode first to get correct \pagetotal +%% Also remove topskip and presep if we are at the beginning of the page \cs_new_protected:Npn \__tblr_build_long_table:n #1 { - %\dim_log:N \pagegoal - %\dim_log:N \pagetotal - \dim_set:Nn \l__tblr_remain_height_dim { \pagegoal - \pagetotal } - \tl_set:Nn \l__tblr_long_from_tl {1} - \int_step_variable:nNn { \c@rowcount } \l__tblr_i_tl + \LogTblrTracing { page } + \par + \LogTblrTracing { page } + \dim_compare:nNnTF { \pagegoal } = { \maxdimen } + { \hbox{}\kern-\topskip\nobreak } + { \skip_vertical:n { \__tblr_spec_item:nn { outer } { presep } } } + \LogTblrTracing { page } + \nointerlineskip + \mode_leave_vertical: + \LogTblrTracing { page } + \hrule height ~ 0pt + \LogTblrTracing { page } + \int_set:Nn \l__tblr_table_page_int {1} + \refstepcounter { table } + \__tblr_build_head_foot: + \dim_set:Nn \l__tblr_remain_height_dim + { \pagegoal - \pagetotal - \l__tblr_row_head_foot_dim } + \tl_set:Nx \l__tblr_long_from_tl { \int_eval:n { \l__tblr_row_head_tl + 1 } } + \tl_set:Nx \l__tblr_long_to_tl + { \int_eval:n { \c@rowcount - ( \l__tblr_row_foot_tl + 0 ) } } + \int_step_variable:nnNn + { \l__tblr_long_from_tl } { \l__tblr_long_to_tl } \l__tblr_i_tl { \dim_set:Nn \l_tmpa_dim { - \__tblr_text_item:ne { hline } { [\l__tblr_i_tl] / @hline-height } - + \__tblr_data_item:nen { row } { \l__tblr_i_tl } { abovesep } + \__tblr_data_item:nen { row } { \l__tblr_i_tl } { @row-height } + \__tblr_data_item:nen { row } { \l__tblr_i_tl } { belowsep } + + + \__tblr_spec_item:ne { hline } + { [ \int_eval:n { \l__tblr_i_tl + 1} ] / @hline-height } } - \dim_compare:nNnTF - { \l_tmpa_dim } > { \l__tblr_remain_height_dim } + \__tblr_check_table_page_break:NNN + \l__tblr_remain_height_dim \l_tmpa_dim \l__tblr_table_page_break_bool + \bool_if:NTF \l__tblr_table_page_break_bool { - \tl_log:N \l__tblr_i_tl - \__tblr_build_page_table:nnx {#1} - { \l__tblr_long_from_tl } { \int_eval:n { \l__tblr_i_tl - 1 } } + \__tblr_do_if_tracing:nn { page } { \tl_log:N \l__tblr_i_tl } + \int_compare:nNnT + { \l__tblr_i_tl - \l__tblr_long_from_tl } > {1} + { + \__tblr_build_page_table:nnx {#1} + { \l__tblr_long_from_tl } { \int_eval:n { \l__tblr_i_tl - 1 } } + \int_incr:N \l__tblr_table_page_int + } \newpage \hbox{}\kern-\topskip\nobreak - \leavevmode - %\dim_log:N \pagegoal - %\dim_log:N \pagetotal + \noindent + \LogTblrTracing { page } \dim_set:Nn \l__tblr_remain_height_dim - { \pagegoal - \pagetotal - \l_tmpa_dim } + { \pagegoal - \pagetotal - \l__tblr_row_head_foot_dim - \l_tmpa_dim } \tl_set_eq:NN \l__tblr_long_from_tl \l__tblr_i_tl } { \dim_add:Nn \l__tblr_remain_height_dim { -\l_tmpa_dim } } } - \__tblr_build_page_table:nnn {#1} { \l__tblr_long_from_tl } { \c@rowcount } + \int_compare:nNnTF { \l__tblr_table_page_int } = {1} + { + \box_set_eq:NN \l__tblr_table_head_box \l__tblr_table_firsthead_box + \box_set_eq:NN \l__tblr_table_foot_box \l__tblr_table_lastfoot_box + } + { + \box_set_eq:NN \l__tblr_table_head_box \l__tblr_table_lasthead_box + \box_set_eq:NN \l__tblr_table_foot_box \l__tblr_table_lastfoot_box + } + \__tblr_build_page_table:nnn + {#1} { \l__tblr_long_from_tl } { \l__tblr_long_to_tl } + \skip_vertical:n { \__tblr_spec_item:nn { outer } { postsep } } + \hrule height ~ 0pt } +\cs_generate_variant:Nn \__tblr_build_long_table:n { e } +\box_new:N \l__tblr_table_head_box +\box_new:N \l__tblr_table_foot_box +\dim_new:N \l__tblr_table_head_foot_dim +\dim_new:N \l__tblr_table_head_body_foot_dim + +%% #1: remain dimension; #2: row dimension; #3: break page or not +\cs_new_protected:Npn \__tblr_check_table_page_break:NNN #1 #2 #3 + { + \int_compare:nNnTF { \l__tblr_table_page_int } = {1} + { + \dim_set:Nn \l__tblr_table_head_body_foot_dim + { + \__tblr_box_height:N \l__tblr_table_firsthead_box + + #2 + \__tblr_box_height:N \l__tblr_table_firstfoot_box + } + \box_set_eq:NN \l__tblr_table_head_box \l__tblr_table_firsthead_box + \dim_compare:nNnTF + { \l__tblr_table_head_body_foot_dim } > {#1} + { + \bool_set_true:N #3 + \box_set_eq:NN \l__tblr_table_foot_box \l__tblr_table_firstfoot_box + } + { \bool_set_false:N #3 } + } + { + \dim_set:Nn \l__tblr_table_head_body_foot_dim + { + \__tblr_box_height:N \l__tblr_table_middlehead_box + + #2 + \__tblr_box_height:N \l__tblr_table_middlefoot_box + } + \box_set_eq:NN \l__tblr_table_head_box \l__tblr_table_middlehead_box + \dim_compare:nNnTF + { \l__tblr_table_head_body_foot_dim } > {#1} + { + \bool_set_true:N #3 + \box_set_eq:NN \l__tblr_table_foot_box \l__tblr_table_middlefoot_box + } + { \bool_set_false:N #3 } + } + } + +\box_new:N \l__tblr_table_box + +%% #1: table alignment; #2: row from; #3: row to \cs_new_protected:Npn \__tblr_build_page_table:nnn #1 #2 #3 { + \bool_set_false:N \l__tblr_build_first_hline_bool + \bool_set_false:N \l__tblr_build_last_hline_bool \__tblr_build_one_table:nn {#2} {#3} + \vbox_set:Nn \l__tblr_table_box + { + \box_use:N \l__tblr_table_head_box + \hrule height ~ 0pt + \box_use:N \l__tblr_row_head_box + \hrule height ~ 0pt + \box_use:N \l__tblr_table_box + \hrule height ~ 0pt + \box_use:N \l__tblr_row_foot_box + \hrule height ~ 0pt + \box_use:N \l__tblr_table_foot_box + } \__tblr_halign_whole:Nn \l__tblr_table_box #1 } \cs_generate_variant:Nn \__tblr_build_page_table:nnn { nnx } @@ -3818,11 +4999,20 @@ } } +%% #1: table alignment +%% For short table, we need to leave vmode first \cs_new_protected:Npn \__tblr_build_short_table:n #1 { + \mode_leave_vertical: \__tblr_build_one_table:nn {1} {\c@rowcount} \__tblr_valign_whole:Nn \l__tblr_table_box #1 } +\cs_generate_variant:Nn \__tblr_build_short_table:n { e } + +\bool_new:N \l__tblr_build_first_hline_bool +\bool_new:N \l__tblr_build_last_hline_bool +\bool_set_true:N \l__tblr_build_first_hline_bool +\bool_set_true:N \l__tblr_build_last_hline_bool %% #1: row from; #2: row to \cs_new_protected:Npn \__tblr_build_one_table:nn #1 #2 @@ -3831,29 +5021,47 @@ { \int_step_variable:nnNn {#1} {#2} \l__tblr_i_tl { - \hbox:n { \__tblr_build_hline:V \l__tblr_i_tl } + \bool_lazy_or:nnT + { \int_compare_p:nNn { \l__tblr_i_tl } > {#1} } + { \bool_if_p:N \l__tblr_build_first_hline_bool } + { \hbox:n { \__tblr_build_hline:V \l__tblr_i_tl } } \hrule height ~ 0pt % remove lineskip between hlines and rows \hbox:n { \__tblr_build_row:N \l__tblr_i_tl } \hrule height ~ 0pt } - \hbox:n { \__tblr_build_hline:n { \int_eval:n {#2 + 1} } } + \bool_if:NT \l__tblr_build_last_hline_bool + { \hbox:n { \__tblr_build_hline:n { \int_eval:n {#2 + 1} } } } } + \bool_set_true:N \l__tblr_build_first_hline_bool + \bool_set_true:N \l__tblr_build_last_hline_bool + } + +%% #1: hline number +\cs_new_protected:Npn \__tblr_build_one_hline:n #1 + { + \vbox_set:Nn \l__tblr_table_box { \hbox:n { \__tblr_build_hline:n { #1 } } } } +\tl_new:N \__tblr_vbox_align_tl +\tl_const:Nn \__tblr_vbox_t_tl {t} +\tl_const:Nn \__tblr_vbox_m_tl {m} +\tl_const:Nn \__tblr_vbox_c_tl {c} +\tl_const:Nn \__tblr_vbox_b_tl {b} + \cs_new_protected:Npn \__tblr_valign_whole:Nn #1 #2 { \group_begin: - \tl_set:Nn \__tlbr_vbox_align_tl {#2} + \tl_set:Nn \__tblr_vbox_align_tl {#2} \dim_set:Nn \l__tblr_t_dim { \box_ht:N #1 + \box_dp:N #1 } - \tl_case:NnF \__tlbr_vbox_align_tl + \tl_case:NnF \__tblr_vbox_align_tl { - \__tlbr_vbox_m_tl + \__tblr_vbox_m_tl { \__tblr_valign_whole_middle:N #1 } - \__tlbr_vbox_c_tl + \__tblr_vbox_c_tl { \__tblr_valign_whole_middle:N #1 } - \__tlbr_vbox_t_tl + \__tblr_vbox_t_tl { \__tblr_valign_whole_top:N #1 } - \__tlbr_vbox_b_tl + \__tblr_vbox_b_tl { \__tblr_valign_whole_bottom:N #1 } } { \__tblr_valign_whole_middle:N #1 } @@ -3868,10 +5076,10 @@ \cs_new_protected:Npn \__tblr_valign_whole_top:N #1 { \tl_set:Nx \l__tblr_a_tl - { \__tblr_text_item:ne { hline } { [1] / @hline-height } } + { \__tblr_spec_item:ne { hline } { [1] / @hline-height } } %% Note that \l__tblr_b_tl may be empty \tl_set:Nx \l__tblr_b_tl - { \__tblr_prop_item:ne { table } { baseline } } + { \__tblr_prop_item:ne { inner } { baseline } } \bool_lazy_or:nnTF { \dim_compare_p:nNn { \l__tblr_a_tl } = { 0pt } } { \int_compare_p:nNn { \l__tblr_b_tl + 0 } = { 1 } } @@ -3902,12 +5110,12 @@ { \tl_set:Nx \l__tblr_a_tl { - \__tblr_text_item:ne { hline } + \__tblr_spec_item:ne { hline } { [\int_eval:n {\c@rowcount + 1}] / @hline-height } } %% Note that \l__tblr_b_tl may be empty \tl_set:Nx \l__tblr_b_tl - { \__tblr_prop_item:ne { table } { baseline } } + { \__tblr_prop_item:ne { inner } { baseline } } \bool_lazy_or:nnTF { \dim_compare_p:nNn { \l__tblr_a_tl } = { 0pt } } { \int_compare_p:nNn { \l__tblr_b_tl + 0 } = { \c@rowcount } } @@ -3937,6 +5145,10 @@ \box_use_drop:N #1 } +%%% -------------------------------------------------------- +%%> \section{Build Table Components} +%%% -------------------------------------------------------- + \dim_new:N \l__tblr_col_o_wd_dim \dim_new:N \l__tblr_col_b_wd_dim @@ -3952,9 +5164,9 @@ \cs_new_protected:Npn \__tblr_build_hline_segment:nn #1 #2 { \tl_set:Nx \l__tblr_n_tl - { \__tblr_text_item:ne { hline } { [#1] / @hline-count } } + { \__tblr_spec_item:ne { hline } { [#1] / @hline-count } } \tl_set:Nx \l__tblr_o_tl - { \__tblr_text_item:ne { hline } { [#1][#2] / omit } } + { \__tblr_spec_item:ne { hline } { [#1][#2] / omit } } \__tblr_get_col_outer_width_border_width:nNN {#2} \l__tblr_col_o_wd_dim \l__tblr_col_b_wd_dim \tl_if_empty:NTF \l__tblr_o_tl @@ -3975,7 +5187,7 @@ \cs_new_protected:Npn \__tblr_build_hline_segment_real:nn #1 #2 { \tl_set:Nx \l__tblr_s_tl - { \__tblr_prop_item:ne { table } { rulesep } } + { \__tblr_prop_item:ne { inner } { rulesep } } \vbox_set:Nn \l__tblr_c_box { %% add an empty hbox to support vbox width @@ -3983,12 +5195,12 @@ \int_step_inline:nn { \l__tblr_n_tl } { \tl_set:Nx \l__tblr_h_tl - { \__tblr_text_item:ne { hline } { [#1](##1) / @hline-height } } + { \__tblr_spec_item:ne { hline } { [#1](##1) / @hline-height } } \hrule height ~ 0pt % remove lineskip \hbox_set_to_wd:Nnn \l__tblr_b_box { \l__tblr_col_o_wd_dim } { \tl_set:Nx \l__tblr_f_tl - { \__tblr_text_item:ne { hline } { [#1][#2](##1) / fg } } + { \__tblr_spec_item:ne { hline } { [#1][#2](##1) / fg } } \tl_if_empty:NF \l__tblr_f_tl { \color{\l__tblr_f_tl} } \__tblr_get_hline_segment_child:nnn {#1} {#2} {##1} } @@ -4009,10 +5221,10 @@ \cs_new_protected:Npn \__tblr_get_col_outer_width_border_width:nNN #1 #2 #3 { \dim_set:Nn #3 - { \__tblr_text_item:ne { vline } { [\int_eval:n {#1 + 1}] / @vline-width } } + { \__tblr_spec_item:ne { vline } { [\int_eval:n {#1 + 1}] / @vline-width } } \dim_set:Nn #2 { - \__tblr_text_item:ne { vline } { [#1] / @vline-width } + \__tblr_spec_item:ne { vline } { [#1] / @vline-width } + \__tblr_data_item:nen { column } {#1} { leftsep } + @@ -4032,6 +5244,8 @@ %% Build current row, #1: row number \cs_new_protected:Npn \__tblr_build_row:N #1 { + \int_set:Nn \c@rownum {#1} + \__tblr_update_rowsep_registers: \__tblr_get_row_inner_height_depth:VNNNN #1 \l__tblr_row_ht_dim \l__tblr_row_dp_dim \l__tblr_row_abovesep_dim \l__tblr_row_belowsep_dim @@ -4078,9 +5292,9 @@ \cs_new_protected:Npn \__tblr_build_vline_segment:nn #1 #2 { \tl_set:Nx \l__tblr_n_tl - { \__tblr_text_item:ne { vline } { [#2] / @vline-count } } + { \__tblr_spec_item:ne { vline } { [#2] / @vline-count } } \tl_set:Nx \l__tblr_o_tl - { \__tblr_text_item:ne { vline } { [#1][#2] / omit } } + { \__tblr_spec_item:ne { vline } { [#1][#2] / omit } } \tl_if_empty:NTF \l__tblr_o_tl { \int_compare:nNnT { \l__tblr_n_tl } > {0} @@ -4093,7 +5307,7 @@ \cs_new_protected:Npn \__tblr_build_vline_segment_omit:nn #1 #2 { \tl_set:Nx \l__tblr_w_tl - { \__tblr_text_item:ne { vline } { [#2] / @vline-width } } + { \__tblr_spec_item:ne { vline } { [#2] / @vline-width } } \skip_horizontal:N \l__tblr_w_tl } @@ -4103,10 +5317,10 @@ \cs_new_protected:Npn \__tblr_build_vline_segment_real:nn #1 #2 { \tl_set:Nx \l__tblr_s_tl - { \__tblr_prop_item:ne { table } { rulesep } } + { \__tblr_prop_item:ne { inner } { rulesep } } \tl_set:Nx \l__tblr_b_tl { - \__tblr_text_item:ne { hline } + \__tblr_spec_item:ne { hline } { [\int_eval:n{#1 + 1}](1) / @hline-height } } \tl_if_empty:NT \l__tblr_b_tl { \tl_set:Nn \l__tblr_b_tl { 0pt } } @@ -4115,12 +5329,12 @@ \int_step_inline:nn { \l__tblr_n_tl } { \tl_set:Nx \l__tblr_w_tl - { \__tblr_text_item:ne { vline } { [#2](##1) / @vline-width } } + { \__tblr_spec_item:ne { vline } { [#2](##1) / @vline-width } } \vbox_set_to_ht:Nnn \l__tblr_b_box { \dim_eval:n { \l__tblr_row_ht_dim + \l__tblr_row_dp_dim } } { \tl_set:Nx \l__tblr_f_tl - { \__tblr_text_item:ne { vline } { [#1][#2](##1) / fg } } + { \__tblr_spec_item:ne { vline } { [#1][#2](##1) / fg } } \tl_if_empty:NF \l__tblr_f_tl { \color{\l__tblr_f_tl} } \__tblr_get_vline_segment_child:nnnxx {#1} {#2} {##1} { \dim_eval:n { \l__tblr_row_ht_dim } } @@ -4146,8 +5360,8 @@ \cs_new_protected:Npn \__tblr_build_cell:NN #1 #2 { - \int_set:Nn \c@rownum {#1} \int_set:Nn \c@colnum {#2} + \__tblr_update_colsep_registers: \group_begin: \tl_set:Nx \l__tblr_w_tl { \__tblr_data_item:nen { column } {#2} { @col-width } } @@ -4305,20 +5519,23 @@ %% #1: row number; #2: column number; #3: dimen register for rowsep above. %% #4: dimen register for total height; #5: dimen register for rowsep below. %% We can use \l__tblr_row_item_skip_size_prop which was made before +%% But when vspan=even, there are no itemskip in the prop list. +%% Therefore we need to calculate them from the sizes of items and skips \cs_new_protected:Npn \__tblr_get_span_vertical_sizes:NNNNN #1 #2 #3 #4 #5 { \dim_set:Nn #3 { \__tblr_data_item:nen { row } {#1} { abovesep } } \dim_zero:N #4 - \int_step_inline:nnn { #1 } { #1 + \l__tblr_cell_rowspan_tl - 2 } - { - \dim_add:Nn #4 - { \prop_item:Ne \l__tblr_row_item_skip_size_prop { itemskip[##1] } } - } \dim_add:Nn #4 + { \prop_item:Ne \l__tblr_row_item_skip_size_prop { item[#1] } } + \int_step_inline:nnn { #1 + 1 } { #1 + \l__tblr_cell_rowspan_tl - 1 } { - \prop_item:Ne \l__tblr_row_item_skip_size_prop - { item[\int_eval:n { #1 + \l__tblr_cell_rowspan_tl - 1 }] } + \dim_add:Nn #4 + { + \prop_item:Ne \l__tblr_row_item_skip_size_prop { skip[##1] } + + + \prop_item:Ne \l__tblr_row_item_skip_size_prop { item[##1] } + } } \dim_set:Nn #5 { @@ -4331,28 +5548,24 @@ %% #1: row number; #2: column number; #3: dimen register for colsep left. %% #4: dimen register for total width; #5: dimen register for colsep right. %% We can use \l__tblr_col_item_skip_size_prop which was made before -%% But when hspan=minimal, there are no itemskip in the prop list. +%% But when hspan=even or hspan=minimal, there are no itemskip in the prop list. %% Therefore we need to calculate them from the sizes of items and skips \cs_new_protected:Npn \__tblr_get_span_horizontal_sizes:NNNNN #1 #2 #3 #4 #5 { \dim_set:Nn #3 { \__tblr_data_item:nen { column } {#2} { leftsep } } \dim_zero:N #4 - \int_step_inline:nnn { #2 } { #2 + \l__tblr_cell_colspan_tl - 2 } + \dim_add:Nn #4 + { \prop_item:Ne \l__tblr_col_item_skip_size_prop { item[#2] } } + \int_step_inline:nnn { #2 + 1 } { #2 + \l__tblr_cell_colspan_tl - 1 } { \dim_add:Nn #4 - { \prop_item:Ne \l__tblr_col_item_skip_size_prop { item[##1] } } - \dim_add:Nn #4 { - \prop_item:Ne \l__tblr_col_item_skip_size_prop - { skip[\int_eval:n { ##1 + 1 }] } + \prop_item:Ne \l__tblr_col_item_skip_size_prop { skip[##1] } + + + \prop_item:Ne \l__tblr_col_item_skip_size_prop { item[##1] } } } - \dim_add:Nn #4 - { - \prop_item:Ne \l__tblr_col_item_skip_size_prop - { item[\int_eval:n { #2 + \l__tblr_cell_colspan_tl - 1 }] } - } \dim_set:Nn #5 { \__tblr_data_item:nen { column } @@ -4373,7 +5586,10 @@ \bool_new:N \g__tblr_tracing_text_bool \bool_new:N \g__tblr_tracing_command_bool -\bool_new:N \g__tblr_tracing_table_bool +\bool_new:N \g__tblr_tracing_option_bool +\bool_new:N \g__tblr_tracing_theme_bool +\bool_new:N \g__tblr_tracing_outer_bool +\bool_new:N \g__tblr_tracing_inner_bool \bool_new:N \g__tblr_tracing_column_bool \bool_new:N \g__tblr_tracing_row_bool \bool_new:N \g__tblr_tracing_cell_bool @@ -4384,6 +5600,10 @@ \bool_new:N \g__tblr_tracing_target_bool \bool_new:N \g__tblr_tracing_cellspan_bool \bool_new:N \g__tblr_tracing_intarray_bool +\bool_new:N \g__tblr_tracing_page_bool +\bool_new:N \g__tblr_tracing_step_bool + +\bool_gset_true:N \g__tblr_tracing_step_bool \keys_define:nn { tblr-set-tracing } { @@ -4391,8 +5611,14 @@ -text .code:n = \bool_gset_false:N \g__tblr_tracing_text_bool, +command .code:n = \bool_gset_true:N \g__tblr_tracing_command_bool, -command .code:n = \bool_gset_false:N \g__tblr_tracing_command_bool, - +table .code:n = \bool_gset_true:N \g__tblr_tracing_table_bool, - -table .code:n = \bool_gset_false:N \g__tblr_tracing_table_bool, + +option .code:n = \bool_gset_true:N \g__tblr_tracing_option_bool, + -option .code:n = \bool_gset_false:N \g__tblr_tracing_option_bool, + +theme .code:n = \bool_gset_true:N \g__tblr_tracing_theme_bool, + -theme .code:n = \bool_gset_false:N \g__tblr_tracing_theme_bool, + +outer .code:n = \bool_gset_true:N \g__tblr_tracing_outer_bool, + -outer .code:n = \bool_gset_false:N \g__tblr_tracing_outer_bool, + +inner .code:n = \bool_gset_true:N \g__tblr_tracing_inner_bool, + -inner .code:n = \bool_gset_false:N \g__tblr_tracing_inner_bool, +column .code:n = \bool_gset_true:N \g__tblr_tracing_column_bool, -column .code:n = \bool_gset_false:N \g__tblr_tracing_column_bool, +row .code:n = \bool_gset_true:N \g__tblr_tracing_row_bool, @@ -4413,6 +5639,10 @@ -cellspan .code:n = \bool_gset_false:N \g__tblr_tracing_cellspan_bool, +intarray .code:n = \bool_gset_true:N \g__tblr_tracing_intarray_bool, -intarray .code:n = \bool_gset_false:N \g__tblr_tracing_intarray_bool, + +page .code:n = \bool_gset_true:N \g__tblr_tracing_page_bool, + -page .code:n = \bool_gset_false:N \g__tblr_tracing_page_bool, + +step .code:n = \bool_gset_true:N \g__tblr_tracing_step_bool, + -step .code:n = \bool_gset_false:N \g__tblr_tracing_step_bool, all .code:n = \__tblr_enable_all_tracings:, none .code:n = \__tblr_disable_all_tracings:, } @@ -4421,7 +5651,10 @@ { \bool_gset_true:N \g__tblr_tracing_text_bool \bool_gset_true:N \g__tblr_tracing_command_bool - \bool_gset_true:N \g__tblr_tracing_table_bool + \bool_gset_true:N \g__tblr_tracing_option_bool + \bool_gset_true:N \g__tblr_tracing_theme_bool + \bool_gset_true:N \g__tblr_tracing_outer_bool + \bool_gset_true:N \g__tblr_tracing_inner_bool \bool_gset_true:N \g__tblr_tracing_column_bool \bool_gset_true:N \g__tblr_tracing_row_bool \bool_gset_true:N \g__tblr_tracing_cell_bool @@ -4432,13 +5665,18 @@ \bool_gset_true:N \g__tblr_tracing_target_bool \bool_gset_true:N \g__tblr_tracing_cellspan_bool \bool_gset_true:N \g__tblr_tracing_intarray_bool + \bool_gset_true:N \g__tblr_tracing_page_bool + \bool_gset_true:N \g__tblr_tracing_step_bool } \cs_new_protected_nopar:Npn \__tblr_disable_all_tracings: { \bool_gset_false:N \g__tblr_tracing_text_bool \bool_gset_false:N \g__tblr_tracing_command_bool - \bool_gset_false:N \g__tblr_tracing_table_bool + \bool_gset_false:N \g__tblr_tracing_option_bool + \bool_gset_false:N \g__tblr_tracing_theme_bool + \bool_gset_false:N \g__tblr_tracing_outer_bool + \bool_gset_false:N \g__tblr_tracing_inner_bool \bool_gset_false:N \g__tblr_tracing_column_bool \bool_gset_false:N \g__tblr_tracing_row_bool \bool_gset_false:N \g__tblr_tracing_cell_bool @@ -4449,6 +5687,8 @@ \bool_gset_false:N \g__tblr_tracing_target_bool \bool_gset_false:N \g__tblr_tracing_cellspan_bool \bool_gset_false:N \g__tblr_tracing_intarray_bool + \bool_gset_false:N \g__tblr_tracing_page_bool + \bool_gset_false:N \g__tblr_tracing_step_bool } \NewDocumentCommand \LogTabularrayTracing { m } @@ -4459,6 +5699,7 @@ \keys_define:nn { tblr-log-tracing } { + step .code:n = \__tblr_log_tracing_step:n {#1}, unknown .code:n = \__tblr_log_tracing:N \l_keys_key_str } @@ -4470,7 +5711,7 @@ \cs_new_protected:Npn \__tblr_log_tracing_text: { - \__tblr_text_log:n { text } + \__tblr_spec_log:n { text } } \cs_new_protected:Npn \__tblr_log_tracing_command: @@ -4478,9 +5719,26 @@ \__tblr_prop_log:n { command } } -\cs_new_protected:Npn \__tblr_log_tracing_table: +\cs_new_protected:Npn \__tblr_log_tracing_option: + { + \__tblr_prop_log:n { note } + \__tblr_prop_log:n { remark } + \__tblr_prop_log:n { more } + } + +\cs_new_protected:Npn \__tblr_log_tracing_theme: + { + \__tblr_style_log: + } + +\cs_new_protected:Npn \__tblr_log_tracing_outer: { - \__tblr_prop_log:n { table } + \__tblr_spec_log:n { outer } + } + +\cs_new_protected:Npn \__tblr_log_tracing_inner: + { + \__tblr_prop_log:n { inner } } \cs_new_protected:Npn \__tblr_log_tracing_column: @@ -4500,12 +5758,12 @@ \cs_new_protected:Npn \__tblr_log_tracing_vline: { - \__tblr_text_log:n { vline } + \__tblr_spec_log:n { vline } } \cs_new_protected:Npn \__tblr_log_tracing_hline: { - \__tblr_text_log:n { hline } + \__tblr_spec_log:n { hline } } \cs_new_protected:Npn \__tblr_log_tracing_colspec: @@ -4537,9 +5795,124 @@ \prop_log:N \l__tblr_row_span_to_row_prop } +\cs_new_protected:Npn \__tblr_log_tracing_page: + { + \dim_log:N \pagegoal + \dim_log:N \pagetotal + } + +\cs_new_protected:Npn \__tblr_log_tracing_step:n #1 + { + \bool_if:NT \g__tblr_tracing_step_bool { \tl_log:x {Step :~ #1} } + } + \cs_new_protected:Npn \__tblr_do_if_tracing:nn #1 #2 { \bool_if:cT { g__tblr_tracing_ #1 _bool } {#2} } +%%% -------------------------------------------------------- +%% \section{Tabularray Libraries} +%%% -------------------------------------------------------- + +%% \NewTblrLibrary and \UseTblrLibrary commands + +\NewDocumentCommand \NewTblrLibrary { m m } + { + \cs_new_protected:cpn { __tblr_use_lib_ #1: } {#2} + } + +\NewDocumentCommand \UseTblrLibrary { m } + { + \clist_map_inline:nn {#1} { \use:c { __tblr_use_lib_ ##1: } } + } + +%% Library booktabs and commands \toprule, \midrule, \bottomrule + +\NewTblrLibrary { booktabs } + { + \NewTableCommand \toprule [1] [] { \hline [0.08em, ##1] } + \NewTableCommand \midrule [1] [] { \hline [0.05em, ##1] } + \NewTableCommand \bottomrule [1] [] { \hline [0.08em, ##1] } + \NewTableCommand \cmidrule [2] [] { \cline [0.03em, ##1] { ##2 } } + } + +%% Library diagbox and command \diagbox + +\NewTblrLibrary { diagbox } + { + \RequirePackage{ diagbox } + \cs_set_eq:NN \__tblr_lib_saved_diagbox:w \diagbox + \NewContentCommand \diagbox [3] [] + { + \__tblr_lib_diagbox_fix:n + { + \__tblr_lib_saved_diagbox:w + [ leftsep=\leftsep, rightsep=\rightsep, ##1 ] + { \__tblr_lib_diagbox_math_or_text:n {##2} } + { \__tblr_lib_diagbox_math_or_text:n {##3} } + } + } + \NewContentCommand \diagboxthree [4] [] + { + \__tblr_lib_diagbox_fix:n + { + \__tblr_lib_saved_diagbox:w + [ leftsep=\leftsep, rightsep=\rightsep, ##1 ] + { \__tblr_lib_diagbox_math_or_text:n {##2} } + { \__tblr_lib_diagbox_math_or_text:n {##3} } + { \__tblr_lib_diagbox_math_or_text:n {##4} } + } + } + } + +\cs_new_protected:Npn \__tblr_lib_diagbox_math_or_text:n #1 + { + \bool_if:NTF \l__tblr_math_mode_bool {$#1$} {#1} + } + +\box_new:N \l__tblr_diag_box + +\cs_new_protected:Npn \__tblr_lib_diagbox_fix:n #1 + { + \hbox_set:Nn \l__tblr_diag_box {#1} + \box_set_ht:Nn \l__tblr_diag_box { \box_ht:N \l__tblr_diag_box - \abovesep } + \box_set_dp:Nn \l__tblr_diag_box { \box_dp:N \l__tblr_diag_box - \belowsep } + \box_use:N \l__tblr_diag_box + } + +%% Library siunitx and S columns + +\NewTblrLibrary { siunitx } + { + \RequirePackage { siunitx } + \NewColumnType { S } [1] [] { Q[si = {##1}] } + \__tblr_data_new_key:nnn { cell } { si } { str } + \keys_define:nn { tblr-column } + { + si .code:n = \__tblr_siunitx_setcolumn:n {##1} + } + \cs_new_protected:Npn \__tblr_siunitx_setcolumn:n ##1 + { + \__tblr_column_gput_cell:nn { si } {##1} + \__tblr_process_text_for_every_column_cell:n { \__tblr_siunitx_tablenum:n } + } + \cs_new_protected:Npn \__tblr_siunitx_tablenum:n ##1 + { + \tl_if_head_is_group:nTF {##1} + { ##1 } + { + \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 + \tablenum {##1} + \group_end: + } + } + } + \ExplSyntaxOff |