summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/tabularray/tabularray-2021.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-03-02 03:03:38 +0000
committerNorbert Preining <norbert@preining.info>2022-03-02 03:03:38 +0000
commit1769d3d8842ef66919943128931e647de9756adb (patch)
tree46df94f2204cba9384cccf5ab6ca8cbbcd49bcad /macros/latex/contrib/tabularray/tabularray-2021.sty
parent3e9a44ea155766214d8657ed79db2206592b6e8e (diff)
CTAN sync 202203020303
Diffstat (limited to 'macros/latex/contrib/tabularray/tabularray-2021.sty')
-rw-r--r--macros/latex/contrib/tabularray/tabularray-2021.sty3152
1 files changed, 2675 insertions, 477 deletions
diff --git a/macros/latex/contrib/tabularray/tabularray-2021.sty b/macros/latex/contrib/tabularray/tabularray-2021.sty
index 8e5c2b9369..f5ad547d71 100644
--- a/macros/latex/contrib/tabularray/tabularray-2021.sty
+++ b/macros/latex/contrib/tabularray/tabularray-2021.sty
@@ -12,13 +12,12 @@
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}
-\ProvidesExplPackage{tabularray}{2021-06-05}{2021K}
+\ProvidesExplPackage{tabularray}{2021-12-01}{2021Q}
{Typeset tabulars and arrays with LaTeX3}
\RequirePackage{xparse}
-\AtBeginDocument{\@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{}}
-\ExplSyntaxOn
+\AtBeginDocument{\@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{}}
%% Backport \tl_if_eq:NnTF for old texlive 2020
\cs_if_exist:NF \tl_if_eq:NnTF
@@ -53,10 +52,12 @@
\cs_generate_variant:Nn \tl_const:Nn { ce }
\cs_generate_variant:Nn \tl_log:n { x }
\cs_generate_variant:Nn \tl_gput_right:Nn { Nf }
+\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 \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,11 +98,33 @@
\box_new:N \l__tblr_c_box % for cell box
\box_new:N \l__tblr_d_box
-%% Some counters for row and column numbering
-\newcounter{rownum}
-\newcounter{colnum}
-\newcounter{rowcount}
-\newcounter{colcount}
+%% 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.
+%% We may need to restore all LaTeX counters in measuring and building cells,
+%% so we must not define these counters with \newcounter command.
+\int_new:N \c@rownum
+\int_new:N \c@colnum
+\int_new:N \c@rowcount
+\int_new:N \c@colcount
+
+%% Add missing \therownum, \thecolnum, \therowcount, \thecolcount (issue #129)
+\NewExpandableDocumentCommand \therownum {} { \@arabic \c@rownum }
+\NewExpandableDocumentCommand \thecolnum {} { \@arabic \c@colnum }
+\NewExpandableDocumentCommand \therowcount {} { \@arabic \c@rowcount }
+\NewExpandableDocumentCommand \thecolcount {} { \@arabic \c@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 +136,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 +210,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 +241,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_text_gput_if_larger:nnn { nne, nnV, nen, nee, neV }
+\cs_generate_variant:Nn \__tblr_spec_gput_if_larger:nnn { nne, nnV, nen, nee, neV }
-\cs_new_protected:Npn \__tblr_text_log:n #1
+\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_spec_gadd_dimen_value:nnn { nne, nnV, nen, nee }
+
+\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} }
}
}
}
@@ -321,6 +362,7 @@
\__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 }
@@ -336,6 +378,10 @@
\__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 } { foreground } { str }
+\__tblr_data_new_key:nnn { cell } { font } { str }
+\__tblr_data_new_key:nnn { cell } { mode } { str }
+\__tblr_data_new_key:nnn { cell } { cmd } { 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 +396,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 +553,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 +707,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 +725,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}
}
}
}
@@ -818,12 +865,30 @@
}
}
+\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
{
- \int_step_inline:nnn {#1} {#2}
+ \__tblr_child_name_to_index:nN {#1} \l__tblr_child_from_tl
+ \__tblr_child_name_to_index:nN {#2} \l__tblr_child_to_tl
+ \int_step_inline:nnn { \l__tblr_child_from_tl } { \l__tblr_child_to_tl }
{ \clist_put_right:Nn \l_tblr_childs_clist {##1} }
}
+\regex_const:Nn \c__tblr_child_name_regex { ^ [X-Z] $ }
+
+%% Convert X, Y, Z to the indexes of the last three childs, respectively
+\cs_new_protected_nopar:Npn \__tblr_child_name_to_index:nN #1 #2
+ {
+ \regex_match:NnTF \c__tblr_child_name_regex {#1}
+ {
+ \tl_set:Nx #2
+ { \int_eval:n { \l_tblr_childs_total_tl + \int_from_alph:n {#1} - 26 } }
+ }
+ { \tl_set:Nx #2 { #1 } }
+ }
+
%%% --------------------------------------------------------
%% \section{New Table Commands}
%%% --------------------------------------------------------
@@ -889,6 +954,54 @@
\int_set:Nn \c@colnum {#2}
}
+%% Table commands are defined only inside tblr environments,
+%% but some packages such as csvsimple need to use them outside tblr environments,
+%% therefore we define some of them first here.
+\ProvideDocumentCommand \SetHlines { o m m } {}
+\ProvideDocumentCommand \SetHline { o m m } {}
+\ProvideDocumentCommand \SetVlines { o m m } {}
+\ProvideDocumentCommand \SetVline { o m m } {}
+\ProvideDocumentCommand \SetCells { o m } {}
+\ProvideDocumentCommand \SetCell { o m } {}
+\ProvideDocumentCommand \SetRows { o m } {}
+\ProvideDocumentCommand \SetRow { o m } {}
+\ProvideDocumentCommand \SetColumns { o m } {}
+\ProvideDocumentCommand \SetColumn { o m } {}
+
+%%% --------------------------------------------------------
+%%> \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}
%%% --------------------------------------------------------
@@ -1007,11 +1120,18 @@
\tl_new:N \l__tblr_hline_dash_tl % dash style
\tl_new:N \l__tblr_hline_fg_tl % dash foreground
\tl_new:N \l__tblr_hline_wd_tl % dash width
+\tl_new:N \l__tblr_hline_leftpos_tl % left position
+\tl_new:N \l__tblr_hline_rightpos_tl % right position
+\bool_new:N \l__tblr_hline_endpos_bool % whether set positions only for both ends
\NewTableCommand \cline [2] [] { \SetHline [=] {#2} {#1} }
\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
@@ -1025,13 +1145,19 @@
\cs_new_protected:Npn \tblr_set_hline:nnn #1 #2 #3
{
\group_begin:
- \keys_set_groups:nnn { tblr-hline } { text } {#3}
- \tl_if_eq:NnF \l__tblr_hline_dash_tl { \exp_not:N \@tblr@text }
+ %% 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} }
{
- \__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}
+ \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}
+ }
}
\group_end:
}
@@ -1068,12 +1194,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 +1221,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
}
@@ -1108,6 +1234,21 @@
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 },
+ l .default:n = { -0.8 },
+ r .meta:n = { rightpos = #1 },
+ r .default:n = { -0.8 },
+ 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,
}
@@ -1131,24 +1272,59 @@
\__tblr_get_childs:nx {#1} { \int_use:N \c@colcount }
\clist_map_inline:Nn \l_tblr_childs_clist
{
- \__tblr_text_gput:nee { hline }
- { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / @dash }
- { \l__tblr_hline_dash_tl }
+ \__tblr_set_hline_option:nnn { ##1 } { @dash } { \l__tblr_hline_dash_tl }
\tl_if_empty:NF \l__tblr_hline_wd_tl
{
- \__tblr_text_gput:nee { hline }
- { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / wd }
- { \l__tblr_hline_wd_tl }
+ \__tblr_set_hline_option:nnn { ##1 } { wd } { \l__tblr_hline_wd_tl }
}
\tl_if_empty:NF \l__tblr_hline_fg_tl
{
- \__tblr_text_gput:nee { hline }
- { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / fg }
- { \l__tblr_hline_fg_tl }
+ \__tblr_set_hline_option:nnn { ##1 } { fg } { \l__tblr_hline_fg_tl }
+ }
+ }
+ \tl_if_empty:NF \l__tblr_hline_leftpos_tl
+ {
+ \bool_if:NTF \l__tblr_hline_endpos_bool
+ {
+ \__tblr_set_hline_option:nnn
+ { \clist_item:Nn \l_tblr_childs_clist {1} }
+ { leftpos }
+ { \l__tblr_hline_leftpos_tl }
+ }
+ {
+ \clist_map_inline:Nn \l_tblr_childs_clist
+ {
+ \__tblr_set_hline_option:nnn
+ { ##1 } { leftpos } { \l__tblr_hline_leftpos_tl }
+ }
+ }
+ }
+ \tl_if_empty:NF \l__tblr_hline_rightpos_tl
+ {
+ \bool_if:NTF \l__tblr_hline_endpos_bool
+ {
+ \__tblr_set_hline_option:nnn
+ { \clist_item:Nn \l_tblr_childs_clist {-1} }
+ { rightpos }
+ { \l__tblr_hline_rightpos_tl }
+ }
+ {
+ \clist_map_inline:Nn \l_tblr_childs_clist
+ {
+ \__tblr_set_hline_option:nnn
+ { ##1 } { rightpos } { \l__tblr_hline_rightpos_tl }
+ }
}
}
}
+%% #1: column; #2: key; #3: value
+\cs_new_protected_nopar:Npn \__tblr_set_hline_option:nnn #1 #2 #3
+ {
+ \__tblr_spec_gput:nee { hline }
+ { [\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 } }
@@ -1156,13 +1332,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 }
}
}
}
@@ -1206,6 +1382,8 @@
\tl_new:N \l__tblr_vline_dash_tl % dash style
\tl_new:N \l__tblr_vline_fg_tl % dash foreground
\tl_new:N \l__tblr_vline_wd_tl % dash width
+\tl_new:N \l__tblr_vline_abovepos_tl % above position
+\tl_new:N \l__tblr_vline_belowpos_tl % below position
\NewTableCommand \rline [2] [] { \SetVline [=] {#2} {#1} }
@@ -1267,12 +1445,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 +1472,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
}
@@ -1306,6 +1484,8 @@
text .groups:n = { text },
wd .code:n = \tl_set:Nn \l__tblr_vline_wd_tl { \dim_eval:n {#1} },
fg .code:n = \tl_set:Nn \l__tblr_vline_fg_tl {#1},
+ abovepos .code:n = \tl_set:Nx \l__tblr_vline_abovepos_tl {#1},
+ belowpos .code:n = \tl_set:Nx \l__tblr_vline_belowpos_tl {#1},
unknown .code:n = \__tblr_vline_unknown_key:V \l_keys_key_str,
}
@@ -1329,21 +1509,33 @@
\__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 }
}
+ \tl_if_empty:NF \l__tblr_vline_abovepos_tl
+ {
+ \__tblr_spec_gput:nee { vline }
+ { [##1][\int_use:N \c@colnum](\l__tblr_vline_num_tl) / abovepos }
+ { \l__tblr_vline_abovepos_tl }
+ }
+ \tl_if_empty:NF \l__tblr_vline_belowpos_tl
+ {
+ \__tblr_spec_gput:nee { vline }
+ { [##1][\int_use:N \c@colnum](\l__tblr_vline_num_tl) / belowpos }
+ { \l__tblr_vline_belowpos_tl }
+ }
}
}
@@ -1440,36 +1632,45 @@
\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},
+ j .meta:n = { halign = j },
+ 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},
+ fg .code:n = \__tblr_cell_gput:ne { foreground } {#1},
+ font .code:n = \__tblr_cell_gput:nn { font } { #1 \selectfont },
+ mode .code:n = \__tblr_cell_gput:nn { mode } {#1},
+ $ .meta:n = { mode = math },
+ $$ .meta:n = { mode = dmath },
+ cmd .code:n = \__tblr_cell_gput:nn { cmd } {#1},
+ preto .code:n = \__tblr_cell_preto_text:n {#1},
+ appto .code:n = \__tblr_cell_appto_text:n {#1},
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 +1681,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,9 +1695,9 @@
\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 }
@@ -1520,13 +1721,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,16 +1747,33 @@
}
\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}
}
}
}
+ %% Make continuous borders for multirow cells
+ \tl_set:Nx \l__tblr_n_tl
+ {
+ \int_max:nn
+ {
+ \__tblr_spec_item:ne { vline } { [\int_use:N \c@colnum] / @vline-count }
+ }
+ { 1 }
+ }
+ \int_step_variable:nnNn
+ { \c@rownum } { \int_eval:n { \c@rownum + #1 -1 } } \l__tblr_i_tl
+ {
+ \__tblr_spec_gput:nee { vline }
+ { [\l__tblr_i_tl][\int_use:N \c@colnum](\l__tblr_n_tl) / belowpos } {1}
+ \__tblr_spec_gput:nee { vline }
+ { [\l__tblr_i_tl][\int_eval:n {\c@colnum + #2}](1) / belowpos } {1}
+ }
}
\cs_generate_variant:Nn \__tblr_set_span_spec:nn { VV }
@@ -1678,53 +1896,63 @@
\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},
+ j .meta:n = { halign = j },
+ 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_column_gput_cell:nn { foreground } {#1},
+ font .code:n = \__tblr_column_gput_cell:nn { font } { #1 \selectfont },
+ mode .code:n = \__tblr_column_gput_cell:nn { mode } {#1},
+ $ .meta:n = { mode = math },
+ $$ .meta:n = { mode = dmath },
+ cmd .code:n = \__tblr_column_gput_cell:nn { cmd } {#1},
+ 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},
+ 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
{
@@ -1747,20 +1975,13 @@
\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 +2051,76 @@
\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},
+ j .meta:n = { halign = j },
+ 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_row_gput_cell:nn { foreground } {#1},
+ font .code:n = \__tblr_row_gput_cell:nn { font } { #1 \selectfont },
+ mode .code:n = \__tblr_row_gput_cell:nn { mode } {#1},
+ $ .meta:n = { mode = math },
+ $$ .meta:n = { mode = dmath },
+ cmd .code:n = \__tblr_row_gput_cell:nn { cmd } {#1},
+ 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},
+ 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},
+ break .code:n = \__tblr_row_gput:nn { break } {#1},
+ pagebreak .meta:n = { break = 1 },
+ nopagebreak .meta:n = { break = -1 },
+ 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_gput_above:nn #1 #2
+ {
+ \__tblr_data_gput:nenn { row } { \int_eval:n { \c@rownum - 1 } } {#1} {#2}
+ }
+\cs_generate_variant:Nn \__tblr_row_gput_above: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 }
+
+\cs_new_protected:Npn \__tblr_row_gadd_dimen_above:nn #1 #2
+ {
+ \__tblr_data_gadd_dimen_value:nenn { row }
+ { \int_eval:n { \c@rownum - 1 } } {#1} {#2}
+ }
+\cs_generate_variant:Nn \__tblr_row_gadd_dimen_above: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
{
@@ -1905,19 +2147,25 @@
}
{
\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 } }
}
}
}
\cs_generate_variant:Nn \__tblr_row_unknown_key:n { V }
+\NewTableCommand \pagebreak
+ {
+ \tblr_set_row:nn {} { break = 1 }
+ }
+
+\NewTableCommand \nopagebreak
+ {
+ \tblr_set_row:nn {} { break = -1 }
+ }
+
%%% --------------------------------------------------------
%% \section{Column Types and Row Types}
%%% --------------------------------------------------------
@@ -2117,6 +2365,7 @@
\NewColumnRowType { l } { Q[l] }
\NewColumnRowType { c } { Q[c] }
\NewColumnRowType { r } { Q[r] }
+\NewColumnRowType { j } { Q[j] }
\NewColumnType { t } [1] { Q[t,wd=#1] }
\NewColumnType { p } [1] { Q[p,wd=#1] }
@@ -2179,7 +2428,10 @@
}
{
\str_if_in:cnTF { g_tblr_used_ \g__tblr_column_or_row_tl _types_str } {#1}
- { \cs:w tblr_ \g__tblr_column_or_row_tl _type_ #1 \cs_end: }
+ {
+ %% Note that #1 may be an active character (see issue #58)
+ \cs:w tblr_ \g__tblr_column_or_row_tl _type_ \token_to_str:N #1 \cs_end:
+ }
{
\msg_error:nnVn { tabularray } { unknown-colrow-type }
\g__tblr_column_or_row_tl {#1}
@@ -2205,43 +2457,102 @@
}
%%% --------------------------------------------------------
-%% \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 }
+\NewTblrEnviron { talltblr }
+\SetTblrOuter [ talltblr ] { tall }
+
\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:
+ \LogTblrTracing { step = init ~ table ~ outer ~ spec}
+ \__tblr_init_table_outer_spec:
+ \LogTblrTracing { step = parse ~ table ~ options }
+ \__tblr_parse_table_option:n {#1}
+ \LogTblrTracing { outer }
+ \LogTblrTracing { option }
\__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 }
+ \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
@@ -2272,35 +2583,54 @@
\regex_replace_all:NVN \c__tblr_remove_braces_regex \c__tblr_remove_braces_tl #1
}
-%% Split table content to cells and store them
-%% #1: table content
+\tl_new:N \l__tblr_body_tl
+\tl_new:N \l__tblr_expand_tl
+\seq_new:N \l__tblr_lines_seq
-\seq_new:N \l_tblr_lines_seq
+%% Expand every occurrence of the specified macro once
+%% #1: table content; #2: macro to be expanded
+\cs_new_protected:Npn \__tblr_expand_table_body:nN #1 #2
+ {
+ \tl_clear:N \l__tblr_body_tl
+ \cs_set_protected:Npn \__tblr_expand_table_body_aux:w ##1 #2
+ {
+ \tl_put_right:Nn \l__tblr_body_tl {##1}
+ \peek_meaning:NTF \q_stop
+ { \use_none:n }
+ { \exp_last_unbraced:NV \__tblr_expand_table_body_aux:w #2 }
+ }
+ \__tblr_expand_table_body_aux:w #1 #2 \q_stop
+ }
+%% Split table content to cells and store them
+%% #1: table content
\cs_new_protected:Npn \__tblr_split_table:n #1
{
+ \tl_set:Nx \l__tblr_expand_tl { \__tblr_spec_item:nn { outer } { expand } }
+ \tl_set:Nx \l__tblr_expand_tl { \tl_head:N \l__tblr_expand_tl }
+ \tl_if_empty:NTF \l__tblr_expand_tl
+ { \tl_set:Nn \l__tblr_body_tl {#1} }
+ { \exp_args:NnV \__tblr_expand_table_body:nN {#1} \l__tblr_expand_tl }
\int_zero:N \c@rowcount
\int_zero:N \c@colcount
- \__tblr_split_table_to_lines:nN { #1 } \l_tblr_lines_seq
- \__tblr_split_lines_to_cells:N \l_tblr_lines_seq
+ \__tblr_split_table_to_lines:NN \l__tblr_body_tl \l__tblr_lines_seq
+ \__tblr_split_lines_to_cells:N \l__tblr_lines_seq
}
%% Split table content to a sequence of lines
-%% #1: table content, #2: resulting sequence of lines
-\cs_new_protected:Npn \__tblr_split_table_to_lines:nN #1 #2
+%% #1: tl with table contents, #2: resulting sequence of lines
+\cs_new_protected:Npn \__tblr_split_table_to_lines:NN #1 #2
{
- \tl_set:Nn \l_tmpa_tl { #1 }
- \__tblr_insert_braces:N \l_tmpa_tl
- \seq_set_split:NnV \l_tmpa_seq { \\ } \l_tmpa_tl
+ \__tblr_insert_braces:N #1
+ \seq_set_split:NnV \l_tmpa_seq { \\ } #1
\seq_clear:N #2
\seq_map_inline:Nn \l_tmpa_seq
{
\tl_if_head_eq_meaning:nNTF {##1} *
{
- \tl_set:Nn \l__tblr_b_tl { \SetRow{nobreak} }
+ \tl_set:Nn \l__tblr_b_tl { \SetRow { break = -1 } }
\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_log:N \l__tblr_c_tl
\tl_if_head_eq_meaning:VNT \l__tblr_c_tl [
{
\tl_put_right:Nn \l__tblr_b_tl { \RowBefore@AddBelowSep }
@@ -2346,16 +2676,21 @@
{
\tl_set:Nn \l_tmpa_tl { ##1 }
\__tblr_remove_braces:N \l_tmpa_tl
+ \__tblr_trim_par_space_tokens: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_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
- \bool_lazy_and:nnTF
- { \int_compare_p:nNn {\c@colnum} = {1} }
- { \tl_if_empty_p:N \l_tmpa_tl }
+ \bool_lazy_all:nTF
+ {
+ { \int_compare_p:nNn {#1} = {\c@rowcount} }
+ { \int_compare_p:nNn {\c@colnum} = {1} }
+ { \tl_if_empty_p:N \l_tmpa_tl }
+ }
{ \int_decr:N \c@rowcount }
{
\__tblr_prop_gput:nnx
@@ -2367,13 +2702,22 @@
}
}
+\regex_const:Nn \c__tblr_trim_left_par_space_regex { ^ \c{par} ? \s * }
+\regex_const:Nn \c__tblr_trim_right_space_par_regex { \s * \c{par} ? $ }
+
+\cs_new_protected:Npn \__tblr_trim_par_space_tokens:N #1
+ {
+ \regex_replace_once:NnN \c__tblr_trim_left_par_space_regex {} #1
+ \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_text_gput:nen { text }
+ \__tblr_spec_gput:nen { text }
{ [\int_use:N \c@rownum][\int_use:N \c@colnum] } { }
}
}
@@ -2395,7 +2739,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:n #1 \q_stop
\tl_if_empty:NF \l__tblr_saved_table_commands_before_cell_text_tl
{
\__tblr_prop_gput:nxV { command }
@@ -2405,26 +2749,26 @@
\tl_set_eq:NN #1 \l__tblr_saved_cell_text_after_table_commands_tl
}
-%% #1 maybe a single token or multiple tokens given in braces
-\cs_new_protected:Npn \__tblr_extract_table_commands_next:w #1
+%% #1 maybe a single token or multiple tokens from a pair of braces
+\cs_new_protected:Npn \__tblr_extract_table_commands_next:n #1
{
- \clist_if_in:NnTF \g__tblr_table_commands_clist { #1 }
+ \tl_if_single_token:nTF {#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 }
- }
- {
- \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 }
+ }
{
- \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} }
}
+ { \__tblr_save_real_cell_text:w {#1} }
}
\cs_new_protected:Npn \__tblr_extract_multicolumn_command:Nn #1 #2
@@ -2469,30 +2813,30 @@
}
{
\bool_if:NTF \l__tblr_table_command_unbrace_next_bool
- { \__tblr_last_unbraced:Nn \__tblr_extract_table_commands_next:w }
- { \__tblr_extract_table_commands_next:w }
+ { \__tblr_last_unbraced:Nn \__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 \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 +2847,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 +2856,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,97 +2866,93 @@
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:
+\tl_new:N \l__tblr_inner_spec_measure_tl
+\tl_new:N \l__tblr_inner_spec_verb_tl
+
+\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 }
- }
-
-\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 }
+ \tl_clear:N \l__tblr_inner_spec_measure_tl
+ \tl_clear:N \l__tblr_inner_spec_verb_tl
+ \keys_set:nv { tblr } { l__tblr_default_ \l__tblr_env_name_tl _inner_tl }
}
-\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, verb,
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},
+ verb .tl_set:N = \l__tblr_inner_spec_verb_tl,
+ verb .default:n = lite,
columns .code:n = \__tblr_set_every_column_aux:n {#1},
rows .code:n = \__tblr_set_every_row_aux:n {#1},
cells .code:n = \__tblr_set_every_cell_aux:n {#1},
@@ -2625,6 +2965,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 +3000,108 @@
{ \__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 },
+ 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},
+ 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 },
+ 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},
+ 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 +3124,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 +3162,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 +3175,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 +3193,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
@@ -2768,10 +3205,13 @@
\xleaders \l__tblr_b_tl \vfil
}
{
+ %% When using text as vline, we need to omit abovepos and belowpos.
+ \unskip
\hbox_set:Nn \l__tblr_d_box { \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
+ \vss
}
\group_end:
}
@@ -2783,11 +3223,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 +3237,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 +3254,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 +3333,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 +3345,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 +3355,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
@@ -2920,7 +3388,9 @@
\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
@@ -2939,13 +3409,46 @@
{ \__tblr_get_cell_text_real:nn { #1 } { #2 } }
}
+\tl_new:N \l__tblr_cell_fg_tl
+\tl_new:N \l__tblr_cell_cmd_tl
+\tl_new:N \l__tblr_cell_mode_tl
+\bool_new:N \l__tblr_cell_math_mode_bool
+\tl_const:Nn \l__tblr_cell_math_style_tl { \relax }
+\tl_const:Nn \l__tblr_cell_imath_style_tl { \textstyle }
+\tl_const:Nn \l__tblr_cell_dmath_style_tl { \displaystyle }
+
%% Get cell text, #1: row number, #2: column number
%% If the width of the cell is not set, split it with \\ and compute the width
%% Therefore we always get a vbox for any cell
\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_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_cell_mode_tl
+ { \__tblr_data_item:neen { cell } {#1} {#2} { mode } }
+ \tl_if_empty:NT \l__tblr_cell_mode_tl
+ {
+ \bool_if:NTF \l__tblr_math_mode_bool
+ { \tl_set:Nn \l__tblr_cell_mode_tl { math } }
+ { \tl_set:Nn \l__tblr_cell_mode_tl { text } }
+ }
+ \tl_if_eq:NnTF \l__tblr_cell_mode_tl { text }
+ { \bool_set_false:N \l__tblr_cell_math_mode_bool }
+ {
+ \bool_set_true:N \l__tblr_cell_math_mode_bool
+ \tl_put_left:Nv \l__tblr_c_tl
+ { l__tblr_cell_ \l__tblr_cell_mode_tl _style_tl }
+ \tl_put_left:Nn \l__tblr_c_tl { $ }
+ \tl_put_right:Nn \l__tblr_c_tl { $ }
+ }
+ \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
@@ -2959,35 +3462,80 @@
}
\dim_compare:nNnT { \l__tblr_w_tl } < { 0pt } % column width unset
{
- \bool_if:NTF \l__tblr_math_mode_bool
+ \bool_if:NTF \l__tblr_cell_math_mode_bool
{
- \hbox_set:Nn \l_tmpa_box { $\l__tblr_c_tl$ }
+ \hbox_set:Nn \l_tmpa_box { \l__tblr_c_tl }
\tl_set:Nx \l__tblr_w_tl { \box_wd:N \l_tmpa_box }
}
{
- \tl_set_eq:NN \l_tmpb_tl \l__tblr_c_tl
- \__tblr_insert_braces:N \l_tmpb_tl
- \seq_set_split:NnV \l_tmpa_seq { \\ } \l_tmpb_tl
- \tl_set:Nn \l__tblr_w_tl { 0pt }
- \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 }
- \tl_set:Nx \l__tblr_w_tl
- { \dim_max:nn { \l__tblr_w_tl } { \box_wd:N \l_tmpa_box } }
- }
+ \__tblr_get_cell_size_with_box:
}
}
+ \tl_set:Nx \l__tblr_cell_fg_tl
+ { \__tblr_data_item:neen { cell } {#1} {#2} { foreground } }
+ \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:
}
+\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,
+%% and we can not fix this problem with \leavevmode command.
+%% See https://tex.stackexchange.com/q/460489.
+%% But we need to use \color command for fg option,
+%% or users may use it in the middle of the cell text,
+%% so we have redefine \color command and disable it before measuring cell.
+
+\NewDocumentCommand \__tblr_fake_color_command:w { o m } { }
+
+\cs_new_protected:Npn \__tblr_get_cell_size_with_vbox:
+ {
+ \hbox_set:Nn \l_tmpa_box
+ {
+ \cs_set_eq:NN \color \__tblr_fake_color_command:w
+ \begin{varwidth}{\paperwidth}
+ \l__tblr_f_tl
+ \__tblr_rescan_cell_tokens:N \l__tblr_c_tl
+ \end{varwidth}
+ }
+ \tl_set:Nx \l__tblr_w_tl { \box_wd:N \l_tmpa_box }
+ }
+
+\cs_new_protected:Npn \__tblr_get_cell_size_with_hbox:
+ {
+ \tl_set_eq:NN \l_tmpb_tl \l__tblr_c_tl
+ \__tblr_insert_braces:N \l_tmpb_tl
+ \seq_set_split:NnV \l_tmpa_seq { \\ } \l_tmpb_tl
+ \tl_set:Nn \l__tblr_w_tl { 0pt }
+ \seq_map_variable:NNn \l_tmpa_seq \l_tmpa_tl
+ {
+ \__tblr_remove_braces:N \l_tmpa_tl
+ \hbox_set:Nn \l_tmpa_box
+ {
+ \l__tblr_f_tl
+ \__tblr_rescan_cell_tokens:N \l_tmpa_tl
+ }
+ \tl_set:Nx \l__tblr_w_tl
+ { \dim_max:nn { \l__tblr_w_tl } { \box_wd:N \l_tmpa_box } }
+ }
+ }
+
%% #1: cell text; #2: box width
\cs_new_protected:Npn \__tblr_get_vcell_and_sizes:NN #1 #2
{
\group_begin:
- \vbox_set_top:Nn \l_tmpa_box { \__tblr_make_vcell_text:nN #1 #2 }
- \vbox_set:Nn \l_tmpb_box { \__tblr_make_vcell_text:nN #1 #2 }
+ \__tblr_save_counters:n { cell }
+ \vbox_set_top:Nn \l_tmpa_box { \__tblr_make_vcell_text:NN #1 #2 }
+ \__tblr_restore_counters:n { cell }
+ \vbox_set:Nn \l_tmpb_box { \__tblr_make_vcell_text:NN #1 #2 }
\dim_gset:Nn \g__tblr_cell_wd_dim { \box_wd:N \l_tmpb_box }
\dim_gset:Nn \g__tblr_cell_ht_dim
{ \box_ht:N \l_tmpb_box + \box_dp:N \l_tmpb_box }
@@ -3029,22 +3577,40 @@
\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
-\cs_new_protected:Npn \__tblr_make_vcell_text:nN #1 #2
+%% 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 }
+ \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
}
+%% When using verb option, there is an end-of-line character at the end.
+%% This character causes extra horizontal space at the end when "measure=hbox",
+%% or causes extra vertical space at the end with "measure=vbox".
+%% Therefore we have to use an \empty to remove it.
+%% See https://tex.stackexchange.com/q/213659
+\cs_new_protected:Npn \__tblr_rescan_cell_tokens:N #1
+ {
+ \tl_if_empty:NTF \l__tblr_inner_spec_verb_tl
+ { #1 }
+ {
+ %% insert space characters after some control sequences first (issue #112)
+ \regex_replace_all:nnN { (\c{[A-Za-z]*}) ([A-Za-z]) } { \1 \ \2 } #1
+ \regex_replace_all:nnN { . } { \c{string} \0 } #1
+ \tl_set:Nx #1 { #1 \noexpand \empty }
+ \exp_args:NV \tex_scantokens:D #1
+ }
+ }
+
%% #1: total height dimension; #2: head dimension; #3: foot dimension;
%% #4: tl for resulting upper size; #5: tl for resulting lower size
@@ -3238,7 +3804,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 +3837,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 +3847,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
@@ -3290,7 +3856,8 @@
}
%% If all columns have negative coefficients and small natural widths,
-%% \l__column_coefficient_prop will be empty after one or more rounds
+%% \l__column_coefficient_prop will be empty after one or more rounds.
+%% We reset @row-height, etc for \linewidth graphics in X columns (issue #80)
\cs_new_protected:Npn \__tblr_adjust_extendable_column_width:
{
\bool_while_do:nn
@@ -3305,6 +3872,14 @@
\__tblr_data_gput:nnne { column } {##1} { width } {##2}
\__tblr_data_gput:nnnn { column } {##1} { @col-width } { 0pt }
}
+ \int_step_inline:nn { \c@rowcount }
+ {
+ \__tblr_data_gput:nnnn { row } {##1} { @row-height } { 0pt }
+ \__tblr_data_gput:nnnn { row } {##1} { @row-head } { 0pt }
+ \__tblr_data_gput:nnnn { row } {##1} { @row-foot } { 0pt }
+ \__tblr_data_gput:nnnn { row } {##1} { @row-upper } { 0pt }
+ \__tblr_data_gput:nnnn { row } {##1} { @row-lower } { 0pt }
+ }
\__tblr_calculate_cell_sizes:
}
@@ -3378,11 +3953,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 +3968,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 +3996,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 +4028,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 +4160,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 +4253,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 +4333,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:
{
@@ -3725,8 +4362,8 @@
%% Cell is spanned from col #1 to col #2, #3 is the return dim
\cs_new_protected:Npn \__tblr_calc_span_widths:nnN #1 #2 #3
{
- \dim_zero:N #3
- \int_step_inline:nnn { #1 } { #2 }
+ \dim_set:Nn #3 { \prop_item:Ne \l__tblr_col_item_skip_size_prop { item[#1] } }
+ \int_step_inline:nnn { #1 + 1 } { #2 }
{
\tl_set:Nx \l_tmpa_tl
{ \prop_item:Ne \l__tblr_col_item_skip_size_prop { skip[##1] } }
@@ -3738,75 +4375,1076 @@
\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
{
- \bool_if:NTF \l__tblr_long_table_bool
- { \__tblr_build_long_table:n {#1} }
- { \__tblr_build_short_table:n {#1} }
+ \prop_item:Nn \l__tblr_element_styles_prop {#1}
}
-\dim_new:N \l__tblr_remain_height_dim
-\tl_new:N \l__tblr_long_from_tl
+\cs_new_protected:Npn \__tblr_style_log:
+ {
+ \prop_log:N \l__tblr_element_styles_prop
+ }
-\cs_new_protected:Npn \__tblr_build_long_table:n #1
+\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 }
{
- %\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
+ \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} }
{
- \dim_set:Nn \l_tmpa_dim
+ %% 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 } { empty } { }
+\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 } { empty } { }
+\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 } { empty } { }
+\DefTblrTemplate { caption-lot } { normal }
+ {
+ \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 { \thetable } { \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 } { empty } { }
+\DefTblrTemplate { caption-tag } { normal } { \tablename\hspace{0.25em}\thetable }
+\SetTblrTemplate { caption-tag } { normal }
+
+\DefTblrTemplate { caption-sep } { empty } { }
+\DefTblrTemplate { caption-sep } { normal } { : \enskip }
+\SetTblrTemplate { caption-sep } { normal }
+
+\DefTblrTemplate { caption-text } { empty } { }
+\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 } { empty } { }
+\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
+ }
+ }
+\DefTblrTemplate { caption } { simple }
+ {
+ \UseTblrAlign { caption }
+ \UseTblrIndent { caption }
+ \UseTblrHang { caption }
+ \leavevmode
+ \UseTblrTemplate { caption-tag } { default }
+ \UseTblrTemplate { caption-sep } { default }
+ \UseTblrTemplate { caption-text } { default }
+ \par
+ }
+\SetTblrTemplate { caption } { normal }
+
+\DefTblrTemplate { capcont } { empty } { }
+\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
+ }
+ }
+\DefTblrTemplate { capcont } { simple }
+ {
+ \UseTblrAlign { caption }
+ \UseTblrIndent { caption }
+ \UseTblrHang { caption }
+ \leavevmode
+ \UseTblrTemplate { caption-tag } { default }
+ \UseTblrTemplate { caption-sep } { default }
+ \UseTblrTemplate { caption-text } { default }
+ \space
+ \UseTblrTemplate { conthead-text } { default }
+ \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 }
+ }
+
+\DefTblrTemplate { note-border } { empty }
+ {
+ \hypersetup { pdfborder = { 0 ~ 0 ~ 0 } }
+ }
+\DefTblrTemplate { note-border } { normal }
+ {
+ \hypersetup { pdfborder = { 0 ~ 0 ~ 1 } }
+ }
+\SetTblrTemplate { note-border } { empty }
+
+\NewDocumentCommand \TblrNote { m }
+ {
+ \cs_if_exist:NT \hypersetup { \ExpTblrTemplate { note-border }{ default } }
+ \__tblr_hyper_link:nn {#1}
+ { \textsuperscript { \sffamily \UseTblrFont { note-tag } #1 } }
+ }
+
+\DefTblrTemplate { note-tag } { empty } { }
+\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 } { empty } { }
+\DefTblrTemplate { note-sep } { normal } { \space }
+\SetTblrTemplate { note-sep } { normal }
+
+\DefTblrTemplate { note-text } { empty } { }
+\DefTblrTemplate { note-text } { normal } { \InsertTblrNoteText }
+\SetTblrTemplate { note-text } { normal }
+
+\DefTblrTemplate { note } { empty } { }
+\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 } { empty } { }
+\DefTblrTemplate { remark-tag } { normal }
+ {
+ \itshape \UseTblrFont { remark-tag } \InsertTblrRemarkTag
+ }
+\SetTblrTemplate { remark-tag } { normal }
+
+\DefTblrTemplate { remark-sep } { empty } { }
+\DefTblrTemplate { remark-sep } { normal } { : \space }
+\SetTblrTemplate { remark-sep } { normal }
+
+\DefTblrTemplate { remark-text } { empty } { }
+\DefTblrTemplate { remark-text } { normal } { \InsertTblrRemarkText }
+\SetTblrTemplate { remark-text } { normal }
+
+\DefTblrTemplate { remark } { empty } { }
+\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 { head } { empty } { }
+\DefTblrTemplate { foot } { empty } { }
+
+\DefTblrTemplate { firsthead } { normal }
+ {
+ \UseTblrTemplate { caption } { 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_text_item:ne { hline } { [\l__tblr_i_tl] / @hline-height }
+ \__tblr_spec_item:nn { vline } { [##1] / @vline-width }
+
- \__tblr_data_item:nen { row } { \l__tblr_i_tl } { abovesep }
+ \__tblr_data_item:nnn { column } {##1} { leftsep }
+
- \__tblr_data_item:nen { row } { \l__tblr_i_tl } { @row-height }
+ \__tblr_data_item:nnn { column } {##1} { @col-width }
+
- \__tblr_data_item:nen { row } { \l__tblr_i_tl } { belowsep }
+ \__tblr_data_item:nnn { column } {##1} { rightsep }
}
- \dim_compare:nNnTF
- { \l_tmpa_dim } > { \l__tblr_remain_height_dim }
+ }
+ \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
+ {
+ \__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 } }
+ }
+
+\cs_new_protected:Npn \__tblr_build_tall_table_head_foot:
+ {
+ \__tblr_get_table_width:
+ \__tblr_build_table_head_aux:Nn \l__tblr_table_firsthead_box
+ {
+ \__tblr_build_table_label_entry:
+ \UseTblrTemplate { firsthead } { default }
+ }
+ \__tblr_build_table_foot_aux:Nn
+ \l__tblr_table_lastfoot_box { \UseTblrTemplate { lastfoot } { default } }
+ }
+
+\cs_new_protected:Npn \__tblr_build_table_label_entry:
+ {
+ \tl_set:Nx \l_tmpa_tl { \InsertTblrText { label } }
+ \tl_if_eq:NnTF \l_tmpa_tl { none }
+ {
+ \SetTblrTemplate { caption-tag }{ empty }
+ \SetTblrTemplate { caption-sep }{ empty }
+ }
+ {
+ \refstepcounter { table }
+ \tl_if_empty:NF \l_tmpa_tl { \exp_args:NV \label \l_tmpa_tl }
+ }
+ \tl_set:Nx \l_tmpb_tl { \InsertTblrText { entry } }
+ \tl_if_eq:NnF \l_tmpb_tl { none }
+ { \UseTblrTemplate { caption-lot } { 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 } } }
+ {
+ \tl_if_eq:enTF { \__tblr_spec_item:nn { outer } { tall } } { true }
+ {
+ \__tblr_build_tall_table:e
+ { \__tblr_spec_item:nn { outer } { valign } }
+ }
+ {
+ \__tblr_build_short_table:e
+ { \__tblr_spec_item:nn { outer } { valign } }
+ }
+ }
+ }
+
+\dim_new:N \l__tblr_remain_height_dim
+\int_new:N \l__tblr_long_from_int
+\int_new:N \l__tblr_long_to_int
+\int_new:N \l__tblr_curr_i_int
+\int_new:N \l__tblr_prev_i_int
+\int_new:N \l__tblr_table_page_int
+\bool_new:N \l__tblr_page_break_curr_bool
+\bool_new:N \l__tblr_page_break_prev_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
+ {
+ \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: % enter horizontal mode to update \pagetotal
+ \LogTblrTracing { page }
+ \hrule height ~ 0pt
+ \nobreak % prevent page break after \hrule (see issue #42)
+ \LogTblrTracing { page }
+ \int_set:Nn \l__tblr_table_page_int {1}
+ \__tblr_build_head_foot:
+ \dim_set:Nn \l__tblr_remain_height_dim
+ { \pagegoal - \pagetotal - \l__tblr_row_head_foot_dim }
+ \int_set:Nn \l__tblr_long_from_int { \l__tblr_row_head_tl + 1 }
+ \int_set:Nn \l__tblr_long_to_int { \c@rowcount - ( \l__tblr_row_foot_tl + 0 ) }
+ \int_set:Nn \l__tblr_curr_i_int { \l__tblr_long_from_int - 1 }
+ \int_do_while:nNnn { \l__tblr_curr_i_int } < { \l__tblr_long_to_int }
+ {
+ \int_set_eq:NN \l__tblr_prev_i_int \l__tblr_curr_i_int
+ \__tblr_get_next_table_rows:NNNN
+ \l__tblr_long_to_int \l__tblr_curr_i_int
+ \l_tmpa_dim \l__tblr_page_break_curr_bool
+ \__tblr_check_table_page_break:NNN
+ \l__tblr_remain_height_dim \l_tmpa_dim \l__tblr_page_break_prev_bool
+ \__tblr_do_if_tracing:nn { page } { \int_log:N \l__tblr_curr_i_int }
+ \bool_if:NTF \l__tblr_page_break_prev_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 } }
+ \int_compare:nNnTF
+ { \l__tblr_long_from_int } > { \l__tblr_prev_i_int }
+ {
+ % See issue #42: if longtblr starts at the bottom of a page,
+ % \pagetotal maybe exceed \pagegoal after adding presep,
+ % or after adding rowhead or rowfoot of the table.
+ % In these cases, we will not typeset table in this page,
+ % but rather do some negative \vskip and execute \newpage.
+ \skip_vertical:n { \pagegoal - \pagetotal }
+ }
+ {
+ \__tblr_build_page_table:nnx {#1}
+ { \int_use:N \l__tblr_long_from_int }
+ { \int_use:N \l__tblr_prev_i_int }
+ \int_incr:N \l__tblr_table_page_int
+ \int_set:Nn \l__tblr_long_from_int { \l__tblr_prev_i_int + 1 }
+ }
\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 }
- \tl_set_eq:NN \l__tblr_long_from_tl \l__tblr_i_tl
+ { \pagegoal - \pagetotal - \l__tblr_row_head_foot_dim - \l_tmpa_dim }
}
{
- \dim_add:Nn \l__tblr_remain_height_dim { -\l_tmpa_dim }
+ \bool_if:NTF \l__tblr_page_break_curr_bool
+ {
+ \__tblr_build_page_table:nnx {#1}
+ { \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
+ \hbox{}\kern-\topskip\nobreak
+ \noindent
+ \LogTblrTracing { page }
+ \dim_set:Nn \l__tblr_remain_height_dim
+ { \pagegoal - \pagetotal - \l__tblr_row_head_foot_dim }
+ \int_set:Nn \l__tblr_long_from_int { \l__tblr_curr_i_int + 1 }
+ }
+ { \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}
+ { \int_use:N \l__tblr_long_from_int } { \int_use:N \l__tblr_long_to_int }
+ \skip_vertical:n { \__tblr_spec_item:nn { outer } { postsep } }
+ % In the past we used "\hrule height ~ 0pt" to get strict postsep,
+ % but the postsep was not discarded when page breaks, see issue #39.
+ % Therefore we use \nointerlineskip here.
+ \nointerlineskip
}
+\cs_generate_variant:Nn \__tblr_build_long_table:n { e }
+%% #1: int with index of the last row; #2: int with index of current row;
+%% #3: row dimension; #4: break page or not.
+\cs_new_protected:Npn \__tblr_get_next_table_rows:NNNN #1 #2 #3 #4
+ {
+ \bool_set_true:N \l_tmpa_bool
+ \dim_zero:N #3
+ \bool_set_false:N #4
+ \bool_while_do:Nn \l_tmpa_bool
+ {
+ \int_incr:N #2
+ \dim_add:Nn #3
+ {
+ \__tblr_data_item:nen { row } { \int_use:N #2 } { abovesep }
+ +
+ \__tblr_data_item:nen { row } { \int_use:N #2 } { @row-height }
+ +
+ \__tblr_data_item:nen { row } { \int_use:N #2 } { belowsep }
+ +
+ \__tblr_spec_item:ne { hline }
+ { [ \int_eval:n { #2 + 1 } ] / @hline-height }
+ }
+ \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 }
+ { \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 }
+ }
+ }
+ { \bool_set_false:N \l_tmpa_bool }
+ }
+ }
+
+\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
+ \__tblr_cover_two_vboxes:NN \l__tblr_row_head_box \l__tblr_table_box
+ \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 }
+%% To solve the problem of missing hlines of long tables in some PDF readers,
+%% We need to draw body rows before head rows (see issue #88).
+\cs_new_protected:Npn \__tblr_cover_two_vboxes:NN #1 #2
+ {
+ \dim_set:Nn \l_tmpa_dim { \box_ht:N #1 + \box_dp:N #1 }
+ \dim_set:Nn \l_tmpb_dim { \box_ht:N #2 + \box_dp:N #2 }
+ \skip_vertical:N \l_tmpa_dim
+ \hrule height ~ 0pt
+ \box_use:N #2
+ \skip_vertical:n { - \l_tmpa_dim - \l_tmpb_dim }
+ \hrule height ~ 0pt
+ \box_use:N #1
+ \skip_vertical:N \l_tmpb_dim
+ \hrule height ~ 0pt
+ }
+
\cs_new_protected:Npn \__tblr_halign_whole:Nn #1 #2
{
\noindent
@@ -3818,42 +5456,129 @@
}
}
+%% #1: table alignment
+%% For tall table, we need to leave vmode first.
+%% Since there may be \centering in table environment,
+%% We use \raggedright to reset alignement for table head/foot.
+\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
+ {
+ \box_use:N \l__tblr_table_firsthead_box
+ \hrule height ~ 0pt
+ \box_use:N \l__tblr_table_box
+ \hrule height ~ 0pt
+ \box_use:N \l__tblr_table_lastfoot_box
+ }
+ \__tblr_valign_whole:Nn \l__tblr_table_box #1
+ }
+\cs_generate_variant:Nn \__tblr_build_tall_table:n { e }
+
+%% #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
+\box_new:N \l__tblr_table_hlines_box
+\box_new:N \l__tblr_hline_box
+\box_new:N \l__tblr_row_box
%% #1: row from; #2: row to
+%% To fix disappeared hlines with colorful tables in Adobe Reader (see #76),
+%% we collect all hlines and draw them at the end of the table.
\cs_new_protected:Npn \__tblr_build_one_table:nn #1 #2
{
+ \box_clear:N \l__tblr_table_hlines_box
\vbox_set:Nn \l__tblr_table_box
{
\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 }
+ { \__tblr_put_one_hline: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 }
+ \__tblr_put_one_row: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
+ {
+ \__tblr_put_one_hline:n
+ { \__tblr_build_hline:n { \int_eval:n {#2 + 1} } }
+ }
+ \skip_vertical:n
+ {
+ - \box_ht:N \l__tblr_table_hlines_box
+ - \box_dp:N \l__tblr_table_hlines_box
+ }
+ \box_use:N \l__tblr_table_hlines_box
}
+ \bool_set_true:N \l__tblr_build_first_hline_bool
+ \bool_set_true:N \l__tblr_build_last_hline_bool
}
+\cs_new_protected:Npn \__tblr_put_one_hline:n #1
+ {
+ \hbox_set:Nn \l__tblr_hline_box {#1}
+ \skip_vertical:n { \box_ht:N \l__tblr_hline_box + \box_dp:N \l__tblr_hline_box }
+ \vbox_set:Nn \l__tblr_table_hlines_box
+ {
+ \vbox_unpack:N \l__tblr_table_hlines_box
+ \box_use:N \l__tblr_hline_box
+ }
+ }
+
+\cs_new_protected:Npn \__tblr_put_one_row:n #1
+ {
+ \hbox_set:Nn \l__tblr_row_box {#1}
+ \vbox_set:Nn \l__tblr_table_hlines_box
+ {
+ \vbox_unpack:N \l__tblr_table_hlines_box
+ \skip_vertical:n
+ { \box_ht:N \l__tblr_row_box + \box_dp:N \l__tblr_row_box }
+ }
+ \box_use:N \l__tblr_row_box
+ }
+
+%% #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 +5593,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 +5627,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 +5662,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 +5681,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 +5704,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,14 +5712,17 @@
\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 }
{
+ \__tblr_get_hline_left_right_skips:nnn {#1} {#2} {##1}
+ \skip_horizontal:N \l__tblr_hline_leftskip_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}
+ \skip_horizontal:N \l__tblr_hline_rightskip_dim
}
\box_set_ht:Nn \l__tblr_b_box { \l__tblr_h_tl }
\box_set_dp:Nn \l__tblr_b_box { 0pt }
@@ -4009,10 +5741,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 }
+
@@ -4024,24 +5756,92 @@
}
}
+\dim_new:N \l__tblr_hline_leftskip_dim
+\dim_new:N \l__tblr_hline_rightskip_dim
+
+%% Calculate left and right skips from leftpos and rightpos specifications
+%% #1: row number; #2: column number; #3: hline index;
+\cs_new_protected:Npn \__tblr_get_hline_left_right_skips:nnn #1 #2 #3
+ {
+ \tl_set:Nx \l__tblr_hline_leftpos_tl
+ { \__tblr_spec_item:ne { hline } { [#1][#2](#3) / leftpos } }
+ \tl_if_empty:NT \l__tblr_hline_leftpos_tl
+ { \tl_set:Nn \l__tblr_hline_leftpos_tl {1} } % default position
+ \tl_set:Nx \l__tblr_hline_rightpos_tl
+ { \__tblr_spec_item:ne { hline } { [#1][#2](#3) / rightpos } }
+ \tl_if_empty:NT \l__tblr_hline_rightpos_tl
+ { \tl_set:Nn \l__tblr_hline_rightpos_tl {1} } % default position
+ \fp_compare:nNnT { \l__tblr_hline_leftpos_tl } < {1}
+ {
+ \dim_set:Nn \l_tmpa_dim
+ { \__tblr_spec_item:ne { vline } { [#2] / @vline-width } }
+ \dim_set:Nn \l_tmpb_dim
+ { \__tblr_data_item:nen { column } {#2} { leftsep } }
+ \fp_compare:nNnTF { \l__tblr_hline_leftpos_tl } < {0}
+ {
+ \dim_set:Nn \l__tblr_hline_leftskip_dim
+ { \l_tmpa_dim - \l__tblr_hline_leftpos_tl \l_tmpb_dim }
+ }
+ {
+ \dim_set:Nn \l__tblr_hline_leftskip_dim
+ { \l_tmpa_dim - \l__tblr_hline_leftpos_tl \l_tmpa_dim }
+ }
+ }
+ \fp_compare:nNnT { \l__tblr_hline_rightpos_tl } < {1}
+ {
+ \dim_set:Nn \l_tmpa_dim
+ {
+ \__tblr_spec_item:ne { vline }
+ { [\int_eval:n { #2 + 1 }] / @vline-width }
+ }
+ \dim_set:Nn \l_tmpb_dim
+ { \__tblr_data_item:nen { column } {#2} { rightsep } }
+ \fp_compare:nNnTF { \l__tblr_hline_rightpos_tl } < {0}
+ {
+ \dim_set:Nn \l__tblr_hline_rightskip_dim
+ { \l_tmpa_dim - \l__tblr_hline_rightpos_tl \l_tmpb_dim }
+ }
+ {
+ \dim_set:Nn \l__tblr_hline_rightskip_dim
+ { \l_tmpa_dim - \l__tblr_hline_rightpos_tl \l_tmpa_dim }
+ }
+ }
+ }
+
\dim_new:N \l__tblr_row_ht_dim
\dim_new:N \l__tblr_row_dp_dim
\dim_new:N \l__tblr_row_abovesep_dim
\dim_new:N \l__tblr_row_belowsep_dim
+\box_new:N \l__tblr_row_vlines_box
+\box_new:N \l__tblr_vline_box
+\box_new:N \l__tblr_cell_box
%% Build current row, #1: row number
+%% To fix disappeared vlines with colorful tables in Adobe Reader (see #76),
+%% we collect all vlines and draw them at the end of the row.
\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
\vrule width ~ 0pt ~ height ~ \l__tblr_row_ht_dim ~ depth ~ \l__tblr_row_dp_dim
+ \hbox_set:Nn \l__tblr_row_vlines_box
+ {
+ \vrule width ~ 0pt ~ height ~ \l__tblr_row_ht_dim
+ ~ depth ~ \l__tblr_row_dp_dim
+ }
\int_step_variable:nNn { \c@colcount } \l__tblr_j_tl
{
- \__tblr_build_vline_segment:nn {#1} { \l__tblr_j_tl }
- \__tblr_build_cell:NN #1 \l__tblr_j_tl
+ \__tblr_put_one_vline:n
+ { \__tblr_build_vline_segment:nn {#1} { \l__tblr_j_tl } }
+ \__tblr_put_one_cell:n { \__tblr_build_cell:NN #1 \l__tblr_j_tl }
}
- \__tblr_build_vline_segment:nn {#1} { \int_eval:n {\c@colcount + 1} }
+ \__tblr_put_one_vline:n
+ { \__tblr_build_vline_segment:nn {#1} { \int_eval:n {\c@colcount + 1} } }
+ \skip_horizontal:n { - \box_wd:N \l__tblr_row_vlines_box }
+ \box_use:N \l__tblr_row_vlines_box
}
%% Read from table specifications and calculate inner height/depth of the row
@@ -4074,13 +5874,35 @@
}
\cs_generate_variant:Nn \__tblr_get_row_inner_height_depth:nNNNN { V }
+\cs_new_protected:Npn \__tblr_put_one_vline:n #1
+ {
+ \hbox_set:Nn \l__tblr_vline_box {#1}
+ \skip_horizontal:n { \box_wd:N \l__tblr_vline_box }
+ \hbox_set:Nn \l__tblr_row_vlines_box
+ {
+ \hbox_unpack:N \l__tblr_row_vlines_box
+ \box_use:N \l__tblr_vline_box
+ }
+ }
+
+\cs_new_protected:Npn \__tblr_put_one_cell:n #1
+ {
+ \hbox_set:Nn \l__tblr_cell_box {#1}
+ \hbox_set:Nn \l__tblr_row_vlines_box
+ {
+ \hbox_unpack:N \l__tblr_row_vlines_box
+ \skip_horizontal:n { \box_wd:N \l__tblr_cell_box }
+ }
+ \box_use:N \l__tblr_cell_box
+ }
+
%% #1: row number, #2: column number
\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 +5915,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,29 +5925,25 @@
\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 } }
- \tl_set:Nx \l__tblr_b_tl
- {
- \__tblr_text_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 } }
+ { \__tblr_prop_item:ne { inner } { rulesep } }
\hbox_set:Nn \l__tblr_a_box
{
\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_above_below_skips:nnn {#1} {#2} {##1}
+ \skip_vertical:N \l__tblr_vline_aboveskip_dim
\__tblr_get_vline_segment_child:nnnxx {#1} {#2} {##1}
{ \dim_eval:n { \l__tblr_row_ht_dim } }
- { \dim_eval:n { \l__tblr_row_dp_dim + \l__tblr_b_tl } }
- \skip_vertical:n { - \l__tblr_b_tl }
+ { \dim_eval:n { \l__tblr_row_dp_dim } }
+ \skip_vertical:N \l__tblr_vline_belowskip_dim
}
\box_set_wd:Nn \l__tblr_b_box { \l__tblr_w_tl }
\box_use:N \l__tblr_b_box
@@ -4139,6 +5957,68 @@
\box_use:N \l__tblr_c_box
}
+\dim_new:N \l__tblr_vline_aboveskip_dim
+\dim_new:N \l__tblr_vline_belowskip_dim
+
+%% Calculate above and below skips from abovepos and belowpos specifications
+%% #1: row number; #2: column number; #3: vline index;
+\cs_new_protected:Npn \__tblr_get_vline_above_below_skips:nnn #1 #2 #3
+ {
+ \tl_set:Nx \l__tblr_vline_abovepos_tl
+ { \__tblr_spec_item:ne { vline } { [#1][#2](#3) / abovepos } }
+ \tl_if_empty:NT \l__tblr_vline_abovepos_tl
+ {
+ \tl_set:Nn \l__tblr_vline_abovepos_tl {0} % default position
+ }
+ \tl_set:Nx \l__tblr_vline_belowpos_tl
+ { \__tblr_spec_item:ne { vline } { [#1][#2](#3) / belowpos } }
+ \tl_if_empty:NT \l__tblr_vline_belowpos_tl
+ {
+ \tl_set:Nn \l__tblr_vline_belowpos_tl {0} % default position
+ }
+ \fp_compare:nNnF { \l__tblr_vline_abovepos_tl } = {0}
+ {
+ \dim_set:Nn \l_tmpa_dim
+ { \__tblr_spec_item:ne { hline } { [#1] / @hline-height } }
+ \fp_compare:nNnTF { \l__tblr_vline_abovepos_tl } < {0}
+ {
+ \dim_set:Nn \l__tblr_vline_aboveskip_dim
+ { - \l__tblr_vline_abovepos_tl \l__tblr_row_abovesep_dim }
+ }
+ {
+ \dim_set:Nn \l__tblr_vline_aboveskip_dim
+ { - \l__tblr_vline_abovepos_tl \l_tmpa_dim }
+ }
+ }
+ %% To join two vline segment above and below a cline,
+ %% we choose to extend every vline downwards a little (#55).
+ \fp_compare:nNnTF { \l__tblr_vline_belowpos_tl } = {0}
+ {
+ \dim_set:Nn \l__tblr_vline_belowskip_dim
+ {
+ - \__tblr_spec_item:ne { hline }
+ { [\int_eval:n { #1 + 1 }](1) / @hline-height }
+ + 0pt
+ }
+ }
+ {
+ \dim_set:Nn \l_tmpa_dim
+ {
+ \__tblr_spec_item:ne { hline }
+ { [\int_eval:n { #1 + 1 }] / @hline-height }
+ }
+ \fp_compare:nNnTF { \l__tblr_vline_belowpos_tl } < {0}
+ {
+ \dim_set:Nn \l__tblr_vline_belowskip_dim
+ { - \l__tblr_vline_belowpos_tl \l__tblr_row_belowsep_dim }
+ }
+ {
+ \dim_set:Nn \l__tblr_vline_belowskip_dim
+ { - \l__tblr_vline_belowpos_tl \l_tmpa_dim }
+ }
+ }
+ }
+
\tl_new:N \l__tblr_cell_rowspan_tl
\tl_new:N \l__tblr_cell_colspan_tl
\dim_new:N \l__tblr_cell_wd_dim
@@ -4146,8 +6026,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 } }
@@ -4183,9 +6063,13 @@
{
\hbox_set_to_wd:Nnn \l__tblr_a_box { \l__tblr_cell_wd_dim }
{
- \tl_if_eq:NnF \g__tblr_cell_halign_tl {l} { \hfil }
- \__tblr_get_cell_text:nn {#1} {#2}
- \tl_if_eq:NnF \g__tblr_cell_halign_tl {r} { \hfil }
+ \tl_if_eq:NnTF \g__tblr_cell_halign_tl {j}
+ { \__tblr_get_cell_text:nn {#1} {#2} }
+ {
+ \tl_if_eq:NnF \g__tblr_cell_halign_tl {l} { \hfil }
+ \__tblr_get_cell_text:nn {#1} {#2}
+ \tl_if_eq:NnF \g__tblr_cell_halign_tl {r} { \hfil }
+ }
}
\vbox_set_to_ht:Nnn \l__tblr_b_box { \l__tblr_cell_ht_dim }
{
@@ -4305,20 +6189,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 +6218,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 +6256,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 +6270,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 +6281,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 +6309,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 +6321,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 +6335,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 +6357,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 +6369,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 +6381,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 +6389,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_spec_log:n { outer }
+ }
+
+\cs_new_protected:Npn \__tblr_log_tracing_inner:
{
- \__tblr_prop_log:n { table }
+ \__tblr_prop_log:n { inner }
}
\cs_new_protected:Npn \__tblr_log_tracing_column:
@@ -4500,12 +6428,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 +6465,279 @@
\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}
}
-\ExplSyntaxOff
+%%% --------------------------------------------------------
+%% \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 amsmath and environments +array, +matrix, +cases, ...
+
+\NewTblrLibrary { amsmath }
+ {
+ \RequirePackage { amsmath, environ }
+ \NewTblrEnviron { +array }
+ \SetTblrInner[+array]{colsep = 5pt}
+ \NewEnviron { +matrix } [1] [] {
+ \begin{+array}[expand = \BODY]{
+ column{1} = {leftsep = 0pt}, column{Z} = {rightsep = 0pt},
+ cells = {c}, ##1
+ }
+ \BODY
+ \end{+array}
+ }
+ \NewEnviron { +bmatrix } [1] [] {
+ \left[\begin{+array}[expand = \BODY]{
+ column{1} = {leftsep = 0pt}, column{Z} = {rightsep = 0pt},
+ cells = {c}, ##1
+ }
+ \BODY
+ \end{+array}\right]
+ \ignorespacesafterend
+ }
+ \NewEnviron { +Bmatrix } [1] [] {
+ \left\lbrace\begin{+array}[expand = \BODY]{
+ column{1} = {leftsep = 0pt}, column{Z} = {rightsep = 0pt},
+ cells = {c}, ##1
+ }
+ \BODY
+ \end{+array}\right\rbrace
+ }
+ \NewEnviron { +pmatrix } [1] [] {
+ \left(\begin{+array}[expand = \BODY]{
+ column{1} = {leftsep = 0pt}, column{Z} = {rightsep = 0pt},
+ cells = {c}, ##1
+ }
+ \BODY
+ \end{+array}\right)
+ }
+ \NewEnviron { +vmatrix } [1] [] {
+ \left\lvert\begin{+array}[expand = \BODY]{
+ column{1} = {leftsep = 0pt}, column{Z} = {rightsep = 0pt},
+ cells = {c}, ##1
+ }
+ \BODY
+ \end{+array}\right\rvert
+ }
+ \NewEnviron { +Vmatrix } [1] [] {
+ \left\lVert\begin{+array}[expand = \BODY]{
+ column{1} = {leftsep = 0pt}, column{Z} = {rightsep = 0pt},
+ cells = {c}, ##1
+ }
+ \BODY
+ \end{+array}\right\rVert
+ }
+ \NewEnviron { +cases } [1] [] {
+ \left\lbrace\begin{+array}[expand = \BODY]{
+ column{1} = {leftsep = 0pt}, column{Z} = {rightsep = 0pt},
+ colspec = {ll}, stretch = 1.2, ##1
+ }
+ \BODY
+ \end{+array}\right.
+ }
+ }
+
+%% Library booktabs and commands \toprule, \midrule, \bottomrule
+
+\NewTblrLibrary { booktabs }
+ {
+ % We only use dimensions \aboverulesep and \belowrulesep in booktabs package
+ \RequirePackage { booktabs }
+ \newcommand \tblr@booktabs@hline [1] [] { \hline [##1] }
+ \newcommand \tblr@booktabs@oldhline [1] [] {
+ \hline [abovespace = \aboverulesep, belowspace = \belowrulesep, ##1]
+ }
+ \newcommand \tblr@booktabs@cline [2] [] { \cline [##1] {##2} }
+ \newcommand \tblr@booktabs@oldcline [2] [] {
+ \cline [abovespace = \aboverulesep, belowspace = \belowrulesep, ##1] {##2}
+ }
+ \newcommand \tblr@booktabs@cline@more [2] [] { \SetHline [+] {##2} {##1} }
+ \newcommand \tblr@booktabs@oldcline@more [2] [] {
+ \SetHline [+] {##2} {
+ abovespace = \aboverulesep, belowspace = \belowrulesep, ##1
+ }
+ }
+ \NewTableCommand \toprule [1] [] {
+ \tblr@booktabs@hline [wd=\heavyrulewidth, ##1]
+ }
+ \NewTableCommand \midrule [1] [] {
+ \tblr@booktabs@hline [wd=\lightrulewidth, ##1]
+ }
+ \NewTableCommand \bottomrule [1] [] {
+ \tblr@booktabs@hline [wd=\heavyrulewidth, ##1]
+ }
+ \NewTableCommand \cmidrule [2] [] {
+ \tblr@booktabs@cline [wd=\cmidrulewidth, endpos, ##1] {##2}
+ }
+ \NewTableCommand \cmidrulemore [2] [] {
+ \tblr@booktabs@cline@more [wd=\cmidrulewidth, endpos, ##1] {##2}
+ }
+ \newcommand \tblr@booktabs@change@more [1] { \cmidrulemore }
+ \NewTableCommand \morecmidrules {
+ \peek_meaning:NTF \cmidrule { \tblr@booktabs@change@more } { \relax }
+ }
+ \NewTblrEnviron { booktabs }
+ \SetTblrInner [ booktabs ] { rowsep = 0pt }
+ \RequirePackage { etoolbox }
+ \AtBeginEnvironment { booktabs }
+ {
+ \let \tblr@booktabs@hline = \tblr@booktabs@oldhline
+ \let \tblr@booktabs@cline = \tblr@booktabs@oldcline
+ \let \tblr@booktabs@cline@more = \tblr@booktabs@oldcline@more
+ }
+ \NewTableCommand \specialrule [3]
+ { \hline [##1, abovespace = ##2, belowspace = ##3] }
+ \NewTableCommand \addrowspace [1] [\defaultaddspace]
+ { \SetVspace { abovespace+ = (##1) / 2, belowspace+ = (##1) / 2 } }
+ \NewTableCommand \addlinespace [1] [\defaultaddspace]
+ { \SetVspace { abovespace+ = (##1) / 2, belowspace+ = (##1) / 2 } }
+ }
+
+%% Library counter for resetting all counters
+
+\tl_new:N \__tblr_saved_trial_counters_tl
+\tl_new:N \__tblr_saved_cell_counters_tl
+
+\cs_new_protected:Npn \__tblr_save_counters:n #1 { }
+\cs_new_protected:Npn \__tblr_restore_counters:n #1 { }
+
+%% We use code from tabularx package for resetting all LaTeX counters,
+%% where internal macro \cl@@ckpt looks like the following:
+%% \@elt{page} \@elt{equation} \@elt{enumi} \@elt{enumii} \@elt{enumiii} ...
+
+\NewTblrLibrary { counter }
+ {
+ \cs_set_protected:Npn \__tblr_save_counters:n ##1
+ {
+ \def \@elt ####1 { \global\value{####1} = \the\value{####1} \relax }
+ \tl_set:cx { __tblr_saved_ ##1 _counters_tl } { \cl@@ckpt }
+ \let \@elt = \relax
+ }
+ \cs_set_protected:Npn \__tblr_restore_counters:n ##1
+ {
+ \tl_use:c { __tblr_saved_ ##1 _counters_tl }
+ }
+ }
+
+%% 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_cell_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}, c] }
+ \NewColumnType { s } [1] [] { Q[si = {##1}, c, cmd = \TblrUnit] }
+ \__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_column_gput_cell:nn { cmd } { \TblrNum }
+ }
+ \NewDocumentCommand \TblrNum { m }
+ {
+ \__tblr_siunitx_process:Nn \tablenum {##1}
+ }
+ \NewDocumentCommand \TblrUnit { m }
+ {
+ \__tblr_siunitx_process:Nn \si {##1}
+ }
+ \cs_new_protected:Npn \__tblr_siunitx_process:Nn ##1 ##2
+ {
+ \tl_if_head_is_group:nTF {##2}
+ { ##2 }
+ {
+ \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
+ ##1 {##2}
+ \group_end:
+ }
+ }
+ }
+
+%% Library varwidth and measure option
+
+\NewTblrLibrary { varwidth }
+ {
+ \RequirePackage { varwidth }
+ \clist_gput_left:Nn \g__tblr_table_known_keys_clist { measure }
+ \keys_define:nn { tblr } { measure .tl_set:N = \l__tblr_inner_spec_measure_tl }
+ }
+