diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/tabularray/tabularray.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/tabularray/tabularray.sty | 909 |
1 files changed, 591 insertions, 318 deletions
diff --git a/Master/texmf-dist/tex/latex/tabularray/tabularray.sty b/Master/texmf-dist/tex/latex/tabularray/tabularray.sty index f5ad547d716..5ec77339f3b 100644 --- a/Master/texmf-dist/tex/latex/tabularray/tabularray.sty +++ b/Master/texmf-dist/tex/latex/tabularray/tabularray.sty @@ -1,49 +1,65 @@ %%% % -*- coding: utf-8 -*- %%% ---------------------------------------------------------------------------- %%% Tabularray: Typeset tabulars and arrays with LaTeX3 -%%% Author : Jianrui Lyu <tolvjr@163.com> +%%% Copyright : 2021-2022 (c) Jianrui Lyu <tolvjr@163.com> %%% Repository: https://github.com/lvjr/tabularray %%% License : The LaTeX Project Public License 1.3 %%% ---------------------------------------------------------------------------- %%% -------------------------------------------------------- -%% \section{Scratch Variables and Function Variants} +%%> \section{Scratch Variables and Function Variants} %%% -------------------------------------------------------- -\NeedsTeXFormat{LaTeX2e} +%% \DeclareRelease and \DeclareCurrentRelease are added in LaTeX 2018-04-01 +\NeedsTeXFormat{LaTeX2e}[2018-04-01] +\DeclareRelease{v2021}{}{tabularray-2021.sty} +\DeclareCurrentRelease{}{2022-01-01} + \RequirePackage{expl3} -\ProvidesExplPackage{tabularray}{2021-12-01}{2021Q} +\ProvidesExplPackage{tabularray}{2022-03-01}{2022A} {Typeset tabulars and arrays with LaTeX3} -\RequirePackage{xparse} - -\AtBeginDocument{\@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{}} - -%% Backport \tl_if_eq:NnTF for old texlive 2020 -\cs_if_exist:NF \tl_if_eq:NnTF +%% \IfFormatAtLeastTF, xparse and lthooks are added in LaTeX 2020-10-01 +%% Note that \@ifl@t@r or \@ifpackagelater means 'this date or later' +\msg_new:nnn { tabularray } { latex-too-old } { - \tl_new:N \l__tblr_backport_b_tl - \prg_new_protected_conditional:Npnn \tl_if_eq:Nn #1 #2 { T, F, TF } - { - \group_begin: - \tl_set:Nn \l__tblr_backport_b_tl {#2} - \exp_after:wN - \group_end: - \if_meaning:w #1 \l__tblr_backport_b_tl - \prg_return_true: - \else: - \prg_return_false: - \fi: - } - \prg_generate_conditional_variant:Nnn \tl_if_eq:Nn { c } { TF, T, F } + Your ~ LaTeX ~ release ~ is ~ too ~ old. \\ + Please ~ update ~ to ~ 2020-10-01 ~ first. + } +\@ifl@t@r\fmtversion{2020-10-01}{}{ + %% Support TeX Live 2020 on Overleaf + \msg_warning:nn { tabularray } { latex-too-old } + \usepackage{xparse} +} + +\AtBeginDocument{ + \@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{} + \@ifpackageloaded{hyperref}{ + \newenvironment{tblrNoHyper}{\NoHyper}{\endNoHyper} + }{ + \newenvironment{tblrNoHyper}{}{} } +} -%% Compatible with texlive 2020 -\cs_if_exist:NF \seq_map_indexed_function:NN +\NewDocumentCommand \TblrParboxRestore { } { \@parboxrestore } + +\NewDocumentCommand \TblrAlignBoth { } { - \cs_set_eq:NN \seq_map_indexed_function:NN \seq_indexed_map_function:NN + \let \\ = \@normalcr + \leftskip = \z@skip + \@rightskip = \z@skip + \rightskip = \@rightskip + \parfillskip = \@flushglue } +\NewDocumentCommand \TblrAlignLeft { } { \raggedright } + +\NewDocumentCommand \TblrAlignCenter { } { \centering } + +\NewDocumentCommand \TblrAlignRight { } { \raggedleft } + +\cs_set_eq:NN \TblrNewPage \newpage + \cs_generate_variant:Nn \msg_error:nnnn { nnVn } \cs_generate_variant:Nn \prop_item:Nn { Ne, NV } \cs_generate_variant:Nn \prop_put:Nnn { Nxn, Nxx, NxV } @@ -55,6 +71,7 @@ \cs_generate_variant:Nn \tl_put_left:Nn { Nv } \prg_generate_conditional_variant:Nnn \clist_if_in:Nn { Nx } { TF } \prg_generate_conditional_variant:Nnn \prop_if_in:Nn { c } { T } +\prg_generate_conditional_variant:Nnn \regex_match:Nn { NV } { TF } \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 } @@ -102,9 +119,10 @@ \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 +\cs_new_eq:NN \__tblr_halign_command_j: \TblrAlignBoth +\cs_new_eq:NN \__tblr_halign_command_l: \TblrAlignLeft +\cs_new_eq:NN \__tblr_halign_command_c: \TblrAlignCenter +\cs_new_eq:NN \__tblr_halign_command_r: \TblrAlignRight %% Some counters for row and column numbering. %% We may need to restore all LaTeX counters in measuring and building cells, @@ -127,7 +145,7 @@ \dim_new:N \rightsep %%% -------------------------------------------------------- -%% \section{Data Structures Based on Property Lists} +%%> \section{Data Structures Based on Property Lists} %%% -------------------------------------------------------- \int_new:N \g_tblr_level_int % store table nesting level @@ -238,7 +256,7 @@ \cs_generate_variant:Nn \__tblr_gadd_dimen_value:Nnn { cnn } %%% -------------------------------------------------------- -%% \section{Data Structures Based on Token Lists} +%%> \section{Data Structures Based on Token Lists} %%% -------------------------------------------------------- \cs_new_protected:Npn \__tblr_clear_spec_lists: @@ -318,7 +336,7 @@ } %%% -------------------------------------------------------- -%% \section{Data Structures Based on Integer Arrays} +%%> \section{Data Structures Based on Integer Arrays} %%% -------------------------------------------------------- \msg_new:nnn { tabularray } { intarray-beyond-bound } @@ -362,7 +380,6 @@ \__tblr_data_new_key:nnn { row } { @row-foot } { dim } \__tblr_data_new_key:nnn { row } { @row-upper } { dim } \__tblr_data_new_key:nnn { row } { @row-lower } { dim } -\__tblr_data_new_key:nnn { row } { break } { int } \int_new:N \g__tblr_data_column_key_count_int \__tblr_data_new_key:nnn { column } { width } { dim } @@ -763,7 +780,7 @@ } %%% -------------------------------------------------------- -%% \section{Child Selectors} +%%> \section{Child Selectors} %%% -------------------------------------------------------- \clist_new:N \g_tblr_used_child_selectors_clist @@ -810,15 +827,42 @@ \clist_new:N \l_tblr_childs_clist \tl_new:N \l_tblr_childs_total_tl -\NewChildSelector { odd } +\NewChildSelector { odd } [1] [] { - \int_step_inline:nnnn {1} {2} { \l_tblr_childs_total_tl } - { \clist_put_right:Nn \l_tblr_childs_clist {##1} } + \tl_if_blank:nTF {#1} + { + \int_step_inline:nnnn {1} {2} { \l_tblr_childs_total_tl } + { \clist_put_right:Nn \l_tblr_childs_clist {##1} } + } + { \__tblr_child_selector_odd_or_even:nn { odd } {#1} } } -\NewChildSelector { even } +\NewChildSelector { even } [1] [] { - \int_step_inline:nnnn {2} {2} { \l_tblr_childs_total_tl } + \tl_if_blank:nTF {#1} + { + \int_step_inline:nnnn {2} {2} { \l_tblr_childs_total_tl } + { \clist_put_right:Nn \l_tblr_childs_clist {##1} } + } + { \__tblr_child_selector_odd_or_even:nn { even } {#1} } + } + +\tl_new:N \l__tblr_child_from_tl +\tl_new:N \l__tblr_child_to_tl + +%% #1: odd or even; #2: selector option +\cs_new_protected:Npn \__tblr_child_selector_odd_or_even:nn #1 #2 + { + \seq_set_split:Nnn \l_tmpa_seq {-} { #2 - Z } + \tl_set:Nx \l__tblr_child_from_tl { \seq_item:Nn \l_tmpa_seq {1} } + \tl_set:Nx \l__tblr_child_to_tl { \seq_item:Nn \l_tmpa_seq {2} } + \tl_use:c { int_if_ #1 :nF } { \l__tblr_child_from_tl } + { + \tl_set:Nx \l__tblr_child_from_tl + { \int_eval:n { \l__tblr_child_from_tl + 1 } } + } + \__tblr_child_name_to_index:VN \l__tblr_child_to_tl \l__tblr_child_to_tl + \int_step_inline:nnnn { \l__tblr_child_from_tl } {2} { \l__tblr_child_to_tl } { \clist_put_right:Nn \l_tblr_childs_clist {##1} } } @@ -842,7 +886,7 @@ __tblr_child_selector_ \seq_item:Nn \l__tblr_childs_regex_seq {2} :w \cs_end: } - \exp_args:Nx \l__tblr_childs_selector_tl + \exp_last_unbraced:Nx \l__tblr_childs_selector_tl { \seq_item:Nn \l__tblr_childs_regex_seq{3} } } { @@ -865,9 +909,6 @@ } } -\tl_new:N \l__tblr_child_from_tl -\tl_new:N \l__tblr_child_to_tl - \cs_new_protected_nopar:Npn \__tblr_get_childs_normal_aux:w #1 - #2 \scan_stop { \__tblr_child_name_to_index:nN {#1} \l__tblr_child_from_tl @@ -888,9 +929,10 @@ } { \tl_set:Nx #2 { #1 } } } +\cs_generate_variant:Nn \__tblr_child_name_to_index:nN { VN } %%% -------------------------------------------------------- -%% \section{New Table Commands} +%%> \section{New Table Commands} %%% -------------------------------------------------------- %% We need some commands to modify table/row/column/cell specifications. @@ -985,7 +1027,7 @@ { \clist_if_in:NnTF \g__tblr_content_commands_clist { #1 } { - \msg_warning:nnn { tabularray } { defined-content-command } { #1 } + \msg_error:nnn { tabularray } { defined-content-command } { #1 } \clist_log:N \g__tblr_content_commands_clist } { @@ -1003,7 +1045,7 @@ } %%% -------------------------------------------------------- -%% \section{New Dash Styles} +%%> \section{New Dash Styles} %%% -------------------------------------------------------- %% \NewDashStyle commands @@ -1073,7 +1115,7 @@ \NewDashStyle {dotted} {on ~ 0.4pt ~ off ~ 1pt} %%% -------------------------------------------------------- -%% \section{Set Hlines and Vlines} +%%> \section{Set Hlines and Vlines} %%% -------------------------------------------------------- \tl_set:Nn \@tblr@dash { dash } @@ -1128,10 +1170,6 @@ \NewTableCommand \hline [1] [] { \SetHline [+] {-} {#1} } -%% Some keys can be set by any hline, such as abovespace and belowspace keys. -%% Using special hline of index 0, you can set these keys without adding any hlines. -\NewTableCommand \SetVspace [1] { \SetHline [0] {-} {#1} } - %% #1: the index of the hline (may be + or =) %% #2: which columns of the hline, separate by commas %% #3: key=value pairs @@ -1145,19 +1183,13 @@ \cs_new_protected:Npn \tblr_set_hline:nnn #1 #2 #3 { \group_begin: - %% We can not use \int_compare:nNnTF here since #1 may be + or = . - %% Also we treat hline of index 0 specially, not adding hline count. - \tl_if_eq:nnTF {#1} {0} - { \keys_set:nn { tblr-hline } {#3} } + \keys_set_groups:nnn { tblr-hline } { text } {#3} + \tl_if_eq:NnF \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text } { - \keys_set_groups:nnn { tblr-hline } { text } {#3} - \tl_if_eq:NnF \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text } - { - \__tblr_set_hline_num:n {#1} - \tl_clear:N \l__tblr_hline_dash_tl - \keys_set:nn { tblr-hline } { dash = solid, #3 } - \__tblr_set_hline_cmd:n {#2} - } + \__tblr_set_hline_num:n {#1} + \tl_clear:N \l__tblr_hline_dash_tl + \keys_set:nn { tblr-hline } { dash = solid, #3 } + \__tblr_set_hline_cmd:n {#2} } \group_end: } @@ -1233,7 +1265,6 @@ text .groups:n = { text }, wd .code:n = \tl_set:Nn \l__tblr_hline_wd_tl { \dim_eval:n {#1} }, fg .code:n = \tl_set:Nn \l__tblr_hline_fg_tl {#1}, - baseline .code:n = \__tblr_hline_set_baseline:n {#1}, leftpos .code:n = \tl_set:Nx \l__tblr_hline_leftpos_tl {#1}, rightpos .code:n = \tl_set:Nx \l__tblr_hline_rightpos_tl {#1}, l .meta:n = { leftpos = #1 }, @@ -1243,12 +1274,6 @@ lr .meta:n = { leftpos = #1, rightpos = #1 }, lr .default:n = { -0.8 }, endpos .bool_set:N = \l__tblr_hline_endpos_bool, - abovespace .code:n = \__tblr_row_gput_above:ne { belowsep } { \dim_eval:n {#1} }, - belowspace .code:n = \__tblr_row_gput:ne { abovesep } { \dim_eval:n {#1} }, - abovespace+ .code:n = \__tblr_row_gadd_dimen_above:ne - { belowsep } { \dim_eval:n {#1} }, - belowspace+ .code:n = \__tblr_row_gadd_dimen:ne - { abovesep } { \dim_eval:n {#1} }, unknown .code:n = \__tblr_hline_unknown_key:V \l_keys_key_str, } @@ -1325,22 +1350,20 @@ { [\int_use:N \c@rownum][#1](\l__tblr_hline_num_tl) / #2 } { #3 } } -\NewTableCommand \firsthline [1] [] { \SetHline [+] {-} { #1, baseline=below } } -\NewTableCommand \lasthline [1] [] { \SetHline [+] {-} { #1, baseline=above } } +\msg_new:nnn { tabularray } { obsolete-firsthline } + { \firsthline ~ is ~ obsolete; ~ use ~ 'baseline=T' ~ instead. } -\cs_new_protected:Npn \__tblr_hline_set_baseline:n #1 +\msg_new:nnn { tabularray } { obsolete-lasthline } + { \lasthline ~ is ~ obsolete; ~ use ~ 'baseline=B' ~ instead. } + +\NewTableCommand \firsthline [1] [] { - \tl_if_eq:nnTF {#1} {above} - { - \__tblr_prop_gput:nnx { inner } - { baseline } { \int_eval:n { \c@rownum - 1 } } - } - { - \tl_if_eq:nnT {#1} {below} - { - \__tblr_prop_gput:nnx { inner } { baseline } { \int_use:N \c@rownum } - } - } + \msg_error:nn { tabularray } { obsolete-firsthline } + } + +\NewTableCommand \lasthline [1] [] + { + \msg_error:nn { tabularray } { obsolete-lasthline } } %% \SetVlines command for setting every vline in the table @@ -1540,7 +1563,107 @@ } %%% -------------------------------------------------------- -%% \section{Set Cells} +%%> \section{Set Hborders and Vborders} +%%% -------------------------------------------------------- + +%% Hborder holds keys not related to a specified hline +\NewTableCommand \hborder [1] { \tblr_set_hborder:n {#1} } + +\cs_new_protected:Npn \tblr_set_hborder:n #1 + { + \keys_set:nn { tblr-hborder } {#1} + } + +\cs_new_protected:Npn \tblr_set_hborder:nn #1 #2 + { + \group_begin: + \__tblr_get_childs:nx {#1} { \int_eval:n { \c@rowcount + 1 } } + \clist_map_inline:Nn \l_tblr_childs_clist + { + \int_set:Nn \c@rownum {##1} + \tblr_set_hborder:n {#2} + } + \group_end: + } + +%% This function is called when parsing table specifications +%% Note that #1 always includes an outer pair of braces +\cs_new_protected:Npn \__tblr_set_hborder_aux:nn #1 #2 + { + \tblr_set_hborder:nn #1 {#2} + } +\cs_generate_variant:Nn \__tblr_set_hborder_aux:nn { Vn } + +\keys_define:nn { tblr-hborder } + { + abovespace .code:n = \__tblr_row_gput_above:ne + { belowsep } { \dim_eval:n {#1} }, + belowspace .code:n = \__tblr_row_gput:ne { abovesep } { \dim_eval:n {#1} }, + abovespace+ .code:n = \__tblr_row_gadd_dimen_above:ne + { belowsep } { \dim_eval:n {#1} }, + belowspace+ .code:n = \__tblr_row_gadd_dimen:ne + { abovesep } { \dim_eval:n {#1} }, + pagebreak .code:n = \__tblr_hborder_gput_pagebreak:n {#1}, + pagebreak .default:n = yes, + baseline .code:n = \__tblr_outer_gput_spec:ne + { baseline } { - \int_use:N \c@rownum }, + } + +\tl_const:Nn \c__tblr_pagebreak_yes_tl { 1 } +\tl_const:Nn \c__tblr_pagebreak_auto_tl { 0 } +\tl_const:Nn \c__tblr_pagebreak_no_tl { -1 } + +\cs_new_protected:Npn \__tblr_hborder_gput_pagebreak:n #1 + { + \tl_if_exist:cT { c__tblr_pagebreak_ #1 _tl } + { + \__tblr_spec_gput:nee { hline } + { [\int_use:N \c@rownum] / @pagebreak } + { \tl_use:c { c__tblr_pagebreak_ #1 _tl } } + } + } + +%% Vborder holds keys not related to a specified vline +\NewTableCommand \vborder [1] { \tblr_set_vborder:n {#1} } + +\cs_new_protected:Npn \tblr_set_vborder:n #1 + { + \keys_set:nn { tblr-vborder } {#1} + } + +\cs_new_protected:Npn \tblr_set_vborder:nn #1 #2 + { + \group_begin: + \__tblr_get_childs:nx {#1} { \int_eval:n { \c@colcount + 1 } } + \clist_map_inline:Nn \l_tblr_childs_clist + { + \int_set:Nn \c@colnum {##1} + \tblr_set_vborder:n {#2} + } + \group_end: + } + +%% This function is called when parsing table specifications +%% Note that #1 always includes an outer pair of braces +\cs_new_protected:Npn \__tblr_set_vborder_aux:nn #1 #2 + { + \tblr_set_vborder:nn #1 {#2} + } +\cs_generate_variant:Nn \__tblr_set_vborder_aux:nn { Vn } + +\keys_define:nn { tblr-vborder } + { + leftspace .code:n = \__tblr_column_gput_left:ne + { rightsep } { \dim_eval:n {#1} }, + rightspace .code:n = \__tblr_column_gput:ne { leftsep } { \dim_eval:n {#1} }, + leftspace+ .code:n = \__tblr_column_gadd_dimen_left:ne + { rightsep } { \dim_eval:n {#1} }, + rightspace+ .code:n = \__tblr_column_gadd_dimen:ne + { leftsep } { \dim_eval:n {#1} }, + } + +%%% -------------------------------------------------------- +%%> \section{Set Cells} %%% -------------------------------------------------------- %% \SetCells command for setting every cell in the table @@ -1767,7 +1890,7 @@ { 1 } } \int_step_variable:nnNn - { \c@rownum } { \int_eval:n { \c@rownum + #1 -1 } } \l__tblr_i_tl + { \c@rownum } { \int_eval:n { \c@rownum + #1 - 2 } } \l__tblr_i_tl { \__tblr_spec_gput:nee { vline } { [\l__tblr_i_tl][\int_use:N \c@colnum](\l__tblr_n_tl) / belowpos } {1} @@ -1777,59 +1900,26 @@ } \cs_generate_variant:Nn \__tblr_set_span_spec:nn { VV } -%% Legacy \multicolumn and \multirow commands -%% Both of them could be replaced with \SetCell command -%% Note that they don't have cell text as the last arguments +%% Obsolete \multicolumn and \multirow commands + +\msg_new:nnn { tabularray } { obsolete-multicolumn } + { \multicolumn ~ is ~ obsolete; ~ use ~ \SetCell ~ instead. } -%% If \multicolumn is followed by \multirow, -%% We need to call \tblr_set_cell together -%% in order to omit all hlines inside the span cell. -\tl_new:N \g__tblr_multicolumn_num_tl -\tl_new:N \g__tblr_multicolumn_spec_tl +\msg_new:nnn { tabularray } { obsolete-multirow } + { \multirow ~ is ~ obsolete; ~ use ~ \SetCell ~ instead. } -%% There maybe p{2em} inside #2 of \multicolumn command \NewTableCommand \multicolumn [2] { - \tl_gclear:N \g__tblr_multicolumn_num_tl - \tl_gclear:N \g__tblr_multicolumn_spec_tl - \tl_map_inline:nn {#2} - { - \bool_lazy_and:nnF - { \tl_if_single_token_p:n {##1} } - { \token_if_eq_charcode_p:NN ##1 | } - { \tl_put_right:Nn \g__tblr_multicolumn_spec_tl {,##1} } - } - \peek_meaning:NTF \multirow - { \tl_gset:Nn \g__tblr_multicolumn_num_tl {#1} } - { \tblr_set_cell:nV { c = #1 } \g__tblr_multicolumn_spec_tl } + \msg_error:nn { tabularray } { obsolete-multicolumn } } \NewTableCommand \multirow [3] [m] { - \tl_if_eq:nnTF {#1} {c} - { \tl_set:Nn \l_tmpa_tl {, m} } - { - \tl_if_eq:nnTF {#1} {t} - { \tl_set:Nn \l_tmpa_tl {, h} } - { \tl_if_eq:nnTF {#1} {b} - { \tl_set:Nn \l_tmpa_tl {, f} } - { \tl_set:Nn \l_tmpa_tl {, #1} } - } - } - \tl_if_eq:nnF {#3} {*} - { \tl_if_eq:nnF {#3} {=} { \tl_put_right:Nn \l_tmpa_tl {, wd=#3} } } - \tl_if_empty:NTF \g__tblr_multicolumn_num_tl - { \tblr_set_cell:nV { r = #2 } \l_tmpa_tl } - { - \tl_put_left:NV \l_tmpa_tl \g__tblr_multicolumn_spec_tl - \exp_args:Nx \tblr_set_cell:nV - { c = \g__tblr_multicolumn_num_tl, r = #2 } \l_tmpa_tl - \tl_gclear:N \g__tblr_multicolumn_num_tl - } + \msg_error:nn { tabularray } { obsolete-multirow } } %%% -------------------------------------------------------- -%% \section{Set Columns and Rows} +%%> \section{Set Columns and Rows} %%% -------------------------------------------------------- %% \SetColumns command for setting every column in the table @@ -1937,6 +2027,12 @@ } \cs_generate_variant:Nn \__tblr_column_gput:nn { ne } +\cs_new_protected:Npn \__tblr_column_gput_left:nn #1 #2 + { + \__tblr_data_gput:nenn { column } { \int_eval:n { \c@colnum - 1 } } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_column_gput_left:nn { ne } + \cs_new_protected:Npn \__tblr_column_gadd_dimen:nn #1 #2 { \__tblr_data_gadd_dimen_value:nenn { column } @@ -1944,6 +2040,13 @@ } \cs_generate_variant:Nn \__tblr_column_gadd_dimen:nn { ne } +\cs_new_protected:Npn \__tblr_column_gadd_dimen_left:nn #1 #2 + { + \__tblr_data_gadd_dimen_value:nenn { column } + { \int_eval:n { \c@colnum - 1 } } {#1} {#2} + } +\cs_generate_variant:Nn \__tblr_column_gadd_dimen_left:nn { ne } + %% #1: key; #2: value \cs_new_protected:Npn \__tblr_column_gput_cell:nn #1 #2 { @@ -2080,9 +2183,8 @@ 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}, - break .code:n = \__tblr_row_gput:nn { break } {#1}, - pagebreak .meta:n = { break = 1 }, - nopagebreak .meta:n = { break = -1 }, + baseline .code:n = \__tblr_outer_gput_spec:ne + { baseline } { \int_use:N \c@rownum }, unknown .code:n = \__tblr_row_unknown_key:V \l_keys_key_str, } @@ -2158,16 +2260,16 @@ \NewTableCommand \pagebreak { - \tblr_set_row:nn {} { break = 1 } + \hborder { pagebreak = yes } } \NewTableCommand \nopagebreak { - \tblr_set_row:nn {} { break = -1 } + \hborder { pagebreak = no } } %%% -------------------------------------------------------- -%% \section{Column Types and Row Types} +%%> \section{Column Types and Row Types} %%% -------------------------------------------------------- %% Some primitive column/row types @@ -2344,8 +2446,8 @@ \str_if_in:cnTF { g_tblr_used_ \g__tblr_column_or_row_tl _types_str } {#1} { \tl_if_eq:NnTF \g__tblr_column_or_row_tl { row } - { \msg_warning:nnnn { tabularray } { used-colrow-type } { Row } {#1} } - { \msg_warning:nnnn { tabularray } { used-colrow-type } { Column } {#1} } + { \msg_error:nnnn { tabularray } { used-colrow-type } { Row } {#1} } + { \msg_error:nnnn { tabularray } { used-colrow-type } { Column } {#1} } \str_log:c { g_tblr_used_ \g__tblr_column_or_row_tl _types_str } } { @@ -2457,13 +2559,13 @@ } %%% -------------------------------------------------------- -%% \section{Set Environments and New 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, + halign = c, baseline = m, headsep = 6pt, footsep = 6pt, presep = 1.5\bigskipamount, postsep = 1.5\bigskipamount, } @@ -2485,13 +2587,13 @@ %% #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} } { } + \tl_new:c { l__tblr_default_ #1 _inner_tl } + \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 \ignorespaces } @@ -2550,7 +2652,7 @@ } %%% -------------------------------------------------------- -%% \section{Split Table Contents} +%%> \section{Split Table Contents} %%% -------------------------------------------------------- %% Insert and remove braces for nesting environments inside cells @@ -2628,7 +2730,7 @@ { \tl_if_head_eq_meaning:nNTF {##1} * { - \tl_set:Nn \l__tblr_b_tl { \SetRow { break = -1 } } + \tl_set:Nn \l__tblr_b_tl { \hborder { pagebreak = no } } \tl_set:Nx \l__tblr_c_tl { \tl_tail:n {##1} } \tl_trim_spaces:N \l__tblr_c_tl %% Ignore spaces between * and [dimen] \tl_if_head_eq_meaning:VNT \l__tblr_c_tl [ @@ -2681,7 +2783,6 @@ \__tblr_extract_table_commands:N \l_tmpa_tl \__tblr_trim_par_space_tokens:N \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 %% We need to do it here since the > or < column type may add text to cells @@ -2711,26 +2812,12 @@ \regex_replace_once:NnN \c__tblr_trim_right_space_par_regex {} #1 } -%% Add empty cells after the \multicolumn span cell -\cs_new_protected:Npn \__tblr_add_multicolumn_empty_cell: - { - \int_step_inline:nn { \l__multicolumn_cell_number_int - 1 } - { - \int_incr:N \c@colnum - \__tblr_spec_gput:nen { text } - { [\int_use:N \c@rownum][\int_use:N \c@colnum] } { } - } - } - %%% -------------------------------------------------------- -%% \section{Extract Table Commands from Cell Text} +%%> \section{Extract Table Commands from Cell Text} %%% -------------------------------------------------------- %% Extract table commands defined with \NewTableCommand from cell text -\clist_gset:Nn \g__tblr_table_commands_unbrace_next_clist {\multirow, \multicolumn} -\bool_new:N \l__tblr_table_command_unbrace_next_bool -\int_new:N \l__multicolumn_cell_number_int \tl_new:N \l__tblr_saved_table_commands_before_cell_text_tl \tl_new:N \l__tblr_saved_cell_text_after_table_commands_tl @@ -2738,7 +2825,6 @@ { \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:n #1 \q_stop \tl_if_empty:NF \l__tblr_saved_table_commands_before_cell_text_tl { @@ -2755,14 +2841,7 @@ \tl_if_single_token:nTF {#1} { \clist_if_in:NnTF \g__tblr_table_commands_clist { #1 } - { - \clist_if_in:NnTF \g__tblr_table_commands_unbrace_next_clist { #1 } - { \bool_set_true:N \l__tblr_table_command_unbrace_next_bool } - { \bool_set_false:N \l__tblr_table_command_unbrace_next_bool } - \token_if_eq_meaning:NNTF #1 \multicolumn - { \__tblr_extract_multicolumn_command:Nn #1 } - { \__tblr_extract_one_table_command:N #1 } - } + { \__tblr_extract_one_table_command:N #1 } { \token_if_eq_meaning:NNF #1 \q_stop { \__tblr_save_real_cell_text:w #1 } @@ -2771,12 +2850,6 @@ { \__tblr_save_real_cell_text:w {#1} } } -\cs_new_protected:Npn \__tblr_extract_multicolumn_command:Nn #1 #2 - { - \int_set:Nn \l__multicolumn_cell_number_int {#2} - \__tblr_extract_one_table_command:N #1 {#2} - } - \cs_new_protected:Npn \__tblr_extract_one_table_command:N #1 { \int_set:Nn \l__tblr_a_int @@ -2811,15 +2884,9 @@ \int_decr:N \l__tblr_a_int \__tblr_extract_table_command_arg_m:n } - { - \bool_if:NTF \l__tblr_table_command_unbrace_next_bool - { \__tblr_last_unbraced:Nn \__tblr_extract_table_commands_next:n } - { \__tblr_extract_table_commands_next:n } - } + { \__tblr_extract_table_commands_next:n } } -\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 \q_stop { @@ -2827,7 +2894,7 @@ } %%% -------------------------------------------------------- -%% \section{Initialize Table Inner Specifications} +%%> \section{Initialize Table Inner Specifications} %%% -------------------------------------------------------- \prop_gset_from_keyval:Nn \g__tblr_initial_table_prop @@ -2858,7 +2925,7 @@ \prop_gset_from_keyval:Nn \g__tblr_initial_cells_prop { - halign = l, + halign = j, valign = t, width = -1pt, % cell width unset rowspan = 1, @@ -2937,10 +3004,10 @@ \clist_new:N \g__tblr_table_known_keys_clist \clist_gset:Nn \g__tblr_table_known_keys_clist { - colspec, rowspec, width, hspan, vspan, stretch, verb, - column, row, cell, vline, hline, columns, rows, cells, vlines, hlines, + colspec, rowspec, column, row, cell, hline, vline, hborder, vborder, width, + rowhead, rowfoot, columns, rows, cells, hlines, vlines, % hborders, vborders, leftsep, rightsep, colsep, abovesep, belowsep, rowsep, rulesep, - rowhead, rowfoot, + baseline, hspan, vspan, stretch, verb, } \keys_define:nn { tblr } @@ -2967,6 +3034,7 @@ 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}, + baseline .code:n = \__tblr_outer_gput_spec:nn { baseline } {#1}, unknown .code:n = \__tblr_table_special_key:Vn \l_keys_key_str {#1}, } @@ -3007,14 +3075,21 @@ \cs_generate_variant:Nn \__tblr_keys_gput:nn { nx } %%% -------------------------------------------------------- -%% \section{Initialize and Parse Table Outer Specifications} +%%> \section{Initialize and Parse Table Outer Specifications} %%% -------------------------------------------------------- +\msg_new:nnn { tabularray } { used-theme-name } + { theme ~ name ~ #1 ~ has ~ been ~ used! } + %% #1: theme names; #2: template and style commands \NewDocumentCommand \NewTblrTheme { m +m } { - \tl_set:cn { g__tblr_theme_ #1 _code_tl } {#2} - \ignorespaces + \tl_if_exist:cTF { g__tblr_theme_ #1 _code_tl } + { \msg_error:nnn { tabularray } { used-theme-name } { #1 } } + { + \tl_set:cn { g__tblr_theme_ #1 _code_tl } {#2} + \ignorespaces + } } \cs_new_protected:Npn \__tblr_use_theme:n #1 @@ -3038,13 +3113,17 @@ long .code:n = \__tblr_outer_gput_spec:nn { long } { true }, tall .code:n = \__tblr_outer_gput_spec:nn { tall } { true }, halign .code:n = \__tblr_outer_gput_spec:nn { halign } {#1}, - valign .code:n = \__tblr_outer_gput_spec:nn { valign } {#1}, + baseline .code:n = \__tblr_outer_gput_spec:nn { baseline } {#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 }, + t .meta:n = { baseline = t }, + T .meta:n = { baseline = T }, + m .meta:n = { baseline = m }, + M .meta:n = { baseline = M }, + b .meta:n = { baseline = b }, + B .meta:n = { baseline = B }, + valign .meta:n = { baseline = #1 }, % obsolete, will be removed some day expand .code:n = \__tblr_outer_gput_spec:nn { expand } {#1}, headsep .code:n = \__tblr_outer_gput_spec:nn { headsep } {#1}, footsep .code:n = \__tblr_outer_gput_spec:nn { footsep } {#1}, @@ -3061,6 +3140,7 @@ { \__tblr_spec_gput:nen { outer } {#1} {#2} } +\cs_generate_variant:Nn \__tblr_outer_gput_spec:nn { ne } \regex_const:Nn \c__tblr_option_key_name_regex { ^ [A-Za-z\-] + $ } @@ -3102,7 +3182,7 @@ \cs_generate_variant:Nn \__tblr_outer_gput_more:nn { Vn } %%% -------------------------------------------------------- -%% \section{Typeset and Calculate Sizes} +%%> \section{Typeset and Calculate Sizes} %%% -------------------------------------------------------- %% Calculate the width and height for every cell and border @@ -3125,12 +3205,47 @@ \cs_new_protected:Npn \__tblr_make_strut_box: { \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 - { \vrule depth \l__tblr_s_tl \box_dp:N \strutbox width ~ 0pt } + \fp_compare:nNnTF { \l__tblr_s_tl } > {0} + { + \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 + { \vrule depth \l__tblr_s_tl \box_dp:N \strutbox width ~ 0pt } + \cs_set_eq:NN \__tblr_use_strut_ht_box: \__tblr_use_strut_ht_box_real: + \cs_set_eq:NN \__tblr_use_strut_dp_box: \__tblr_use_strut_dp_box_real: + } + { + \fp_compare:nNnTF { \l__tblr_s_tl } < {0} + { + \cs_set_eq:NN \__tblr_use_strut_ht_box: \__tblr_use_strut_ht_box_vmode: + } + { + \cs_set_eq:NN \__tblr_use_strut_ht_box: \__tblr_use_strut_ht_box_hmode: + } + \cs_set_eq:NN \__tblr_use_strut_dp_box: \__tblr_use_strut_dp_box_ignore: + } } +\cs_new_protected:Npn \__tblr_use_strut_ht_box_real: + { + \mode_leave_vertical: + \box_use:N \l__tblr_strut_ht_box + } +\cs_new_protected:Npn \__tblr_use_strut_ht_box_hmode: + { + \mode_leave_vertical: + } +\cs_new_protected:Npn \__tblr_use_strut_ht_box_vmode: + { + \@minipagetrue % for lists (see issue #99) + } + +\cs_new_protected:Npn \__tblr_use_strut_dp_box_real: + { + \box_use:N \l__tblr_strut_dp_box + } +\cs_new_protected:Npn \__tblr_use_strut_dp_box_ignore: { } + %% Calculate the thickness for every hline and vline \cs_new_protected:Npn \__tblr_calculate_line_sizes: { @@ -3207,7 +3322,11 @@ { %% When using text as vline, we need to omit abovepos and belowpos. \unskip - \hbox_set:Nn \l__tblr_d_box { \l__tblr_b_tl } + \hbox_set:Nn \l__tblr_d_box + { + \bool_if:NTF \l__tblr_math_mode_bool + { $ \l__tblr_b_tl $ } { \l__tblr_b_tl } + } \box_set_ht:Nn \l__tblr_d_box {#4} \box_set_dp:Nn \l__tblr_d_box {#5} \box_use:N \l__tblr_d_box @@ -3265,7 +3384,11 @@ \__tblr_get_hline_dash_style:N \l__tblr_b_tl \xleaders \l__tblr_b_tl \hfil } - { \l__tblr_b_tl \hfil } + { + \bool_if:NTF \l__tblr_math_mode_bool + { $ \l__tblr_b_tl $ } { \l__tblr_b_tl } + \hfil + } \group_end: } @@ -3329,6 +3452,7 @@ %% You can use these two counters in cell text \int_zero:N \c@rownum \int_zero:N \c@colnum + \__tblr_save_counters:n { table } \int_step_inline:nn { \c@rowcount } { \int_incr:N \c@rownum @@ -3355,6 +3479,7 @@ \g__tblr_cell_foot_dim } } + \__tblr_restore_counters:n { table } \int_step_inline:nn { \c@colcount } { \tl_set:Nx \l__tblr_w_tl @@ -3388,9 +3513,7 @@ \cs_new_protected:Npn \__tblr_measure_cell_update_sizes:nnNNNN #1 #2 #3 #4 #5 #6 { \__tblr_get_cell_alignments:nn {#1} {#2} - \__tblr_save_counters:n { trial } \hbox_set:Nn \l_tmpa_box { \__tblr_get_cell_text:nn {#1} {#2} } - \__tblr_restore_counters:n { trial } \__tblr_update_cell_size:nnNNNN {#1} {#2} #3 #4 #5 #6 \__tblr_update_row_size:nnNNN {#1} {#2} #4 #5 #6 \__tblr_update_col_size:nN {#2} #3 @@ -3423,13 +3546,21 @@ \cs_new_protected:Npn \__tblr_get_cell_text_real:nn #1 #2 { \group_begin: - \tl_set:Nx \l__tblr_cell_cmd_tl - { \__tblr_data_item:neen { cell } {#1} {#2} { cmd } } - \tl_if_empty:NTF \l__tblr_cell_cmd_tl - { \tl_set:Nx \l__tblr_c_tl { \__tblr_spec_item:ne { text } {[#1][#2]} } } - { - \tl_set:Nx \l__tblr_c_tl { { \__tblr_spec_item:ne { text } {[#1][#2]} } } - \tl_put_left:NV \l__tblr_c_tl \l__tblr_cell_cmd_tl + \tl_set:Nx \l__tblr_c_tl { \__tblr_spec_item:ne { text } {[#1][#2]} } + %% when the cell text is guarded by a pair of curly braces, + %% we unbrace it and ignore cmd option of the cell, see issue #90. + \bool_lazy_and:nnTF + { \tl_if_single_p:N \l__tblr_c_tl } + { \exp_args:NV \tl_if_head_is_group_p:n \l__tblr_c_tl } + { \exp_last_unbraced:NNV \tl_set:Nn \l__tblr_c_tl \l__tblr_c_tl } + { + \tl_set:Nx \l__tblr_cell_cmd_tl + { \__tblr_data_item:neen { cell } {#1} {#2} { cmd } } + \tl_if_empty:NF \l__tblr_cell_cmd_tl + { + \tl_set:Nx \l__tblr_c_tl + { \exp_not:V \l__tblr_cell_cmd_tl { \exp_not:V \l__tblr_c_tl } } + } } \tl_set:Nx \l__tblr_cell_mode_tl { \__tblr_data_item:neen { cell } {#1} {#2} { mode } } @@ -3462,14 +3593,17 @@ } \dim_compare:nNnT { \l__tblr_w_tl } < { 0pt } % column width unset { + \__tblr_save_counters:n { cell } \bool_if:NTF \l__tblr_cell_math_mode_bool { - \hbox_set:Nn \l_tmpa_box { \l__tblr_c_tl } + %% Note that font = \boldmath will increase cell width (issue #137) + \hbox_set:Nn \l_tmpa_box { \l__tblr_f_tl \l__tblr_c_tl } \tl_set:Nx \l__tblr_w_tl { \box_wd:N \l_tmpa_box } } { \__tblr_get_cell_size_with_box: } + \__tblr_restore_counters:n { cell } } \tl_set:Nx \l__tblr_cell_fg_tl { \__tblr_data_item:neen { cell } {#1} {#2} { foreground } } @@ -3480,11 +3614,9 @@ \cs_new_protected:Npn \__tblr_get_cell_size_with_box: { - \__tblr_save_counters:n { cell } \tl_if_eq:NnTF \l__tblr_inner_spec_measure_tl { vbox } { \__tblr_get_cell_size_with_vbox: } { \__tblr_get_cell_size_with_hbox: } - \__tblr_restore_counters:n { cell } } %% Varwidth won't work as expected when \color command occurs in it, @@ -3494,6 +3626,9 @@ %% or users may use it in the middle of the cell text, %% so we have redefine \color command and disable it before measuring cell. +%% In order to correctly measure an enumerate environment, +%% we need to enclose varwidth with NoHyper environment (see issue #196). + \NewDocumentCommand \__tblr_fake_color_command:w { o m } { } \cs_new_protected:Npn \__tblr_get_cell_size_with_vbox: @@ -3501,10 +3636,12 @@ \hbox_set:Nn \l_tmpa_box { \cs_set_eq:NN \color \__tblr_fake_color_command:w + \begin{tblrNoHyper} \begin{varwidth}{\paperwidth} \l__tblr_f_tl \__tblr_rescan_cell_tokens:N \l__tblr_c_tl \end{varwidth} + \end{tblrNoHyper} } \tl_set:Nx \l__tblr_w_tl { \box_wd:N \l_tmpa_box } } @@ -3582,15 +3719,15 @@ \cs_new_protected:Npn \__tblr_make_vcell_text:NN #1 #2 { \dim_set:Nn \tex_hsize:D { #2 } - \@arrayparboxrestore + \TblrParboxRestore \cs:w __tblr_halign_command_ \g__tblr_cell_halign_tl : \cs_end: - \mode_leave_vertical: - \box_use:N \l__tblr_strut_ht_box + %% \mode_leave_vertical: has been moved into \__tblr_use_strut_ht_box: + \__tblr_use_strut_ht_box: \tl_if_empty:NF \l__tblr_cell_fg_tl { \exp_args:NV \color \l__tblr_cell_fg_tl } \bool_if:NTF \l__tblr_cell_math_mode_bool { #1 } { \__tblr_rescan_cell_tokens:N #1 } - \box_use:N \l__tblr_strut_dp_box + \__tblr_use_strut_dp_box: } %% When using verb option, there is an end-of-line character at the end. @@ -3775,7 +3912,7 @@ } %%% -------------------------------------------------------- -%% \section{Calculate and Adjust Extendable Columns} +%%> \section{Calculate and Adjust Extendable Columns} %%% -------------------------------------------------------- %% Compute column widths when there are some extendable columns @@ -3943,7 +4080,7 @@ } %%% -------------------------------------------------------- -%% \section{Calculate and Adjust Multispan Cells} +%%> \section{Calculate and Adjust Multispan Cells} %%% -------------------------------------------------------- %% Compute and adjust widths when there are some span cells. @@ -4479,6 +4616,7 @@ \keys_set:nn { tblr-def-template } {#1} \ignorespaces } +\cs_new_eq:NN \DeclareTblrTemplate \DefTblrTemplate \cs_new_protected:Npn \__tblr_def_template:n #1 { @@ -4869,11 +5007,16 @@ } \SetTblrTemplate { note-border } { empty } +\cs_set_eq:NN \TblrOverlap \rlap + \NewDocumentCommand \TblrNote { m } { \cs_if_exist:NT \hypersetup { \ExpTblrTemplate { note-border }{ default } } - \__tblr_hyper_link:nn {#1} - { \textsuperscript { \sffamily \UseTblrFont { note-tag } #1 } } + \TblrOverlap + { + \__tblr_hyper_link:nn {#1} + { \textsuperscript { \sffamily \UseTblrFont { note-tag } #1 } } + } } \DefTblrTemplate { note-tag } { empty } { } @@ -5146,16 +5289,26 @@ \__tblr_build_table_label_entry: \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 } } + \__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_tall_table_head_foot: @@ -5192,9 +5345,12 @@ \vbox_set:Nn #1 { \hsize = \tablewidth - \parindent = 0pt \relax - \vbox:n {#2} - \skip_vertical:n { \__tblr_spec_item:nn { outer } { headsep } } + \TblrParboxRestore % it will set \linewidth = \hsize + \vbox_set:Nn \l_tmpa_box {#2} + \box_use:N \l_tmpa_box + \dim_compare:nNnT + { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box } > { 0pt } + { \skip_vertical:n { \__tblr_spec_item:nn { outer } { headsep } } } } } @@ -5203,9 +5359,12 @@ \vbox_set:Nn #1 { \hsize = \tablewidth - \skip_vertical:n { \__tblr_spec_item:nn { outer } { footsep } } - \parindent = 0pt \relax - \vbox:n {#2} + \TblrParboxRestore % it will set \linewidth = \hsize + \vbox_set:Nn \l_tmpb_box {#2} + \dim_compare:nNnT + { \box_ht:N \l_tmpb_box + \box_dp:N \l_tmpb_box } > { 0pt } + { \skip_vertical:n { \__tblr_spec_item:nn { outer } { footsep } } } + \box_use:N \l_tmpb_box } } @@ -5217,11 +5376,11 @@ \tl_if_eq:enTF { \__tblr_spec_item:nn { outer } { tall } } { true } { \__tblr_build_tall_table:e - { \__tblr_spec_item:nn { outer } { valign } } + { \__tblr_spec_item:nn { outer } { baseline } } } { \__tblr_build_short_table:e - { \__tblr_spec_item:nn { outer } { valign } } + { \__tblr_spec_item:nn { outer } { baseline } } } } } @@ -5288,7 +5447,7 @@ \int_incr:N \l__tblr_table_page_int \int_set:Nn \l__tblr_long_from_int { \l__tblr_prev_i_int + 1 } } - \newpage + \TblrNewPage \hbox{}\kern-\topskip\nobreak \noindent \LogTblrTracing { page } @@ -5302,7 +5461,7 @@ { \int_use:N \l__tblr_long_from_int } { \int_use:N \l__tblr_curr_i_int } \int_incr:N \l__tblr_table_page_int - \newpage + \TblrNewPage \hbox{}\kern-\topskip\nobreak \noindent \LogTblrTracing { page } @@ -5356,12 +5515,17 @@ \int_compare:nNnTF {#2} < {#1} { \tl_set:Nx \l__tblr_b_tl - { \__tblr_data_item:nen { row } { \int_eval:n { #2 + 1 } } { break } } - \int_compare:nNnTF { \l__tblr_b_tl } < { 0 } + { + \__tblr_spec_item:ne { hline } + { [ \int_eval:n { #2 + 1 } ] / @pagebreak } + } + % Note that \l__tblr_b_tl may be empty + \int_compare:nNnTF { \l__tblr_b_tl + 0 } < { 0 } { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool - \int_compare:nNnT { \l__tblr_b_tl } > { 0 } { \bool_set_true:N #4 } + \int_compare:nNnT { \l__tblr_b_tl + 0 } > { 0 } + { \bool_set_true:N #4 } } } { \bool_set_false:N \l_tmpa_bool } @@ -5425,7 +5589,7 @@ \hrule height ~ 0pt \box_use:N \l__tblr_table_foot_box } - \__tblr_halign_whole:Nn \l__tblr_table_box #1 + \__tblr_halign_whole:Nn \l__tblr_table_box {#1} } \cs_generate_variant:Nn \__tblr_build_page_table:nnn { nnx } @@ -5463,7 +5627,6 @@ \cs_new_protected:Npn \__tblr_build_tall_table:n #1 { \mode_leave_vertical: - \raggedright \__tblr_build_tall_table_head_foot: \__tblr_build_one_table:nn {1} {\c@rowcount} \vbox_set:Nn \l__tblr_table_box @@ -5474,7 +5637,7 @@ \hrule height ~ 0pt \box_use:N \l__tblr_table_lastfoot_box } - \__tblr_valign_whole:Nn \l__tblr_table_box #1 + \__tblr_valign_whole:Nn \l__tblr_table_box {#1} } \cs_generate_variant:Nn \__tblr_build_tall_table:n { e } @@ -5484,7 +5647,7 @@ { \mode_leave_vertical: \__tblr_build_one_table:nn {1} {\c@rowcount} - \__tblr_valign_whole:Nn \l__tblr_table_box #1 + \__tblr_valign_whole:Nn \l__tblr_table_box {#1} } \cs_generate_variant:Nn \__tblr_build_short_table:n { e } @@ -5561,9 +5724,15 @@ \tl_new:N \__tblr_vbox_align_tl \tl_const:Nn \__tblr_vbox_t_tl {t} +\tl_const:Nn \__tblr_vbox_T_tl {T} \tl_const:Nn \__tblr_vbox_m_tl {m} +\tl_const:Nn \__tblr_vbox_M_tl {M} \tl_const:Nn \__tblr_vbox_c_tl {c} \tl_const:Nn \__tblr_vbox_b_tl {b} +\tl_const:Nn \__tblr_vbox_B_tl {B} + +\regex_const:Nn \c__tblr_is_positive_integer_regex { ^ \d+ $ } +\regex_const:Nn \c__tblr_is_negative_integer_regex { ^ - \d+ $ } \cs_new_protected:Npn \__tblr_valign_whole:Nn #1 #2 { @@ -5576,12 +5745,34 @@ { \__tblr_valign_whole_middle:N #1 } \__tblr_vbox_c_tl { \__tblr_valign_whole_middle:N #1 } + \__tblr_vbox_M_tl + { \__tblr_valign_whole_middle_row_or_border:N #1 } \__tblr_vbox_t_tl { \__tblr_valign_whole_top:N #1 } + \__tblr_vbox_T_tl + { + \tl_set:Nn \__tblr_vbox_align_tl {1} + \__tblr_valign_whole_at_row_from_above:N #1 + } \__tblr_vbox_b_tl { \__tblr_valign_whole_bottom:N #1 } + \__tblr_vbox_B_tl + { + \tl_set:Nx \__tblr_vbox_align_tl { \int_use:N \c@rowcount } + \__tblr_valign_whole_at_row_from_below:N #1 + } + } + { + \regex_match:NVTF \c__tblr_is_positive_integer_regex \__tblr_vbox_align_tl + { \__tblr_valign_whole_at_row:N #1 } + { + \regex_match:NVTF + \c__tblr_is_negative_integer_regex \__tblr_vbox_align_tl + { \__tblr_valign_whole_at_border:N #1 } + { \__tblr_valign_whole_middle:N #1 } + } } - { \__tblr_valign_whole_middle:N #1 } + \box_use_drop:N #1 \group_end: } @@ -5592,74 +5783,147 @@ \cs_new_protected:Npn \__tblr_valign_whole_top:N #1 { - \tl_set:Nx \l__tblr_a_tl - { \__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 { 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 } } + \dim_set:Nn \l__tblr_h_dim { \__tblr_valign_get_hline_total:n {1} } + \dim_compare:nNnT \l__tblr_h_dim = { 0pt } + { \dim_add:Nn \l__tblr_h_dim { \__tblr_valign_get_row_height:n {1} } } + \box_set_ht:Nn #1 { \l__tblr_h_dim } + \box_set_dp:Nn #1 { \l__tblr_t_dim - \l__tblr_h_dim } + } + +\cs_new_protected:Npn \__tblr_valign_whole_bottom:N #1 + { + \dim_set:Nn \l__tblr_d_dim + { \__tblr_valign_get_hline_total:n { \int_eval:n { \c@rowcount + 1 } } } + \dim_compare:nNnTF \l__tblr_d_dim = { 0pt } { - \dim_set:Nn \l__tblr_h_dim - { - \__tblr_data_item:nnn { row } {1} { abovesep } - + - ( \__tblr_data_item:nnn { row } {1} { @row-height } - + - \__tblr_data_item:nnn { row } {1} { @row-upper } - - - \__tblr_data_item:nnn { row } {1} { @row-lower } - ) / 2 - } - \dim_set:Nn \l__tblr_d_dim { \l__tblr_t_dim - \l__tblr_h_dim } + \dim_set:Nn \l__tblr_d_dim + { \__tblr_valign_get_row_depth:n { \int_use:N \c@rowcount } } } + { \dim_zero:N \l__tblr_d_dim } + \box_set_ht:Nn #1 { \l__tblr_t_dim - \l__tblr_d_dim } + \box_set_dp:Nn #1 { \l__tblr_d_dim } + } + +\cs_new_protected:Npn \__tblr_valign_whole_middle_row_or_border:N #1 + { + \int_if_odd:nTF { \c@rowcount } { - \dim_set:Nn \l__tblr_h_dim { 0pt } - \dim_set_eq:NN \l__tblr_d_dim \l__tblr_t_dim + \tl_set:Nx \__tblr_vbox_align_tl { \int_eval:n { (\c@rowcount + 1) / 2 } } + \__tblr_valign_whole_at_row_from_above:N #1 + } + { + \tl_set:Nx \__tblr_vbox_align_tl { \int_eval:n { \c@rowcount / 2 + 1 } } + \__tblr_valign_whole_at_border_from_above:N #1 } - \box_set_ht:Nn #1 { \l__tblr_h_dim } - \box_set_dp:Nn #1 { \l__tblr_d_dim } - \box_use_drop:N #1 } -\cs_new_protected:Npn \__tblr_valign_whole_bottom:N #1 +\cs_new_protected:Npn \__tblr_valign_whole_at_row:N #1 { - \tl_set:Nx \l__tblr_a_tl + \int_compare:nNnTF { 2 * \__tblr_vbox_align_tl } > { \c@rowcount } + { \__tblr_valign_whole_at_row_from_below:N #1 } + { \__tblr_valign_whole_at_row_from_above:N #1 } + } + +\cs_new_protected:Npn \__tblr_valign_whole_at_row_from_above:N #1 + { + \dim_set:Nn \l__tblr_h_dim + { \__tblr_valign_get_hline_total:n { \__tblr_vbox_align_tl } } + \dim_add:Nn \l__tblr_h_dim + { \__tblr_valign_get_row_height:n { \__tblr_vbox_align_tl } } + \int_step_inline:nn { \__tblr_vbox_align_tl - 1 } { - \__tblr_spec_item:ne { hline } - { [\int_eval:n {\c@rowcount + 1}] / @hline-height } + \dim_add:Nn \l__tblr_h_dim { \__tblr_valign_get_hline_total:n {##1} } + \dim_add:Nn \l__tblr_h_dim { \__tblr_valign_get_row_total:n {##1} } } - %% Note that \l__tblr_b_tl may be empty - \tl_set:Nx \l__tblr_b_tl - { \__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 } } + \box_set_ht:Nn #1 { \l__tblr_h_dim } + \box_set_dp:Nn #1 { \l__tblr_t_dim - \l__tblr_h_dim } + } + +\cs_new_protected:Npn \__tblr_valign_whole_at_row_from_below:N #1 + { + \dim_set:Nn \l__tblr_d_dim + { \__tblr_valign_get_hline_total:n { \int_eval:n {\c@rowcount + 1} } } + \dim_add:Nn \l__tblr_d_dim + { \__tblr_valign_get_row_depth:n { \__tblr_vbox_align_tl } } + \int_step_inline:nnn { \__tblr_vbox_align_tl + 1 } { \c@rowcount } { - \dim_set:Nn \l__tblr_d_dim - { - ( \__tblr_data_item:nen { row } - { \int_use:N \c@rowcount } { @row-height } - - - \__tblr_data_item:nen { row } - { \int_use:N \c@rowcount } { @row-upper } - + - \__tblr_data_item:nen { row } - { \int_use:N \c@rowcount } { @row-lower } - ) / 2 - + - \__tblr_data_item:nnn { row } {1} { belowsep } - } - \dim_set:Nn \l__tblr_h_dim { \l__tblr_t_dim - \l__tblr_d_dim } + \dim_add:Nn \l__tblr_d_dim { \__tblr_valign_get_hline_total:n {##1} } + \dim_add:Nn \l__tblr_d_dim { \__tblr_valign_get_row_total:n {##1} } } + \box_set_dp:Nn #1 { \l__tblr_d_dim } + \box_set_ht:Nn #1 { \l__tblr_t_dim - \l__tblr_d_dim } + } + +\cs_new_protected:Npn \__tblr_valign_whole_at_border:N #1 + { + \tl_set:Nx \__tblr_vbox_align_tl { \int_eval:n { - \__tblr_vbox_align_tl } } + \int_compare:nNnTF { 2 * \__tblr_vbox_align_tl - 2 } > { \c@rowcount } + { \__tblr_valign_whole_at_border_from_below:N #1 } + { \__tblr_valign_whole_at_border_from_above:N #1 } + } + +\cs_new_protected:Npn \__tblr_valign_whole_at_border_from_above:N #1 + { + \dim_set:Nn \l__tblr_h_dim + { \__tblr_valign_get_hline_total:n { \__tblr_vbox_align_tl } } + \int_step_inline:nn { \__tblr_vbox_align_tl - 1 } { - \dim_set:Nn \l__tblr_d_dim { 0pt } - \dim_set_eq:NN \l__tblr_h_dim \l__tblr_t_dim + \dim_add:Nn \l__tblr_h_dim { \__tblr_valign_get_hline_total:n {##1} } + \dim_add:Nn \l__tblr_h_dim { \__tblr_valign_get_row_total:n {##1} } } \box_set_ht:Nn #1 { \l__tblr_h_dim } + \box_set_dp:Nn #1 { \l__tblr_t_dim - \l__tblr_h_dim } + } + +\cs_new_protected:Npn \__tblr_valign_whole_at_border_from_below:N #1 + { + \dim_zero:N \l__tblr_d_dim + \int_step_inline:nnn { \__tblr_vbox_align_tl } { \c@rowcount } + { + \dim_add:Nn \l__tblr_d_dim { \__tblr_valign_get_row_total:n {##1} } + \dim_add:Nn \l__tblr_d_dim + { \__tblr_valign_get_hline_total:n { \int_eval:n { ##1 + 1 } } } + } \box_set_dp:Nn #1 { \l__tblr_d_dim } - \box_use_drop:N #1 + \box_set_ht:Nn #1 { \l__tblr_t_dim - \l__tblr_d_dim } + } + +\cs_new_nopar:Npn \__tblr_valign_get_hline_total:n #1 + { + \__tblr_spec_item:ne { hline } { [#1] / @hline-height } + } + +\cs_new_nopar:Npn \__tblr_valign_get_row_total:n #1 + { + \__tblr_data_item:nnn { row } {#1} { abovesep } + + + \__tblr_data_item:nnn { row } {#1} { @row-height } + + + \__tblr_data_item:nnn { row } {#1} { belowsep } + } + +\cs_new_nopar:Npn \__tblr_valign_get_row_height:n #1 + { + \__tblr_data_item:nnn { row } {#1} { abovesep } + + + ( \__tblr_data_item:nnn { row } {#1} { @row-height } + + + \__tblr_data_item:nnn { row } {#1} { @row-upper } + - + \__tblr_data_item:nnn { row } {#1} { @row-lower } + ) / 2 + } + +\cs_new_nopar:Npn \__tblr_valign_get_row_depth:n #1 + { + ( \__tblr_data_item:nen { row } {#1} { @row-height } + - + \__tblr_data_item:nen { row } {#1} { @row-upper } + + + \__tblr_data_item:nen { row } {#1} { @row-lower } + ) / 2 + + + \__tblr_data_item:nnn { row } {#1} { belowsep } } %%% -------------------------------------------------------- @@ -6064,7 +6328,8 @@ \hbox_set_to_wd:Nnn \l__tblr_a_box { \l__tblr_cell_wd_dim } { \tl_if_eq:NnTF \g__tblr_cell_halign_tl {j} - { \__tblr_get_cell_text:nn {#1} {#2} } + % cell width may be less than column width for j cells + { \__tblr_get_cell_text:nn {#1} {#2} \hfil } { \tl_if_eq:NnF \g__tblr_cell_halign_tl {l} { \hfil } \__tblr_get_cell_text:nn {#1} {#2} @@ -6245,14 +6510,13 @@ } %%% -------------------------------------------------------- -%% \section{Tracing Tabularray} +%%> \section{Tracing Tabularray} %%% -------------------------------------------------------- -\NewDocumentCommand \SetTabularrayTracing { m } +\NewDocumentCommand \SetTblrTracing { m } { \keys_set:nn { tblr-set-tracing } {#1} } -\cs_new_eq:NN \SetTblrTracing \SetTabularrayTracing \bool_new:N \g__tblr_tracing_text_bool \bool_new:N \g__tblr_tracing_command_bool @@ -6361,11 +6625,10 @@ \bool_gset_false:N \g__tblr_tracing_step_bool } -\NewDocumentCommand \LogTabularrayTracing { m } +\NewDocumentCommand \LogTblrTracing { m } { \keys_set:nn { tblr-log-tracing } {#1} } -\cs_new_eq:NN \LogTblrTracing \LogTabularrayTracing \keys_define:nn { tblr-log-tracing } { @@ -6482,7 +6745,7 @@ } %%% -------------------------------------------------------- -%% \section{Tabularray Libraries} +%%> \section{Tabularray Libraries} %%% -------------------------------------------------------- %% \NewTblrLibrary and \UseTblrLibrary commands @@ -6571,17 +6834,18 @@ \RequirePackage { booktabs } \newcommand \tblr@booktabs@hline [1] [] { \hline [##1] } \newcommand \tblr@booktabs@oldhline [1] [] { - \hline [abovespace = \aboverulesep, belowspace = \belowrulesep, ##1] + \hline [##1] + \hborder { abovespace = \aboverulesep, belowspace = \belowrulesep } } \newcommand \tblr@booktabs@cline [2] [] { \cline [##1] {##2} } \newcommand \tblr@booktabs@oldcline [2] [] { - \cline [abovespace = \aboverulesep, belowspace = \belowrulesep, ##1] {##2} + \cline [##1] {##2} + \hborder { abovespace = \aboverulesep, belowspace = \belowrulesep } } \newcommand \tblr@booktabs@cline@more [2] [] { \SetHline [+] {##2} {##1} } \newcommand \tblr@booktabs@oldcline@more [2] [] { - \SetHline [+] {##2} { - abovespace = \aboverulesep, belowspace = \belowrulesep, ##1 - } + \SetHline [+] {##2} {##1} + \hborder { abovespace = \aboverulesep, belowspace = \belowrulesep } } \NewTableCommand \toprule [1] [] { \tblr@booktabs@hline [wd=\heavyrulewidth, ##1] @@ -6603,20 +6867,29 @@ \peek_meaning:NTF \cmidrule { \tblr@booktabs@change@more } { \relax } } \NewTblrEnviron { booktabs } + \NewTblrEnviron { longtabs } + \NewTblrEnviron { talltabs } \SetTblrInner [ booktabs ] { rowsep = 0pt } + \SetTblrInner [ longtabs ] { rowsep = 0pt } + \SetTblrInner [ talltabs ] { rowsep = 0pt } + \SetTblrOuter [ longtabs ] { long } + \SetTblrOuter [ talltabs ] { tall } \RequirePackage { etoolbox } - \AtBeginEnvironment { booktabs } + \newcommand \tblr@booktabs@begin@hook { \let \tblr@booktabs@hline = \tblr@booktabs@oldhline \let \tblr@booktabs@cline = \tblr@booktabs@oldcline \let \tblr@booktabs@cline@more = \tblr@booktabs@oldcline@more } + \AtBeginEnvironment { booktabs } { \tblr@booktabs@begin@hook } + \AtBeginEnvironment { longtabs } { \tblr@booktabs@begin@hook } + \AtBeginEnvironment { talltabs } { \tblr@booktabs@begin@hook } \NewTableCommand \specialrule [3] - { \hline [##1, abovespace = ##2, belowspace = ##3] } + { \hline [##1] \hborder { abovespace = ##2, belowspace = ##3 } } \NewTableCommand \addrowspace [1] [\defaultaddspace] - { \SetVspace { abovespace+ = (##1) / 2, belowspace+ = (##1) / 2 } } + { \hborder { abovespace+ = (##1) / 2, belowspace+ = (##1) / 2 } } \NewTableCommand \addlinespace [1] [\defaultaddspace] - { \SetVspace { abovespace+ = (##1) / 2, belowspace+ = (##1) / 2 } } + { \hborder { abovespace+ = (##1) / 2, belowspace+ = (##1) / 2 } } } %% Library counter for resetting all counters |