diff options
author | Karl Berry <karl@freefriends.org> | 2021-09-01 20:46:06 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-09-01 20:46:06 +0000 |
commit | d4e44131171a82984daed50321a3d4f4cab5b7f4 (patch) | |
tree | e1f64f1629a31d144e89311407a5fa1409f118f5 | |
parent | 671c1be8b30497ad3b3bf02672b74b997984e4f7 (diff) |
tabularray (1sep21)
git-svn-id: svn://tug.org/texlive/trunk@60389 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/tabularray/tabularray.pdf | bin | 680990 -> 725112 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/tabularray/tabularray.tex | 264 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/tabularray/tabularray-2021.sty | 955 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/tabularray/tabularray.sty | 640 |
4 files changed, 1411 insertions, 448 deletions
diff --git a/Master/texmf-dist/doc/latex/tabularray/tabularray.pdf b/Master/texmf-dist/doc/latex/tabularray/tabularray.pdf Binary files differindex c7b3de29caf..198b6fd2118 100644 --- a/Master/texmf-dist/doc/latex/tabularray/tabularray.pdf +++ b/Master/texmf-dist/doc/latex/tabularray/tabularray.pdf diff --git a/Master/texmf-dist/doc/latex/tabularray/tabularray.tex b/Master/texmf-dist/doc/latex/tabularray/tabularray.tex index 1e5b4a104e8..0d502f3bbca 100644 --- a/Master/texmf-dist/doc/latex/tabularray/tabularray.tex +++ b/Master/texmf-dist/doc/latex/tabularray/tabularray.tex @@ -11,7 +11,7 @@ \usepackage[firstpage=true]{background} \backgroundsetup{contents={}} -\UseTblrLibrary{booktabs,diagbox,siunitx} +\UseTblrLibrary{booktabs,diagbox,siunitx,varwidth} \usepackage{hyperref} \hypersetup{ @@ -24,6 +24,7 @@ \tcbset{sharp corners, boxrule=0.5pt, colback=red9} \usepackage{float} +%\usepackage{enumerate} \setcounter{tocdepth}{1} @@ -59,7 +60,7 @@ \renewcommand*{\thefootnote}{*} -\newcommand*{\myversion}{2021M} +\newcommand*{\myversion}{2021N} \newcommand*{\mylpad}[1]{\ifnum#1<10 0\the#1\else\the#1\fi} \colorlet{highback}{azure9} @@ -112,7 +113,7 @@ \noindent \begin{tblr}{ - colspec = {lX}, colsep = 12mm, hlines = {2pt, white}, + colspec = {rX}, colsep = 8mm, hlines = {2pt, white}, row{odd} = {azure8}, row{even} = {gray8}, row{1} = {6em,azure2,fg=white,font=\LARGE\bfseries\sffamily}, row{2-Z} = {3em,font=\Large}, @@ -122,13 +123,14 @@ Version & \myversion\ (\the\year-\mylpad\month-\mylpad\day) \\ Code & \url{https://github.com/lvjr/tabularray} \\ Code & \url{https://bitbucket.org/lvjr/tabularray} \\ - Issue & \url{https://github.com/lvjr/tabularray/issues} \\ Forum & \url{https://github.com/lvjr/tabularray/discussions} \\ + Forum & \url{https://tex.stackexchange.com/questions/tagged/tabularray} \\ + Issue & \url{https://github.com/lvjr/tabularray/issues} \\ \end{tblr} -\begin{codehigh}[boxsep=6mm] +\begin{codehigh}[boxsep=4mm] \begin{tblr}{ - colspec = {lX}, colsep = 12mm, hlines = {2pt, white}, + colspec = {rX}, colsep = 8mm, hlines = {2pt, white}, row{odd} = {azure8}, row{even} = {gray8}, row{1} = {6em,azure2,fg=white,font=\LARGE\bfseries\sffamily}, row{2-Z} = {3em,font=\Large}, @@ -138,8 +140,9 @@ Version & \myversion\ (\the\year-\mylpad\month-\mylpad\day) \\ Code & \url{https://github.com/lvjr/tabularray} \\ Code & \url{https://bitbucket.org/lvjr/tabularray} \\ - Issue & \url{https://github.com/lvjr/tabularray/issues} \\ Forum & \url{https://github.com/lvjr/tabularray/discussions} \\ + Forum & \url{https://tex.stackexchange.com/questions/tagged/tabularray} \\ + Issue & \url{https://github.com/lvjr/tabularray/issues} \\ \end{tblr} \end{codehigh} @@ -565,7 +568,7 @@ With \verb!tabularray! package, you can change the styles of tables via old inte The old interfaces consist of some table commands inside the table contents. Same as \verb!tabular! and \verb!array! environments, -all table commands \textcolor{red3}{must} be put at the beginning ot the cell text. +all table commands \textcolor{red3}{must} be put at the beginning of the cell text. Also, new table commands \textcolor{red3}{must} be defined with \verb!\NewTableCommand!. The new interfaces consist of some options inside the mandatory argument, @@ -590,18 +593,38 @@ hence totally separating the styles and the contents of tables. \section{Hlines and Vlines} -All available keys for hlines and vlines are described in Table \ref{key:hvline}. +All available keys for hlines and vlines are described in Table \ref{key:hline} and Table \ref{key:vline}. \begin{spectblr}[ - caption = {Keys for Hlines and Vlines}, - label = {key:hvline}, + caption = {Keys for Hlines}, + label = {key:hline}, + remark{Note} = {In most cases, you can omit the underlined key names and write only their values.} +]{} + Key & Description and Values & Initial Value \\ + \underline{\K{dash}} & dash style: \V{solid}, \V{dashed} or \V{dotted} & \V{solid} \\ + \K{text} & replace hline with text (like \V{!} specifier in \K{rowspec}) & \None \\ + \underline{\K{wd}} & rule width dimension & \V{0.4pt} \\ + \underline{\K{fg}} & rule color name & \None \\ + \K{leftpos} & crossing or trimming position at the left side & \V{1} \\ + \K{rightpos} & crossing or trimming position at the right side & \V{1} \\ + \K{abovespace} & set \V{belowsep} of previous row (see Table \ref{key:row}) & \V{2pt} \\ + \K{belowspace} & set \V{abovesep} of current row (see Table \ref{key:row}) & \V{2pt} \\ + \K{abovespace+} & increase \V{belowsep} of previous row & \None \\ + \K{belowspace+} & increase \V{abovesep} of current row & \None \\ +\end{spectblr} +\vspace{-2em} +\begin{spectblr}[ + caption = {Keys for Vlines}, + label = {key:vline}, remark{Note} = {In most cases, you can omit the underlined key names and write only their values.} ]{} Key & Description and Values & Initial Value \\ \underline{\K{dash}} & dash style: \V{solid}, \V{dashed} or \V{dotted} & \V{solid} \\ - \K{text} & replace hline/vline with text (like \V{!} specifier in \K{colspec}) & \None \\ - \underline{\K{wd}} & rule width dimension & \None \\ + \K{text} & replace vline with text (like \V{!} specifier in \K{colspec}) & \None \\ + \underline{\K{wd}} & rule width dimension & \V{0.4pt} \\ \underline{\K{fg}} & rule color name & \None \\ + \K{abovepos} & crossing or trimming position at the above side & \V{0} \\ + \K{belowpos} & crossing or trimming position at the below side & \V{0} \\ \end{spectblr} \subsection{Hlines and Vlines in New Interfaces} @@ -675,8 +698,10 @@ Another pair of braces before will draw more hlines/vlines (in which \verb!-! st \end{tblr} \end{demohigh} +Note that you \underline{must} use indexes in order: first 1, then 2, etc. + Options \verb!hline{i}! and \verb!vline{j}! are for setting some hlines and vlines, respectively. -Their values are the same as options \verb!hliness! and \verb!vlines!: +Their values are the same as options \verb!hlines! and \verb!vlines!: \begin{demohigh} \begin{tblr}{ @@ -731,10 +756,49 @@ Now we show the usage of \verb!text! key by the following example% You need to load \verb!chemmacros! package for the \verb!\ch! command. +The \verb!leftpos! and \verb!rightpos! keys specify crossing or trimming positions for hlines. +The possible values for them are decimal numbers between \verb!-1! and \verb!1!. +Their initial values are \verb!1!. + +\begin{center} +\begin{tblr}{width=0.5\textwidth,colspec={rX[l]},hlines} + -1 & the hline is trimmed by \V{colsep} \\ + 0 & the hline only touches the first vline \\ + 1 & the hline touches all the vlines \\ +\end{tblr} +\end{center} + +The \verb!abovepos! and \verb!belowpos! keys for vlines have similar meanings. +But their initial values are \verb!0!. + +\begin{center} +\begin{tblr}{width=0.5\textwidth,colspec={rX[l]},hlines} + -1 & the vline is trimmed by \V{rowsep} \\ + 0 & the vline only touches the first hline \\ + 1 & the vline touches all the hlines \\ +\end{tblr} +\end{center} + +Here is an example for these four keys: + +\begin{demohigh} +\begin{tblr}{ + hline{1,4} = {1}{-}{}, + hline{1,4} = {2}{-}{}, + hline{2,3} = {1}{-}{leftpos = -1, rightpos = -1}, + hline{2,3} = {2}{-}{leftpos = -1, rightpos = -1}, + vline{1,4} = {abovepos = 1, belowpos = 1}, +} + Alpha & Beta & Gamma \\ + Epsilon & Zeta & Eta \\ + Iota & Kappa & Lambda \\ +\end{tblr} +\end{demohigh} + \subsection{Hlines and Vlines in Old Interfaces} The \verb!\hline! command has an optional argument which accepts key-value options. -The available keys are described in Table \ref{key:hvline}. +The available keys are described in Table \ref{key:hline}. \begin{demohigh} \begin{tblr}{llll} @@ -821,7 +885,7 @@ All available keys for cells are described in Table \ref{key:cell} and Table \re ]{} Key & Description and Values & Initial Value \\ \underline{\K{halign}} - & horizontal alignment: \V{l} (left), \V{c} (center), or \V{r} (right) + & horizontal alignment: \V{l} (left), \V{c} (center), \V{r} (right) or \V{j} (justify) & \V{l} \\ \underline{\K{valign}} & vertical alignment: \V{t} (top), \V{m} (middle), \V{b} (bottom), @@ -2022,8 +2086,9 @@ To avoid potential conflict, you need to enable them with \verb!\UseTblrLibrary! \section{Library \texttt{booktabs}} -When you write \verb!\UseTblrLibrary{booktabs}!, -\verb!tabularray! package will define commands \verb!\toprule!, \verb!\midrule!, +With \verb!\UseTblrLibrary{booktabs}! in the preamble of the document, +\verb!tabularray! will load \verb!booktabs! package, +and define \verb!\toprule!, \verb!\midrule!, \verb!\bottomrule! and \verb!\cmidrule! inside \verb!tblr! environment. \begin{demohigh} @@ -2040,24 +2105,113 @@ When you write \verb!\UseTblrLibrary{booktabs}!, \end{tblr} \end{demohigh} -At this moment, \verb!trim! options for \verb!\cmidrule! command are not supported. -(As a workaround, you may insert an empty column to separate two \verb!\cmidrule!'s.) -But rule colors are possible just like \verb!\hline! and \verb!\cline! commands. +Just like \verb!\hline! and \verb!\cline! commands, +you can also specify rule width and color in the optional argument of any of these commands. \begin{demohigh} \begin{tblr}{llll} -\toprule[purple3] - Alpha & Beta & Gamma & Delta \\ +\toprule[2pt,purple3] + Alpha & Beta & Gamma & Delta \\ \midrule[blue3] + Epsilon & Zeta & Eta & Theta \\ +\cmidrule[azure3]{2-3} + Iota & Kappa & Lambda & Mu \\ +\bottomrule[2pt,purple3] +\end{tblr} +\end{demohigh} + +If you need more than one cmidrules, you can use \verb!\cmidrulemore! command. + +\begin{demohigh} +\begin{tblr}{llll} +\toprule + Alpha & Beta & Gamma & Delta \\ +\cmidrule{1-3} \cmidrulemore{2-4} Epsilon & Zeta & Eta & Theta \\ -\cmidrule[azure3]{1-3} +\cmidrule{1-3} \morecmidrules \cmidrule{2-4} Iota & Kappa & Lambda & Mu \\ -\cmidrule[azure3]{2-4} - Nu & Xi & Omicron & Pi \\ -\bottomrule[purple3] +\bottomrule \end{tblr} \end{demohigh} +From version \verb!2021N!, trim options (\verb!l!, \verb!r!, \verb!lr!) +for \verb!\cmidrule! command are also supported. + +\begin{demohigh} +\begin{tblr}{llll} +\toprule + Alpha & Beta & Gamma & Delta \\ +\cmidrule[lr]{1-2} \cmidrule[lr=-0.4]{3-4} + Epsilon & Zeta & Eta & Theta \\ +\cmidrule[r]{1-2} \cmidrule[l]{3-4} + Iota & Kappa & Lambda & Mu \\ +\bottomrule +\end{tblr} +\end{demohigh} + +Note that you need to put \verb!l!, \verb!r! or \verb!lr! option into +the \underline{\color{red3}square brackets}. +and the possible values are decimal numbers between \verb!-1! and \verb!0!, +where \verb!-1! means trimming the whole colsep, and \verb!0! means no trimming. +The default value is \verb!-0.8!, which makes similar result as \verb!booktabs! package does. + +There is also a \verb!booktabs! environment for you. With this environment, +the default \verb!rowsep=0pt!, but extra vertical space will be added by +\verb!\toprule!, \verb!\midrule!, \verb!\bottomrule! and \verb!\cmidrule! commands. +The sizes of vertical space are determined by \verb!\aboverulesep! and \verb!\belowrulesep! dimensions. + +\begin{demohigh} +\begin{booktabs}{ + colspec = lcccc, + cell{1}{1} = {r=2}{}, cell{1}{2,4} = {c=2}{}, +} +\toprule + Sample & I & & II & \\ +\cmidrule[lr]{2-3} \cmidrule[lr]{4-5} + & A & B & C & D \\ +\midrule + S1 & 5 & 6 & 7 & 8 \\ + S2 & 6 & 7 & 8 & 5 \\ + S3 & 7 & 8 & 5 & 6 \\ +\bottomrule +\end{booktabs} +\end{demohigh} +% S4 & 8 & 5 & 6 & 7 \\ + +You can also use \verb!\specialrule! command. +The second argument sets \verb!belowsep! of previous row, +and the third argument sets \verb!abovesep! of current row, + +\begin{demohigh} +\begin{booktabs}{row{2}={olive9}} +\toprule + Alpha & Beta & Gamma & Delta \\ +\specialrule{0.5pt}{4pt}{6pt} + Epsilon & Zeta & Eta & Theta \\ +\specialrule{0.8pt,blue3}{3pt}{2pt} + Iota & Kappa & Lambda & Mu \\ +\bottomrule +\end{booktabs} +\end{demohigh} + +At last, there is also an \verb!\addlinespace! command. +You can specify the size of vertical space to be added in its optional argument, +and the default size is \verb!0.5em!. +This command adds one half of the space to \verb!belowsep! of previous row, +and the other half to \verb!abovesep! of current row. + +\begin{demohigh} +\begin{booktabs}{row{2}={olive9}} +\toprule + Alpha & Beta & Gamma & Delta \\ +\addlinespace + Epsilon & Zeta & Eta & Theta \\ +\addlinespace[1em] + Iota & Kappa & Lambda & Mu \\ +\bottomrule +\end{booktabs} +\end{demohigh} + \section{Library \texttt{diagbox}} When writing \verb!\UseTblrLibrary{diagbox}! in the preamble of the document, @@ -2102,39 +2256,31 @@ and defines \verb!S! column as \verb!Q! column with \verb!si! key. \begin{demohigh} \begin{tblr}{ hlines, vlines, - colspec={ - S[table-format=3.2] - S[table-format=3.2] - S[table-format=3.2] - } + colspec={S[table-format=3.2]S[table-format=3.2]}, } - {{{Head}}} & {{{Head}}} & {{{Head}}} \\ - 111 & 111 & 111 \\ - 2.1 & 2.2 & 2.3 \\ - 33.11 & 33.22 & 33.33 \\ + {{{Head}}} & {{{Head}}} \\ + 111 & 111 \\ + 2.1 & 2.2 \\ + 33.11 & 33.22 \\ \end{tblr} \end{demohigh} \begin{demohigh} \begin{tblr}{ hlines, vlines, - colspec={ - Q[si={table-format=3.2},c] - Q[si={table-format=3.2},c] - Q[si={table-format=3.2},c] - } + colspec={Q[si={table-format=3.2},c]Q[si={table-format=3.2},c]} } - {{{Head}}} & {{{Head}}} & {{{Head}}} \\ - 111 & 111 & 111 \\ - 2.1 & 2.2 & 2.3 \\ - 33.11 & 33.22 & 33.33 \\ + {{{Head}}} & {{{Head}}} \\ + 111 & 111 \\ + 2.1 & 2.2 \\ + 33.11 & 33.22 \\ \end{tblr} \end{demohigh} -Note that you need to use \underline{triple} pairs of braces to guard non-numeric cells. +Note that you need to use \underline{\color{red3}triple} pairs of braces to guard non-numeric cells. Also you must use \verb!l!, \verb!c! or \verb!r! to set horizontal alignment for non-numeric cells: - +\nopagebreak \begin{demohigh} \begin{tblr}{ hlines, vlines, columns={6em}, @@ -2157,6 +2303,30 @@ Both \verb!S! and \verb!s! columns are supported. In fact, These two columns are \NewColumnType{s}[1][]{Q[si={##1},c,cmd=\TblrUnit]} \end{codehigh} +\section{Library \texttt{varwidth}} + +To build a nice table, \verb!tabularray! need to measure the widths of cells. +By default, it uses \verb!\hbox! to measure the sizes. +This causes an error if a cell contains some vertical material, such as lists or display maths. + +With \verb!\UseTblrLibrary{varwidth}! in the preamble of the document, +\verb!tabularray! loads \verb!varwidth! package, +and adds a new inner specification \verb!measure! for tables. +After setting \verb!measure=vbox!, it will use \verb!\vbox! to measure cell widths. + +\begin{demohigh} +\begin{tblr}{measure=vbox} +\hline + Text Text Text Text Text Text Text + \begin{itemize} + \item List List List List List List + \item List List List List List List List + \end{itemize} + Text Text Text Text Text Text Text \\ +\hline +\end{tblr} +\end{demohigh} + \chapter{The Source Code} %\CodeHigh{lite} diff --git a/Master/texmf-dist/tex/latex/tabularray/tabularray-2021.sty b/Master/texmf-dist/tex/latex/tabularray/tabularray-2021.sty index 90ddaadd342..8e5c2b93694 100644 --- a/Master/texmf-dist/tex/latex/tabularray/tabularray-2021.sty +++ b/Master/texmf-dist/tex/latex/tabularray/tabularray-2021.sty @@ -12,7 +12,7 @@ \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} -\ProvidesExplPackage{tabularray}{2021-05-25}{2021J} +\ProvidesExplPackage{tabularray}{2021-06-05}{2021K} {Typeset tabulars and arrays with LaTeX3} \RequirePackage{xparse} @@ -97,60 +97,78 @@ \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} + %%% -------------------------------------------------------- %% \section{Data Structures Based on Property Lists} %%% -------------------------------------------------------- \int_new:N \g_tblr_level_int % store table nesting level +\cs_new_protected:Npn \__tblr_clear_prop_lists: + { + \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_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 } + \prop_gclear_new:c { g__tblr_hline_ \int_use:N \g_tblr_level_int _prop } + \prop_gclear_new:c { g__tblr_vline_ \int_use:N \g_tblr_level_int _prop } + } + \cs_new_protected:Npn \__tblr_prop_gput:nnn #1 #2 #3 { \prop_gput:cnn - { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } { #3 } + { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } { #3 } } \cs_generate_variant:Nn \__tblr_prop_gput:nnn { nnx, nnV, nxn, nxx, nxV } \cs_new:Npn \__tblr_prop_item:nn #1 #2 { - \prop_item:cn { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } + \prop_item:cn { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } } \cs_generate_variant:Nn \__tblr_prop_item:nn { ne } \cs_new_protected:Npn \__tblr_prop_if_in:nnT #1 { - \prop_if_in:cnT { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } + \prop_if_in:cnT { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } } \cs_new_protected:Npn \__tblr_prop_if_in:nnF #1 { - \prop_if_in:cnF { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } + \prop_if_in:cnF { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } } \cs_new_protected:Npn \__tblr_prop_if_in:nnTF #1 { - \prop_if_in:cnTF { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } + \prop_if_in:cnTF { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } } \prg_generate_conditional_variant:Nnn \__tblr_prop_if_in:nn { nx } { T, F, TF } \cs_new_protected:Npn \__tblr_prop_log:n #1 { - \prop_log:c { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } + \prop_log:c { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } } \cs_new_protected:Npn \__tblr_prop_map_inline:nn #1 #2 { - \prop_map_inline:cn { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } {#2} + \prop_map_inline:cn { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } {#2} } \cs_new_protected:Npn \__tblr_prop_gput_if_larger:nnn #1 #2 #3 { \__tblr_gput_if_larger:cnn - { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } { #3 } + { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } { #3 } } \cs_generate_variant:Nn \__tblr_prop_gput_if_larger:nnn { nnx, nnV, nxn, nxx, nxV } \cs_new_protected:Npn \__tblr_prop_gadd_dimen_value:nnn #1 #2 #3 { \__tblr_gadd_dimen_value:cnn - { g_tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } { #3 } + { g__tblr_#1_ \int_use:N \g_tblr_level_int _prop } { #2 } { #3 } } \cs_generate_variant:Nn \__tblr_prop_gadd_dimen_value:nnn { nnx, nnV, nxn, nxx } @@ -193,27 +211,90 @@ } \cs_generate_variant:Nn \__tblr_gadd_dimen_value:Nnn { cnn } -%% Some counters for row and column numbering -\newcounter{rownum} -\newcounter{colnum} -\newcounter{rowcount} -\newcounter{colcount} +%%% -------------------------------------------------------- +%% \section{Data Structures Based on Token Lists} +%%% -------------------------------------------------------- + +\cs_new_protected:Npn \__tblr_clear_text_lists: + { + \__tblr_clear_one_text_lists:n { text } + \__tblr_clear_one_text_lists:n { hline } + \__tblr_clear_one_text_lists:n { vline } + } + +\cs_new_protected:Npn \__tblr_clear_one_text_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 } + } + } + { \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 + { + \tl_gset:cn + { g__tblr_text_ \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_new:Npn \__tblr_text_item:nn #1 #2 + { + \tl_if_exist:cT { g__tblr_text_ \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 } + } + } +\cs_generate_variant:Nn \__tblr_text_item:nn { ne } + +\cs_new_protected:Npn \__tblr_text_gput_if_larger:nnn #1 #2 #3 + { + \tl_set:Nx \l__tblr_put_if_larger_tl { \__tblr_text_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} } + } +\cs_generate_variant:Nn \__tblr_text_gput_if_larger:nnn { nne, nnV, nen, nee, neV } + +\cs_new_protected:Npn \__tblr_text_log:n #1 + { + \clist_gremove_duplicates:c + { g__tblr_#1_ \int_use:N \g_tblr_level_int _clist } + \tl_log:n { ----------~----------~----------~----------~---------- } + \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} } + } + } + } %%% -------------------------------------------------------- %% \section{Data Structures Based on Integer Arrays} %%% -------------------------------------------------------- -\int_new:N \g__tblr_array_int +\msg_new:nnn { tabularray } { intarray-beyond-bound } + { Position ~ #2 ~ is ~ beyond ~ the ~ bound ~ of ~ intarray ~ #1.} -\cs_new_protected:Npn \__tblr_initial_table_data: +\cs_new_protected:Npn \__tblr_intarray_gset:Nnn #1 #2 #3 { - \int_gincr:N \g__tblr_array_int - \intarray_new:cn { g__tblr_row_ \int_use:N \g__tblr_array_int _intarray } - { \g__tblr_data_row_key_count_int * \c@rowcount } - \cs_set_eq:cc { g__tblr_row_ \int_use:N \g_tblr_level_int _intarray } - { g__tblr_row_ \int_use:N \g__tblr_array_int _intarray } - %\intarray_log:c { g__tblr_row_ \int_use:N \g_tblr_level_int _intarray } + \bool_lazy_or:nnTF + { \int_compare_p:nNn {#2} < {0} } + { \int_compare_p:nNn {#2} > {\intarray_count:N #1} } + { + \bool_if:NT \g__tblr_tracing_intarray_bool + { \msg_warning:nnnn { tabularray } { intarray-beyond-bound } {#1} {#2} } + } + { \intarray_gset:Nnn #1 {#2} {#3} } } +\cs_generate_variant:Nn \__tblr_intarray_gset:Nnn { cnn } %% #1: data name; #2: key name; #3: value type \cs_new_protected:Npn \__tblr_data_new_key:nnn #1 #2 #3 @@ -231,7 +312,6 @@ } \int_new:N \g__tblr_data_row_key_count_int - \__tblr_data_new_key:nnn { row } { height } { dim } \__tblr_data_new_key:nnn { row } { coefficient } { dec } \__tblr_data_new_key:nnn { row } { abovesep } { dim } @@ -242,6 +322,52 @@ \__tblr_data_new_key:nnn { row } { @row-upper } { dim } \__tblr_data_new_key:nnn { row } { @row-lower } { dim } +\int_new:N \g__tblr_data_column_key_count_int +\__tblr_data_new_key:nnn { column } { width } { dim } +\__tblr_data_new_key:nnn { column } { coefficient } { dec } +\__tblr_data_new_key:nnn { column } { leftsep } { dim } +\__tblr_data_new_key:nnn { column } { rightsep } { dim } +\__tblr_data_new_key:nnn { column } { @col-width } { dim } + +\int_new:N \g__tblr_data_cell_key_count_int +\__tblr_data_new_key:nnn { cell } { width } { dim } +\__tblr_data_new_key:nnn { cell } { rowspan } { int } +\__tblr_data_new_key:nnn { cell } { colspan } { int } +\__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 } { omit } { int } +\__tblr_data_new_key:nnn { cell } { @cell-width } { dim } +\__tblr_data_new_key:nnn { cell } { @cell-height } { dim } +\__tblr_data_new_key:nnn { cell } { @cell-depth } { dim } + +\clist_const:Nn \g__tblr_data_clist { row, column, cell } +\tl_const:Nn \g__tblr_data_row_count_tl { \c@rowcount } +\tl_const:Nn \g__tblr_data_column_count_tl { \c@colcount } +\tl_const:Nn \g__tblr_data_cell_count_tl { \c@rowcount * \c@colcount } +\tl_const:Nn \g__tblr_data_row_index_number_tl {1} +\tl_const:Nn \g__tblr_data_column_index_number_tl {1} +\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: + { + \clist_map_function:NN \g__tblr_data_clist \__tblr_initial_one_data:n + } + +\cs_new_protected:Npn \__tblr_initial_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 } + { + \int_use:c { g__tblr_data_#1_key_count_int } + * \tl_use:c { g__tblr_data_#1_count_tl } + } + \cs_set_eq:cc { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } + { g__tblr_#1_ \int_use:N \g__tblr_array_int _intarray } + %\intarray_log:c { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } + } + %% #1: data name; #2: data index; #3: key name \cs_new:Npn \__tblr_data_key_to_int:nnn #1 #2 #3 { @@ -249,8 +375,17 @@ + \tl_use:c { g__tblr_data_#1_key_number_#3_tl } } +%% #1: data name; #2: data index 1; #3: data index 2; #4: key name +\cs_new:Npn \__tblr_data_key_to_int:nnnn #1 #2 #3 #4 + { + ( #2 - 1 ) * \c@colcount * \int_use:c { g__tblr_data_#1_key_count_int } + + ( #3 - 1 ) * \int_use:c { g__tblr_data_#1_key_count_int } + + \tl_use:c { g__tblr_data_#1_key_number_#4_tl } + } + \int_new:N \l__tblr_key_count_int \int_new:N \l__tblr_key_quotient_int +\int_new:N \l__tblr_key_quotient_two_int \int_new:N \l__tblr_key_remainder_int %% #1: data name; #2: array position; @@ -275,11 +410,50 @@ { g__tblr_data_#1_key_name_ \int_use:N \l__tblr_key_remainder_int _tl } } +%% #1: data name; #2: array position; +%% #3: returning tl with index 1; #4: returning tl with index 2; +%% #5: returning tl with key name +\cs_new:Npn \__tblr_data_int_to_key:nnNNN #1 #2 #3 #4 #5 + { + \int_set_eq:Nc \l__tblr_key_count_int { g__tblr_data_#1_key_count_int } + \int_set:Nn \l__tblr_key_quotient_int + { + \int_div_truncate:nn + { #2 + \l__tblr_key_count_int - 1 } { \l__tblr_key_count_int } + } + \int_set:Nn \l__tblr_key_remainder_int + { + #2 + \l__tblr_key_count_int + - \l__tblr_key_quotient_int * \l__tblr_key_count_int + } + \int_compare:nNnT { \l__tblr_key_remainder_int } = { 0 } + { \int_set_eq:NN \l__tblr_key_remainder_int \l__tblr_key_count_int } + \tl_set_eq:Nc #5 + { g__tblr_data_#1_key_name_ \int_use:N \l__tblr_key_remainder_int _tl } + \int_set:Nn \l__tblr_key_quotient_two_int + { + \int_div_truncate:nn + { \l__tblr_key_quotient_int + \c@colcount - 1 } { \c@colcount } + } + \int_set:Nn \l__tblr_key_remainder_int + { + \l__tblr_key_quotient_int + \c@colcount + - \l__tblr_key_quotient_two_int * \c@colcount + } + \int_compare:nNnT { \l__tblr_key_remainder_int } = { 0 } + { \int_set_eq:NN \l__tblr_key_remainder_int \c@colcount } + \tl_set:Nx #4 { \int_use:N \l__tblr_key_remainder_int } + \tl_set:Nx #3 { \int_use:N \l__tblr_key_quotient_two_int } + } + +\tl_new:N \g__tblr_data_int_from_value_tl + %% #1: data name; #2: key name; #3: value -\cs_new:Npn \__tblr_data_value_to_int:nnn #1 #2 #3 +%% The result will be stored in \g__tblr_data_int_from_value_tl +\cs_new_protected:Npn \__tblr_data_int_from_value:nnn #1 #2 #3 { \cs:w - __tblr_data_ \tl_use:c { g__tblr_data_#1_key_type_#2_tl } _to_int:n + __tblr_data_int_from_ \tl_use:c { g__tblr_data_#1_key_type_#2_tl } :n \cs_end: {#3} } @@ -294,9 +468,19 @@ } \cs_generate_variant:Nn \__tblr_data_int_to_value:nnn { nne, nVe } -\cs_new:Npn \__tblr_data_dim_to_int:n #1 +\cs_new_protected:Npn \__tblr_data_int_from_int:n #1 { - \dim_to_decimal_in_sp:n {#1} + \tl_gset:Nn \g__tblr_data_int_from_value_tl {#1} + } + +\cs_new:Npn \__tblr_data_int_to_int:n #1 + { + #1 + } + +\cs_new_protected:Npn \__tblr_data_int_from_dim:n #1 + { + \tl_gset:Nx \g__tblr_data_int_from_value_tl { \dim_to_decimal_in_sp:n {#1} } } %% Return a dimension in pt so that it's easier to understand in tracing messages @@ -307,9 +491,10 @@ \dim_to_decimal:n { #1 sp } pt } -\cs_new:Npn \__tblr_data_dec_to_int:n #1 +\cs_new_protected:Npn \__tblr_data_int_from_dec:n #1 { - \dim_to_decimal_in_sp:n {#1 pt} + \tl_gset:Nx \g__tblr_data_int_from_value_tl + { \dim_to_decimal_in_sp:n {#1 pt} } } \cs_new:Npn \__tblr_data_int_to_dec:n #1 @@ -317,17 +502,57 @@ \dim_to_decimal:n {#1 sp} } +\int_new:N \g__tblr_data_str_value_count_int +\tl_set:cn { g__tblr_data_0_to_str_tl } { } + +\cs_new_protected:Npn \__tblr_data_int_from_str:n #1 + { + \tl_if_exist:cTF { g__tblr_data_#1_to_int_tl } + { + \tl_gset_eq:Nc \g__tblr_data_int_from_value_tl + { g__tblr_data_#1_to_int_tl } + } + { + \int_gincr:N \g__tblr_data_str_value_count_int + \tl_gset:cx { g__tblr_data_#1_to_int_tl } + { \int_use:N \g__tblr_data_str_value_count_int } + \tl_gset:cx + { g__tblr_data_ \int_use:N \g__tblr_data_str_value_count_int _to_str_tl } + { #1 } + \tl_gset:Nx \g__tblr_data_int_from_value_tl + { \int_use:N \g__tblr_data_str_value_count_int } + } + } + +\cs_new:Npn \__tblr_data_int_to_str:n #1 + { + \tl_use:c { g__tblr_data_#1_to_str_tl } + } + %% #1: data name; #2: data index; #3: key; #4: value \cs_new_protected:Npn \__tblr_data_gput:nnnn #1 #2 #3 #4 { - \intarray_gset:cnn + \__tblr_data_int_from_value:nnn {#1} {#3} {#4} + \__tblr_intarray_gset:cnn { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } { \__tblr_data_key_to_int:nnn {#1} {#2} {#3} } - { \__tblr_data_value_to_int:nnn {#1} {#3} {#4} } + { \g__tblr_data_int_from_value_tl } } \cs_generate_variant:Nn \__tblr_data_gput:nnnn { nnne, nnnV, nenn, nene, nenV, nVnn } +%% #1: data name; #2: data index 1; #3: data index 2; #4: key; #5: value +\cs_new_protected:Npn \__tblr_data_gput:nnnnn #1 #2 #3 #4 #5 + { + \__tblr_data_int_from_value:nnn {#1} {#4} {#5} + \__tblr_intarray_gset:cnn + { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } + { \__tblr_data_key_to_int:nnnn {#1} {#2} {#3} {#4} } + { \g__tblr_data_int_from_value_tl } + } +\cs_generate_variant:Nn \__tblr_data_gput:nnnnn + { nnnne, nnnnV, neenn, neene, neenV, neeen, nVVnn } + %% #1: data name; #2: data index; #3: key \cs_new:Npn \__tblr_data_item:nnn #1 #2 #3 { @@ -339,13 +564,32 @@ } \cs_generate_variant:Nn \__tblr_data_item:nnn { nen } +%% #1: data name; #2: data index 1; #3: data index 2; #4: key +\cs_new:Npn \__tblr_data_item:nnnn #1 #2 #3 #4 + { + \__tblr_data_int_to_value:nne {#1} {#4} + { + \intarray_item:cn { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } + { \__tblr_data_key_to_int:nnnn {#1} {#2} {#3} {#4} } + } + } +\cs_generate_variant:Nn \__tblr_data_item:nnnn { neen } + \tl_new:N \l__tblr_data_key_tl \tl_new:N \l__tblr_data_index_tl +\tl_new:N \l__tblr_data_index_two_tl \cs_new_protected:Npn \__tblr_data_log:n #1 { + \use:c { __tblr_data_log_ \use:c { g__tblr_data_#1_index_number_tl } :n } {#1} + \__tblr_prop_log:n {#1} + } + +\cs_new_protected:cpn { __tblr_data_log_1:n } #1 + { %\intarray_log:c { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } \tl_set:Nx \l_tmpa_tl { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } + \tl_log:n { ----------~----------~----------~----------~---------- } \int_step_inline:nn { \intarray_count:c { \l_tmpa_tl } } { @@ -353,52 +597,80 @@ \l__tblr_data_index_tl \l__tblr_data_key_tl \tl_log:x { + \space { #1 [\l__tblr_data_index_tl] / \l__tblr_data_key_tl } - \space = \space + ~\space => ~\space + { + \__tblr_data_int_to_value:nVe {#1} \l__tblr_data_key_tl + { \intarray_item:cn { \l_tmpa_tl } {##1} } + } + } + } + } + +\cs_new_protected:cpn { __tblr_data_log_2:n } #1 + { + %\intarray_log:c { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } + \tl_set:Nx \l_tmpa_tl { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } + \tl_log:n { ----------~----------~----------~----------~---------- } + \int_step_inline:nn + { \intarray_count:c { \l_tmpa_tl } } + { + \__tblr_data_int_to_key:nnNNN {#1} {##1} + \l__tblr_data_index_tl \l__tblr_data_index_two_tl \l__tblr_data_key_tl + \tl_log:x + { + \space + { + #1 [\l__tblr_data_index_tl][\l__tblr_data_index_two_tl] + / \l__tblr_data_key_tl + } + ~\space => ~\space { \__tblr_data_int_to_value:nVe {#1} \l__tblr_data_key_tl { \intarray_item:cn { \l_tmpa_tl } {##1} } } } } - \__tblr_prop_log:n {#1} } %% #1: data name; #2: row index; #3: key; #4: value \cs_new_protected:Npn \__tblr_data_gput_if_larger:nnnn #1 #2 #3 #4 { + \__tblr_data_int_from_value:nnn {#1} {#3} {#4} \__tblr_array_gput_if_larger:cnn { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } { \__tblr_data_key_to_int:nnn {#1} {#2} {#3} } - { \__tblr_data_value_to_int:nnn {#1} {#3} {#4} } + { \g__tblr_data_int_from_value_tl } } \cs_generate_variant:Nn \__tblr_data_gput_if_larger:nnnn { nnne, nnnV, nene, nenV } \cs_new_protected:Npn \__tblr_array_gput_if_larger:Nnn #1 #2 #3 { \int_compare:nNnT {#3} > { \intarray_item:Nn #1 {#2} } - { \intarray_gset:Nnn #1 {#2} {#3} } + { \__tblr_intarray_gset:Nnn #1 {#2} {#3} } } \cs_generate_variant:Nn \__tblr_array_gput_if_larger:Nnn { cnn } %% #1: data name; #2: data index; #3: key; #4: value \cs_new_protected:Npn \__tblr_data_gadd_dimen_value:nnnn #1 #2 #3 #4 { + \__tblr_data_int_from_value:nnn {#1} {#3} {#4} \__tblr_array_gadd_value:cnn { g__tblr_#1_ \int_use:N \g_tblr_level_int _intarray } { \__tblr_data_key_to_int:nnn {#1} {#2} {#3} } - { \__tblr_data_value_to_int:nnn {#1} {#3} {#4} } + { \g__tblr_data_int_from_value_tl } } \cs_generate_variant:Nn \__tblr_data_gadd_dimen_value:nnnn { nnne, nnnV, nene } \cs_new_protected:Npn \__tblr_array_gadd_value:Nnn #1 #2 #3 { - \intarray_gset:Nnn #1 {#2} { \intarray_item:Nn #1 {#2} + #3 } + \__tblr_intarray_gset:Nnn #1 {#2} { \intarray_item:Nn #1 {#2} + #3 } } \cs_generate_variant:Nn \__tblr_array_gadd_value:Nnn { cnn } \bool_new:N \g__tblr_use_intarray_bool -%\bool_set_true:N \g__tblr_use_intarray_bool +\bool_set_true:N \g__tblr_use_intarray_bool \AtBeginDocument { @@ -408,10 +680,18 @@ { \__tblr_prop_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} + } \cs_set:Npn \__tblr_data_item:nnn #1 #2 #3 { \__tblr_prop_item:nn {#1} { [#2] / #3 } } + \cs_set:Npn \__tblr_data_item:nnnn #1 #2 #3 #4 + { + \__tblr_prop_item:nn {#1} { [#2][#3] / #4 } + } \cs_set_protected:Npn \__tblr_data_log:n #1 { \__tblr_prop_log:n {#1} @@ -420,10 +700,18 @@ { \__tblr_prop_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} + } \cs_set_protected:Npn \__tblr_data_gadd_dimen_value:nnnn #1 #2 #3 #4 { \__tblr_prop_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} + } } } @@ -490,7 +778,6 @@ \regex_const:Nn \c__tblr_split_selector_name_regex { ^ ( [A-Za-z] {2,} ) ( . * ) } \seq_new:N \l__tblr_childs_split_seq \seq_new:N \l__tblr_childs_regex_seq -\tl_new:N \l__tblr_childs_end_tl \tl_new:N \l__tblr_childs_selector_tl %% #1, child specifications; #2, total number. @@ -524,15 +811,16 @@ { \seq_set_split:Nnn \l__tblr_childs_split_seq {,} {#1} \seq_map_inline:Nn \l__tblr_childs_split_seq - { \__tblr_get_childs_normal_aux:w ##1 - s \scan_stop } + { + \tl_if_in:nnTF {##1} {-} + { \__tblr_get_childs_normal_aux:w ##1 \scan_stop } + { \__tblr_get_childs_normal_aux:w ##1 - ##1 \scan_stop } + } } -\cs_new_protected_nopar:Npn \__tblr_get_childs_normal_aux:w #1 - #2 #3 \scan_stop +\cs_new_protected_nopar:Npn \__tblr_get_childs_normal_aux:w #1 - #2 \scan_stop { - \tl_if_eq:nnTF {#2} {s} - { \tl_set:Nn \l__tblr_childs_end_tl {#1} } - { \tl_set:Nn \l__tblr_childs_end_tl {#2} } - \int_step_inline:nnn {#1} { \l__tblr_childs_end_tl } + \int_step_inline:nnn {#1} {#2} { \clist_put_right:Nn \l_tblr_childs_clist {##1} } } @@ -780,11 +1068,12 @@ { \tl_clear:N \l__tblr_hline_num_tl \tl_set:Nx \l__tblr_hline_count_tl - { \__tblr_prop_item:ne { hline } { [\int_use:N \c@rownum] / @hline-count } } - \tl_if_empty:NTF \l__tblr_hline_count_tl + { \__tblr_text_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_prop_gput:nxx { hline } + \__tblr_text_gput:nen { hline } { [\int_use:N \c@rownum] / @hline-count } { 1 } } { @@ -806,7 +1095,7 @@ { \tl_set:Nx \l__tblr_hline_count_tl { \int_eval:n { \l__tblr_hline_count_tl + 1 } } - \__tblr_prop_gput:nxx { hline } + \__tblr_text_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 } @@ -842,18 +1131,18 @@ \__tblr_get_childs:nx {#1} { \int_use:N \c@colcount } \clist_map_inline:Nn \l_tblr_childs_clist { - \__tblr_prop_gput:nxx { hline } + \__tblr_text_gput:nee { hline } { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / @dash } { \l__tblr_hline_dash_tl } \tl_if_empty:NF \l__tblr_hline_wd_tl { - \__tblr_prop_gput:nxx { hline } + \__tblr_text_gput:nee { hline } { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / wd } { \l__tblr_hline_wd_tl } } \tl_if_empty:NF \l__tblr_hline_fg_tl { - \__tblr_prop_gput:nxx { hline } + \__tblr_text_gput:nee { hline } { [\int_use:N \c@rownum][##1](\l__tblr_hline_num_tl) / fg } { \l__tblr_hline_fg_tl } } @@ -978,11 +1267,12 @@ { \tl_clear:N \l__tblr_vline_num_tl \tl_set:Nx \l__tblr_vline_count_tl - { \__tblr_prop_item:ne { vline } { [\int_use:N \c@colnum] / @vline-count } } - \tl_if_empty:NTF \l__tblr_vline_count_tl + { \__tblr_text_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_prop_gput:nxx { vline } + \__tblr_text_gput:nen { vline } { [\int_use:N \c@colnum] / @vline-count } { 1 } } { @@ -1004,7 +1294,7 @@ { \tl_set:Nx \l__tblr_vline_count_tl { \int_eval:n { \l__tblr_vline_count_tl + 1 } } - \__tblr_prop_gput:nxx { vline } + \__tblr_text_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 } @@ -1039,18 +1329,18 @@ \__tblr_get_childs:nx {#1} { \int_use:N \c@rowcount } \clist_map_inline:Nn \l_tblr_childs_clist { - \__tblr_prop_gput:nxx { vline } + \__tblr_text_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_prop_gput:nxx { vline } + \__tblr_text_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_prop_gput:nxx { vline } + \__tblr_text_gput:nee { vline } { [##1][\int_use:N \c@colnum](\l__tblr_vline_num_tl) / fg } { \l__tblr_vline_fg_tl } } @@ -1150,42 +1440,77 @@ \keys_define:nn { tblr-cell-spec } { - l .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / halign} {l}, - c .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / halign} {c}, - r .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / halign} {r}, - t .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / valign} {t}, - p .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / valign} {t}, - m .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / valign} {m}, - b .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / valign} {b}, - h .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / valign} {h}, - f .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / valign} {f}, - wd .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / width} {#1}, - bg .code:n = \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / background} {#1}, + 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 }, unknown .code:n = \__tblr_cell_unknown_key:V \l_keys_key_str, } +\tl_new:N \l__tblr_cell_text_tl + +\cs_new_protected:Npn \__tblr_cell_preto_text:n #1 + { + \__tblr_cell_preto_text:een + { \int_use:N \c@rownum } { \int_use:N \c@colnum } {#1} + } + +\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_put_left:Nn \l__tblr_cell_text_tl {#3} + \__tblr_text_gput:nnV { text } { [#1][#2] } \l__tblr_cell_text_tl + } +\cs_generate_variant:Nn \__tblr_cell_preto_text:nnn { nen, enn, een } + +\cs_new_protected:Npn \__tblr_cell_appto_text:n #1 + { + \__tblr_cell_appto_text:een + { \int_use:N \c@rownum } { \int_use:N \c@colnum } {#1} + } + +\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_put_right:Nn \l__tblr_cell_text_tl {#3} + \__tblr_text_gput:neV { text } { [#1][#2] } \l__tblr_cell_text_tl + } +\cs_generate_variant:Nn \__tblr_cell_appto_text:nnn { nen, enn, een } + \cs_new_protected:Npn \__tblr_cell_unknown_key:n #1 { \regex_match:NnTF \c__tblr_is_color_key_regex {#1} { - \__tblr_prop_gput:nxx {cell} - {[\int_use:N \c@rownum][\int_use:N \c@colnum] / background} {#1} + \__tblr_data_gput:neene { cell } + { \int_use:N \c@rownum } { \int_use:N \c@colnum } { background } {#1} } { \tl_set_rescan:Nnn \l__tblr_v_tl {} {#1} - \__tblr_prop_gput:nxx {cell} - { [\int_use:N \c@rownum][\int_use:N \c@colnum] / width } + \__tblr_data_gput:neene { cell } + { \int_use:N \c@rownum } { \int_use:N \c@colnum } { width } { \dim_eval:n { \l__tblr_v_tl } } } } @@ -1196,14 +1521,14 @@ \int_compare:nNnT { #1 } > { 1 } { \__tblr_prop_gput:nnn {table} {rowspan} {true} - \__tblr_prop_gput:nxn {cell} - { [\int_use:N \c@rownum][\int_use:N \c@colnum] / rowspan } { #1 } + \__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:nxn {cell} - { [\int_use:N \c@rownum][\int_use:N \c@colnum] / colspan } { #2 } + \__tblr_data_gput:neenn { cell } + { \int_use:N \c@rownum } { \int_use:N \c@colnum } { colspan } {#2} } \int_step_variable:nnNn { \int_use:N \c@rownum } { \int_eval:n { \c@rownum + #1 - 1 } } \l__tblr_i_tl @@ -1216,17 +1541,17 @@ { \int_compare_p:nNn { \l__tblr_i_tl } = { \c@rownum } } { \int_compare_p:nNn { \l__tblr_j_tl } = { \c@colnum } } { - \__tblr_prop_gput:nxx {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / omit } {true} + \__tblr_data_gput:neenn { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { omit } {1} } \int_compare:nNnF { \l__tblr_i_tl } = { \c@rownum } { - \__tblr_prop_gput:nxx {hline} + \__tblr_text_gput:nen { hline } { [\l__tblr_i_tl][\l__tblr_j_tl] / omit } {true} } \int_compare:nNnF { \l__tblr_j_tl } = { \c@colnum } { - \__tblr_prop_gput:nxx {vline} + \__tblr_text_gput:nee { vline } { [\l__tblr_i_tl][\l__tblr_j_tl] / omit } {true} } } @@ -1373,19 +1698,21 @@ { \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}, - wd .code:n = \__tblr_prop_gput:nxx { column } - { [\int_use:N \c@colnum] / width } { \dim_eval:n {#1} }, - co .code:n = \__tblr_prop_gput:nxx { column } - { [\int_use:N \c@colnum] / coefficient } {#1}, - leftsep .code:n = \__tblr_prop_gput:nxx { column } - { [\int_use:N \c@colnum] / leftsep } { \dim_eval:n {#1} }, - rightsep .code:n = \__tblr_prop_gput:nxx { column } - { [\int_use:N \c@colnum] / rightsep } { \dim_eval:n {#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_prop_gadd_dimen_value:nxx { column } - { [\int_use:N \c@colnum] / leftsep } { \dim_eval:n {#1} }, - rightsep+ .code:n = \__tblr_prop_gadd_dimen_value:nxx { column } - { [\int_use:N \c@colnum] / rightsep } { \dim_eval:n {#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, } @@ -1395,7 +1722,23 @@ { \int_step_inline:nn { \c@rowcount } { - \__tblr_prop_gput:nxn {cell} { [##1][#1] / #2 } {#3} + \__tblr_data_gput:neenn { cell } {##1} {#1} {#2} {#3} + } + } + +\cs_new_protected:Npn \__tblr_preto_text_for_every_column_cell:n #1 + { + \int_step_inline:nn { \c@rowcount } + { + \__tblr_cell_preto_text:nen {##1} { \int_use:N \c@colnum } {#1} + } + } + +\cs_new_protected:Npn \__tblr_appto_text_for_every_column_cell:n #1 + { + \int_step_inline:nn { \c@rowcount } + { + \__tblr_cell_appto_text:nen {##1} { \int_use:N \c@colnum } {#1} } } @@ -1405,8 +1748,8 @@ { \regex_match:NnTF \c__tblr_is_number_key_regex {#1} { - \__tblr_prop_gput:nxx { column } - { [\int_use:N \c@colnum] / coefficient } {#1} + \__tblr_data_gput:nene { column } + { \int_use:N \c@colnum } { coefficient } {#1} } { \regex_match:NnTF \c__tblr_is_color_key_regex {#1} @@ -1416,8 +1759,8 @@ } { \tl_set_rescan:Nnn \l__tblr_v_tl {} {#1} - \__tblr_prop_gput:nxx { column } - { [\int_use:N \c@colnum] / width } { \dim_eval:n { \l__tblr_v_tl } } + \__tblr_data_gput:nene { column } + { \int_use:N \c@colnum } { width } { \dim_eval:n { \l__tblr_v_tl } } } } } @@ -1507,6 +1850,8 @@ { \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 } @@ -1531,7 +1876,23 @@ { \int_step_inline:nn { \c@colcount } { - \__tblr_prop_gput:nxn {cell} { [#1][##1] / #2 } {#3} + \__tblr_data_gput:neenn { cell } {#1} {##1} {#2} {#3} + } + } + +\cs_new_protected:Npn \__tblr_preto_text_for_every_row_cell:n #1 + { + \int_step_inline:nn { \c@colcount } + { + \__tblr_cell_preto_text:enn { \int_use:N \c@rownum } {##1} {#1} + } + } + +\cs_new_protected:Npn \__tblr_appto_text_for_every_row_cell:n #1 + { + \int_step_inline:nn { \c@colcount } + { + \__tblr_cell_appto_text:enn { \int_use:N \c@rownum } {##1} {#1} } } @@ -1614,26 +1975,16 @@ \exp_args:Nc \NewDocumentCommand { tblr_primitive_column_type_ > } { O{} m } { - \tl_if_blank:nF { #1 } + \tl_if_blank:nF {#1} { - \__tblr_prop_gput:nxx + \__tblr_data_gput:nene { column } - { [\int_use:N \c@colnum] / leftsep} - { \dim_eval:n { #1 } } + { \int_use:N \c@colnum } { leftsep } + { \dim_eval:n {#1} } } - \tl_if_blank:nF { #2 } + \tl_if_blank:nF {#2} { - \int_step_variable:nNn { \c@rowcount } \l__tblr_i_tl - { - \tl_set:Nx \l_tmpa_tl - { - \__tblr_prop_item:ne {text} - { [\l__tblr_i_tl][\int_use:N \c@colnum] } - } - \tl_put_left:Nn \l_tmpa_tl { #2 } - \__tblr_prop_gput:nxV {text} - { [\l__tblr_i_tl][\int_use:N \c@colnum] } \l_tmpa_tl - } + \__tblr_preto_text_for_every_column_cell:n {#2} } \__tblr_execute_colrow_spec_next:N } @@ -1645,24 +1996,14 @@ \exp_args:Nc \NewDocumentCommand { tblr_primitive_row_type_ > } { O{} m } { - \tl_if_blank:nF { #1 } + \tl_if_blank:nF {#1} { \__tblr_data_gput:nene { row } { \int_use:N \c@rownum } { abovesep } { \dim_eval:n { #1 } } } - \tl_if_blank:nF { #2 } + \tl_if_blank:nF {#2} { - \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl - { - \tl_set:Nx \l_tmpa_tl - { - \__tblr_prop_item:ne {text} - { [\int_use:N \c@rownum][\l__tblr_j_tl] } - } - \tl_put_left:Nn \l_tmpa_tl { #2 } - \__tblr_prop_gput:nxV {text} - { [\int_use:N \c@rownum][\l__tblr_j_tl] } \l_tmpa_tl - } + \__tblr_preto_text_for_every_row_cell:n {#2} } \__tblr_execute_colrow_spec_next:N } @@ -1674,26 +2015,17 @@ \exp_args:Nc \NewDocumentCommand { tblr_primitive_column_type_ < } { O{} m } { - \tl_if_blank:nF { #1 } + \tl_if_blank:nF {#1} { - \__tblr_prop_gput:nxx - { column } - { [\int_eval:n {\c@colnum - 1}] / rightsep } - { \dim_eval:n { #1 } } + \__tblr_data_gput:nene { column } + { \int_eval:n {\c@colnum - 1} } { rightsep } { \dim_eval:n {#1} } } - \tl_if_blank:nF { #2 } + \tl_if_blank:nF {#2} { - \int_step_variable:nNn { \c@rowcount } \l__tblr_i_tl - { - \tl_set:Nx \l_tmpa_tl - { - \__tblr_prop_item:ne {text} - { [\l__tblr_i_tl][\int_eval:n {\c@colnum - 1}] } - } - \tl_put_right:Nn \l_tmpa_tl { #2 } - \__tblr_prop_gput:nxV {text} - { [\l__tblr_i_tl][\int_eval:n {\c@colnum - 1}] } \l_tmpa_tl - } + \group_begin: + \int_decr:N \c@colnum + \__tblr_appto_text_for_every_column_cell:n {#2} + \group_end: } \__tblr_execute_colrow_spec_next:N } @@ -1705,24 +2037,17 @@ \exp_args:Nc \NewDocumentCommand { tblr_primitive_row_type_ < } { O{} m } { - \tl_if_blank:nF { #1 } + \tl_if_blank:nF {#1} { \__tblr_data_gput:nene { row } { \int_eval:n {\c@rownum - 1} } { belowsep } { \dim_eval:n {#1} } } - \tl_if_blank:nF { #2 } + \tl_if_blank:nF {#2} { - \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl - { - \tl_set:Nx \l_tmpa_tl - { - \__tblr_prop_item:ne {text} - { [\int_eval:n {\c@rownum - 1}][\l__tblr_j_tl] } - } - \tl_put_right:Nn \l_tmpa_tl { #2 } - \__tblr_prop_gput:nxV {text} - { [\int_eval:n {\c@rownum - 1}][\l__tblr_j_tl] } \l_tmpa_tl - } + \group_begin: + \int_decr:N \c@rownum + \__tblr_appto_text_for_every_row_cell:n {#2} + \group_end: } \__tblr_execute_colrow_spec_next:N } @@ -1902,6 +2227,7 @@ \mode_leave_vertical: \int_gincr:N \g_tblr_level_int \__tblr_clear_prop_lists: + \__tblr_clear_text_lists: \__tblr_enable_table_commands: \__tblr_split_table:n { #3 } \LogTblrTracing { command } @@ -1916,18 +2242,6 @@ \int_gdecr:N \g_tblr_level_int } -\cs_new_protected:Npn \__tblr_clear_prop_lists: - { - \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_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 } - \prop_gclear_new:c { g_tblr_hline_ \int_use:N \g_tblr_level_int _prop } - \prop_gclear_new:c { g_tblr_vline_ \int_use:N \g_tblr_level_int _prop } - } - %% 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 @@ -2034,7 +2348,7 @@ \__tblr_remove_braces:N \l_tmpa_tl \int_incr:N \c@colnum \__tblr_extract_table_commands:N \l_tmpa_tl - \__tblr_prop_gput:nxV {text} { [#1][\int_use:N \c@colnum] } \l_tmpa_tl + \__tblr_text_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 @@ -2059,7 +2373,7 @@ \int_step_inline:nn { \l__multicolumn_cell_number_int - 1 } { \int_incr:N \c@colnum - \__tblr_prop_gput:nxn {text} + \__tblr_text_gput:nen { text } { [\int_use:N \c@rownum][\int_use:N \c@colnum] } { } } } @@ -2175,6 +2489,7 @@ \prop_gset_from_keyval:Nn \g__tblr_default_tblr_table_prop { stretch = 1, + rulesep = 2pt, } \prop_gset_from_keyval:Nn \g__tblr_default_tblr_rows_prop @@ -2192,6 +2507,8 @@ { leftsep = 6pt, rightsep = 6pt, + width = -1pt, % column width unset + coefficient = 0, % column coefficient unset @col-width = 0pt, } @@ -2199,16 +2516,20 @@ { halign = l, valign = t, + width = -1pt, % cell width unset + rowspan = 1, + colspan = 1, + omit = 0, } \prop_gset_from_keyval:Nn \g__tblr_default_tblr_hlines_prop { - rulesep = 2pt, + @hline-count = 0, } \prop_gset_from_keyval:Nn \g__tblr_default_tblr_vlines_prop { - rulesep = 2pt, + @vline-count = 0, } \cs_new_protected:Npn \__tblr_initial_table_spec: @@ -2225,37 +2546,37 @@ } \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _hlines_prop } { - \__tblr_prop_gput:nxn { hline } { [\l__tblr_i_tl] / ##1 } {##2} + \__tblr_text_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 } { - \__tblr_prop_gput:nxn { cell } - { [\l__tblr_i_tl][\l__tblr_j_tl] / ##1 } {##2} + \__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 } { - \__tblr_prop_gput:nxn { hline } + \__tblr_text_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 } { - \__tblr_prop_gput:nxn { column } { [\l__tblr_j_tl] / ##1 } {##2} + \__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 } { - \__tblr_prop_gput:nxn { vline } { [\l__tblr_j_tl] / ##1 } {##2} + \__tblr_text_gput:nen { vline } { [\l__tblr_j_tl] / ##1 } {##2} } } \prop_map_inline:cn { g__tblr_default_ \l__tblr_env_name_tl _vlines_prop } { - \__tblr_prop_gput:nxn { vline } + \__tblr_text_gput:nen { vline } { [\int_eval:n { \c@colcount + 1}] / ##1 } {##2} } \keys_set:nv { tblr } { l__tblr_default_ \l__tblr_env_name_tl _tl } @@ -2279,7 +2600,7 @@ { long, colspec, rowspec, width, hspan, stretch, column, row, cell, vline, hline, columns, rows, cells, vlines, hlines, - leftsep, rightsep, colsep, abovesep, belowsep, rowsep, + leftsep, rightsep, colsep, abovesep, belowsep, rowsep, rulesep, } \bool_new:N \l__tblr_long_table_bool @@ -2303,6 +2624,7 @@ abovesep .code:n = \tblr_set_every_row:nn { } { abovesep = #1 }, 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}, unknown .code:n = \__tblr_table_special_key:Vn \l_keys_key_str {#1}, } @@ -2403,11 +2725,11 @@ { \dim_zero:N \l__tblr_w_dim \tl_set:Nx \l__tblr_n_tl - { \__tblr_prop_item:ne { vline } { [#2] / @vline-count } } - \tl_if_empty:NF \l__tblr_n_tl + { \__tblr_text_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 { vline } { [#2] / rulesep } } + { \__tblr_prop_item:ne { table } { rulesep } } \int_step_inline:nn { \l__tblr_n_tl } { \vbox_set_to_ht:Nnn \l__tblr_b_box {1pt} @@ -2416,14 +2738,14 @@ {#1} {#2} {##1} {1pt} {1pt} } \tl_set:Nx \l__tblr_w_tl { \dim_eval:n { \box_wd:N \l__tblr_b_box } } - \__tblr_prop_gput_if_larger:nxx { vline } + \__tblr_text_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_prop_gput_if_larger:nxx { vline } + \__tblr_text_gput_if_larger:nee { vline } { [#2]/ @vline-width } { \dim_use:N \l__tblr_w_dim } } @@ -2434,10 +2756,10 @@ { \group_begin: \tl_set:Nx \l__tblr_w_tl - { \__tblr_prop_item:ne { vline } { [#1][#2](#3) / wd } } + { \__tblr_text_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_prop_item:ne { vline } { [#1][#2](#3) / @dash } } + { \__tblr_text_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 @@ -2461,11 +2783,11 @@ { \dim_zero:N \l__tblr_h_dim \tl_set:Nx \l__tblr_n_tl - { \__tblr_prop_item:ne { hline } { [#1] / @hline-count } } - \tl_if_empty:NF \l__tblr_n_tl + { \__tblr_text_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 { hline } { [#1] / rulesep } } + { \__tblr_prop_item:ne { table } { rulesep } } \int_step_inline:nn { \l__tblr_n_tl } { \hbox_set_to_wd:Nnn \l__tblr_b_box {1pt} @@ -2475,14 +2797,14 @@ \dim_eval:n { \box_ht:N \l__tblr_b_box + \box_dp:N \l__tblr_b_box } } - \__tblr_prop_gput_if_larger:nxx { hline } + \__tblr_text_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_prop_gput_if_larger:nxx { hline } + \__tblr_text_gput_if_larger:nee { hline } { [#1] / @hline-height } { \dim_use:N \l__tblr_h_dim } } @@ -2492,10 +2814,10 @@ { \group_begin: \tl_set:Nx \l__tblr_w_tl - { \__tblr_prop_item:ne { hline } { [#1][#2](#3) / wd } } + { \__tblr_text_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_prop_item:ne { hline } { [#1][#2](#3) / @dash } } + { \__tblr_text_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 @@ -2527,9 +2849,9 @@ { \group_begin: \tl_gset:Nx \g__tblr_cell_halign_tl - { \__tblr_prop_item:ne { cell } { [#1][#2] / halign } } + { \__tblr_data_item:neen { cell } {#1} {#2} { halign } } \tl_set:Nx \l__tblr_v_tl - { \__tblr_prop_item:ne { cell } { [#1][#2] / valign } } + { \__tblr_data_item:neen { cell } {#1} {#2} { valign } } \tl_case:NnF \l__tblr_v_tl { \c__tblr_valign_t_tl @@ -2607,7 +2929,7 @@ %% #1: row number, #2: column number \cs_new_protected:Npn \__tblr_get_cell_text:nn #1 #2 { - \__tblr_prop_if_in:nxTF {cell} { [#1][#2] / omit } + \int_compare:nNnTF { \__tblr_data_item:neen { cell } {#1} {#2} { omit } } > {0} { \dim_gzero:N \g__tblr_cell_wd_dim \dim_gzero:N \g__tblr_cell_ht_dim @@ -2623,18 +2945,19 @@ \cs_new_protected:Npn \__tblr_get_cell_text_real:nn #1 #2 { \group_begin: - \tl_set:Nx \l__tblr_c_tl { \__tblr_prop_item:ne {text} {[#1][#2]} } + \tl_set:Nx \l__tblr_c_tl { \__tblr_text_item:ne { text } {[#1][#2]} } \tl_set:Nx \l__tblr_w_tl - { \__tblr_prop_item:ne { cell } { [#1][#2] / width } } - \tl_if_empty:NT \l__tblr_w_tl + { \__tblr_data_item:neen { cell } {#1} {#2} { width } } + \dim_compare:nNnT { \l__tblr_w_tl } < { 0pt } % cell width unset { - \__tblr_prop_if_in:nxF { cell } { [#1][#2] / colspan } + \int_compare:nNnT + { \__tblr_data_item:neen { cell } {#1} {#2} { colspan } } < {2} { \tl_set:Nx \l__tblr_w_tl - { \__tblr_prop_item:ne { column } { [#2] / width } } + { \__tblr_data_item:nen { column } {#2} { width } } } } - \tl_if_empty:NT \l__tblr_w_tl + \dim_compare:nNnT { \l__tblr_w_tl } < { 0pt } % column width unset { \bool_if:NTF \l__tblr_math_mode_bool { @@ -2757,15 +3080,15 @@ { \group_begin: \tl_set:Nx \l__tblr_c_tl - { \__tblr_prop_item:ne {cell} { [#1][#2] / colspan } } - \tl_if_empty:NF \l__tblr_c_tl + { \__tblr_data_item:neen { cell } {#1} {#2} { colspan } } + \int_compare:nNnT { \l__tblr_c_tl } > {1} { - \__tblr_prop_gput:nxx {cell} { [#1][#2] / @cell-width } { \dim_use:N #3 } + \__tblr_data_gput:neene { cell } {#1} {#2} { @cell-width } {\dim_use:N #3} \dim_gzero:N #3 % don't affect column width } \tl_set:Nx \l__tblr_r_tl - { \__tblr_prop_item:ne {cell} { [#1][#2] / rowspan } } - \tl_if_empty:NF \l__tblr_r_tl + { \__tblr_data_item:neen { cell } {#1} {#2} { rowspan } } + \int_compare:nNnT { \l__tblr_r_tl } > {1} { \tl_case:Nn \g__tblr_cell_valign_tl { @@ -2794,8 +3117,8 @@ #4 #5 #6 \l__tblr_u_tl \l__tblr_v_tl } } - \__tblr_prop_gput:nxV {cell} { [#1][#2] / @cell-height } \l__tblr_u_tl - \__tblr_prop_gput:nxV {cell} { [#1][#2] / @cell-depth } \l__tblr_v_tl + \__tblr_data_gput:neenV { cell } {#1} {#2} { @cell-height } \l__tblr_u_tl + \__tblr_data_gput:neenV { cell } {#1} {#2} { @cell-depth } \l__tblr_v_tl %% Don't affect row sizes \dim_gzero:N #4 \dim_gzero:N #5 @@ -2876,12 +3199,12 @@ \cs_new_protected:Npn \__tblr_update_col_size:nN #1 #2 { \tl_set:Nx \l_tmpb_tl - { \__tblr_prop_item:ne {column} { [#1] / @col-width } } + { \__tblr_data_item:nen { column } {#1} { @col-width } } \bool_lazy_or:nnT { \tl_if_empty_p:N \l_tmpb_tl } { \dim_compare_p:nNn { \dim_use:N #2 } > { \l_tmpb_tl } } { - \__tblr_prop_gput:nxx {column} { [#1] / @col-width } { \dim_use:N #2 } + \__tblr_data_gput:nene { column } {#1} { @col-width } { \dim_use:N #2 } } } @@ -2925,14 +3248,14 @@ \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl { \tl_set:Nx \l__tblr_a_tl - { \__tblr_prop_item:ne {column} { [\l__tblr_j_tl] / width } } + { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { width } } \tl_set:Nx \l__tblr_b_tl - { \__tblr_prop_item:ne {column} { [\l__tblr_j_tl] / coefficient } } + { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { coefficient } } \tl_set:Nx \l__tblr_c_tl - { \__tblr_prop_item:ne {column} { [\l__tblr_j_tl] / @col-width } } - \tl_if_empty:NTF \l__tblr_a_tl + { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { @col-width } } + \dim_compare:nNnTF { \l__tblr_a_tl } < { 0pt } % column width unset { - \tl_if_empty:NTF \l__tblr_b_tl + \dim_compare:nNnTF { \l__tblr_b_tl pt } = { 0pt } { \dim_sub:Nn \l__column_target_dim { \l__tblr_c_tl } } { \prop_put:Nxx \l__column_coefficient_prop @@ -2948,17 +3271,17 @@ } { \dim_sub:Nn \l__column_target_dim { \l__tblr_a_tl } } \tl_set:Nx \l__tblr_a_tl - { \__tblr_prop_item:ne {vline} { [\l__tblr_j_tl] / @vline-width } } + { \__tblr_text_item:ne { vline } { [\l__tblr_j_tl] / @vline-width } } \tl_set:Nx \l__tblr_b_tl - { \__tblr_prop_item:ne {column} { [\l__tblr_j_tl] / leftsep} } + { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { leftsep } } \tl_set:Nx \l__tblr_c_tl - { \__tblr_prop_item:ne {column} { [\l__tblr_j_tl] / rightsep } } + { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { rightsep } } \dim_set:Nn \l__column_target_dim { \l__column_target_dim - \l__tblr_a_tl - \l__tblr_b_tl - \l__tblr_c_tl } } \tl_set:Nx \l__tblr_a_tl { - \__tblr_prop_item:ne {vline} + \__tblr_text_item:ne { vline } { [\int_eval:n {\c@colcount + 1}] / @vline-width } } \tl_if_empty:NF \l__tblr_a_tl @@ -2979,8 +3302,8 @@ } \prop_map_inline:Nn \l__column_computed_width_prop { - \__tblr_prop_gput:nnx {column} { [##1] / width } { ##2 } - \__tblr_prop_gput:nnn {column} { [##1] / @col-width } { 0pt } + \__tblr_data_gput:nnne { column } {##1} { width } {##2} + \__tblr_data_gput:nnnn { column } {##1} { @col-width } { 0pt } } \__tblr_calculate_cell_sizes: } @@ -3067,7 +3390,7 @@ \__tblr_collect_span_widths: \__tblr_set_column_widths_from_span_widths: } - \LogTblrTracing {column} + \LogTblrTracing { column } \__tblr_calculate_cell_sizes: } \__tblr_prop_if_in:nnT {table} {rowspan} @@ -3095,14 +3418,13 @@ { \dim_eval:n { - \__tblr_prop_item:ne {column} - { [\int_eval:n { \l__tblr_j_tl - 1 }] / rightsep } + \__tblr_data_item:nen { column } + { \int_eval:n { \l__tblr_j_tl - 1 } } { rightsep } + - \__tblr_prop_item:ne {vline} + \__tblr_text_item:ne { vline } { [\l__tblr_j_tl] / @vline-width } + - \__tblr_prop_item:ne {column} - { [\l__tblr_j_tl] / leftsep} + \__tblr_data_item:nen { column } { \l__tblr_j_tl } { leftsep } } } } @@ -3111,7 +3433,7 @@ { 0pt } } \prop_put:Nxx \l__tblr_col_item_skip_size_prop { item[\l__tblr_j_tl] } - { \__tblr_prop_item:ne {column} { [\l__tblr_j_tl] / @col-width } } + { \__tblr_data_item:nen { column } { \l__tblr_j_tl } { @col-width } } } \__tblr_do_if_tracing:nn { cellspan } { \prop_log:N \l__tblr_col_item_skip_size_prop } @@ -3131,7 +3453,7 @@ \__tblr_data_item:nen { row } { \int_eval:n {\l__tblr_i_tl - 1} } { belowsep } + - \__tblr_prop_item:ne {hline} + \__tblr_text_item:ne { hline } { [\l__tblr_i_tl] / @hline-height } + \__tblr_data_item:nen { row } { \l__tblr_i_tl } { abovesep } @@ -3165,10 +3487,10 @@ { \tl_set:Nx \l__tblr_a_tl { - \__tblr_prop_item:ne {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / colspan } + \__tblr_data_item:neen { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { colspan } } - \tl_if_empty:NF \l__tblr_a_tl + \int_compare:nNnT { \l__tblr_a_tl } > {1} { \__tblr_put_if_larger:Nxx \l__tblr_col_span_size_prop { @@ -3176,8 +3498,8 @@ \int_eval:n {\l__tblr_j_tl + \l__tblr_a_tl - 1} ) } { - \__tblr_prop_item:ne {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / @cell-width } + \__tblr_data_item:neen { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { @cell-width } } } } @@ -3198,15 +3520,15 @@ { \tl_set:Nx \l__tblr_a_tl { - \__tblr_prop_item:ne {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / rowspan } + \__tblr_data_item:neen { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { rowspan } } - \tl_if_empty:NF \l__tblr_a_tl + \int_compare:nNnT { \l__tblr_a_tl } > {1} { \tl_set:Nx \l__tblr_v_tl { - \__tblr_prop_item:ne {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / valign } + \__tblr_data_item:neen { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { valign } } \tl_if_eq:NnT \l__tblr_v_tl { h } { @@ -3215,8 +3537,8 @@ \__tblr_data_item:nen { row } { \l__tblr_i_tl } { @row-head } } - \__tblr_prop_gput:nxV {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / @cell-height } + \__tblr_data_gput:neenV { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { @cell-height } \l__tblr_h_tl } \tl_if_eq:NnT \l__tblr_v_tl { f } @@ -3228,8 +3550,8 @@ { \int_eval:n { \l__tblr_i_tl + \l__tblr_a_tl - 1 } } { @row-foot } } - \__tblr_prop_gput:nxV {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / @cell-depth } + \__tblr_data_gput:neenV { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { @cell-depth } \l__tblr_d_tl } \__tblr_put_if_larger:Nxx \l__tblr_row_span_size_prop @@ -3240,11 +3562,11 @@ { \dim_eval:n { - \__tblr_prop_item:ne {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / @cell-height } + \__tblr_data_item:neen { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { @cell-height } + - \__tblr_prop_item:ne {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / @cell-depth } + \__tblr_data_item:neen { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { @cell-depth } } } \prop_put:Nxx \l__tblr_row_span_to_row_prop @@ -3340,8 +3662,8 @@ { \int_step_variable:nNn { \c@colcount } \l__tblr_j_tl { - \__tblr_prop_gput:nxx {column} - { [\l__tblr_j_tl] / @col-width } + \__tblr_data_gput:nene { column } + { \l__tblr_j_tl } { @col-width } { \prop_item:Ne \l__tblr_col_item_skip_size_prop { item[\l__tblr_j_tl] } } } } @@ -3383,17 +3705,17 @@ { \tl_set:Nx \l__tblr_a_tl { - \__tblr_prop_item:ne {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / colspan } + \__tblr_data_item:neen { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { colspan } } - \tl_if_empty:NF \l__tblr_a_tl + \int_compare:nNnT { \l__tblr_a_tl } > {1} { \__tblr_calc_span_widths:xxN { \l__tblr_j_tl } { \int_eval:n { \l__tblr_j_tl + \l__tblr_a_tl - 1 } } \l__tblr_w_dim - \__tblr_prop_gput:nxx {cell} - { [\l__tblr_i_tl][\l__tblr_j_tl] / width } + \__tblr_data_gput:neene { cell } + { \l__tblr_i_tl } { \l__tblr_j_tl } { width } { \dim_use:N \l__tblr_w_dim } } } @@ -3448,7 +3770,7 @@ { \dim_set:Nn \l_tmpa_dim { - \__tblr_prop_item:ne { hline } { [\l__tblr_i_tl] / @hline-height } + \__tblr_text_item:ne { hline } { [\l__tblr_i_tl] / @hline-height } + \__tblr_data_item:nen { row } { \l__tblr_i_tl } { abovesep } + @@ -3546,7 +3868,7 @@ \cs_new_protected:Npn \__tblr_valign_whole_top:N #1 { \tl_set:Nx \l__tblr_a_tl - { \__tblr_prop_item:ne { hline } { [1] / @hline-height } } + { \__tblr_text_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 } } @@ -3580,7 +3902,7 @@ { \tl_set:Nx \l__tblr_a_tl { - \__tblr_prop_item:ne { hline } + \__tblr_text_item:ne { hline } { [\int_eval:n {\c@rowcount + 1}] / @hline-height } } %% Note that \l__tblr_b_tl may be empty @@ -3630,14 +3952,14 @@ \cs_new_protected:Npn \__tblr_build_hline_segment:nn #1 #2 { \tl_set:Nx \l__tblr_n_tl - { \__tblr_prop_item:ne { hline } { [#1] / @hline-count } } + { \__tblr_text_item:ne { hline } { [#1] / @hline-count } } \tl_set:Nx \l__tblr_o_tl - { \__tblr_prop_item:ne { hline } { [#1][#2] / omit } } + { \__tblr_text_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 { - \tl_if_empty:NF \l__tblr_n_tl + \int_compare:nNnT { \l__tblr_n_tl } > {0} { \__tblr_build_hline_segment_real:nn {#1} {#2} } } { \__tblr_build_hline_segment_omit:nn {#1} {#2} } @@ -3653,7 +3975,7 @@ \cs_new_protected:Npn \__tblr_build_hline_segment_real:nn #1 #2 { \tl_set:Nx \l__tblr_s_tl - { \__tblr_prop_item:ne { hline } { [#1] / rulesep } } + { \__tblr_prop_item:ne { table } { rulesep } } \vbox_set:Nn \l__tblr_c_box { %% add an empty hbox to support vbox width @@ -3661,12 +3983,12 @@ \int_step_inline:nn { \l__tblr_n_tl } { \tl_set:Nx \l__tblr_h_tl - { \__tblr_prop_item:ne { hline } { [#1](##1) / @hline-height } } + { \__tblr_text_item:ne { hline } { [#1](##1) / @hline-height } } \hrule height ~ 0pt % remove lineskip \hbox_set_to_wd:Nnn \l__tblr_b_box { \l__tblr_col_o_wd_dim } { \tl_set:Nx \l__tblr_f_tl - { \__tblr_prop_item:ne { hline } { [#1][#2](##1) / fg } } + { \__tblr_text_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} } @@ -3687,16 +4009,16 @@ \cs_new_protected:Npn \__tblr_get_col_outer_width_border_width:nNN #1 #2 #3 { \dim_set:Nn #3 - { \__tblr_prop_item:ne {vline} { [\int_eval:n {#1 + 1}] / @vline-width } } + { \__tblr_text_item:ne { vline } { [\int_eval:n {#1 + 1}] / @vline-width } } \dim_set:Nn #2 { - \__tblr_prop_item:ne {vline} { [#1] / @vline-width } + \__tblr_text_item:ne { vline } { [#1] / @vline-width } + - \__tblr_prop_item:ne {column} { [#1] / leftsep } + \__tblr_data_item:nen { column } {#1} { leftsep } + - \__tblr_prop_item:ne {column} { [#1] / @col-width } + \__tblr_data_item:nen { column } {#1} { @col-width } + - \__tblr_prop_item:ne {column} { [#1] / rightsep } + \__tblr_data_item:nen { column } {#1} { rightsep } + #3 } @@ -3756,12 +4078,12 @@ \cs_new_protected:Npn \__tblr_build_vline_segment:nn #1 #2 { \tl_set:Nx \l__tblr_n_tl - { \__tblr_prop_item:ne { vline } { [#2] / @vline-count } } + { \__tblr_text_item:ne { vline } { [#2] / @vline-count } } \tl_set:Nx \l__tblr_o_tl - { \__tblr_prop_item:ne { vline } { [#1][#2] / omit } } + { \__tblr_text_item:ne { vline } { [#1][#2] / omit } } \tl_if_empty:NTF \l__tblr_o_tl { - \tl_if_empty:NF \l__tblr_n_tl + \int_compare:nNnT { \l__tblr_n_tl } > {0} { \__tblr_build_vline_segment_real:nn {#1} {#2} } } { \__tblr_build_vline_segment_omit:nn {#1} {#2} } @@ -3771,7 +4093,7 @@ \cs_new_protected:Npn \__tblr_build_vline_segment_omit:nn #1 #2 { \tl_set:Nx \l__tblr_w_tl - { \__tblr_prop_item:ne { vline } { [#2] / @vline-width } } + { \__tblr_text_item:ne { vline } { [#2] / @vline-width } } \skip_horizontal:N \l__tblr_w_tl } @@ -3781,10 +4103,10 @@ \cs_new_protected:Npn \__tblr_build_vline_segment_real:nn #1 #2 { \tl_set:Nx \l__tblr_s_tl - { \__tblr_prop_item:ne { vline } { [#2] / rulesep } } + { \__tblr_prop_item:ne { table } { rulesep } } \tl_set:Nx \l__tblr_b_tl { - \__tblr_prop_item:ne { hline } + \__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 } } @@ -3793,12 +4115,12 @@ \int_step_inline:nn { \l__tblr_n_tl } { \tl_set:Nx \l__tblr_w_tl - { \__tblr_prop_item:ne { vline } { [#2](##1) / @vline-width } } + { \__tblr_text_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_prop_item:ne { vline } { [#1][#2](##1) / fg } } + { \__tblr_text_item:ne { vline } { [#1][#2](##1) / fg } } \tl_if_empty:NF \l__tblr_f_tl { \color{\l__tblr_f_tl} } \__tblr_get_vline_segment_child:nnnxx {#1} {#2} {##1} { \dim_eval:n { \l__tblr_row_ht_dim } } @@ -3828,24 +4150,24 @@ \int_set:Nn \c@colnum {#2} \group_begin: \tl_set:Nx \l__tblr_w_tl - { \__tblr_prop_item:ne { column } { [#2] / @col-width } } + { \__tblr_data_item:nen { column } {#2} { @col-width } } \tl_set:Nx \l__tblr_h_tl { \__tblr_data_item:nen { row } {#1} { @row-height } } \tl_set:Nx \l__tblr_x_tl - { \__tblr_prop_item:ne { column } { [#2] / leftsep} } + { \__tblr_data_item:nen { column } {#2} { leftsep} } \tl_set:Nx \l__tblr_y_tl - { \__tblr_prop_item:ne { column } { [#2] / rightsep } } + { \__tblr_data_item:nen { column } {#2} { rightsep } } \tl_set:Nx \l__tblr_cell_colspan_tl - { \__tblr_prop_item:ne { cell } { [#1][#2] / colspan } } - \tl_if_empty:NTF \l__tblr_cell_colspan_tl + { \__tblr_data_item:neen { cell } {#1} {#2} { colspan } } + \int_compare:nNnTF { \l__tblr_cell_colspan_tl } < {2} { \dim_set:Nn \l__tblr_cell_wd_dim { \l__tblr_w_tl } } { \__tblr_get_span_horizontal_sizes:NNNNN #1 #2 \l__tblr_o_dim \l__tblr_cell_wd_dim \l__tblr_q_dim } \tl_set:Nx \l__tblr_cell_rowspan_tl - { \__tblr_prop_item:ne { cell } { [#1][#2] / rowspan } } - \tl_if_empty:NTF \l__tblr_cell_rowspan_tl + { \__tblr_data_item:neen { cell } {#1} {#2} { rowspan } } + \int_compare:nNnTF { \l__tblr_cell_rowspan_tl } < {2} { \dim_set:Nn \l__tblr_cell_ht_dim { \l__tblr_h_tl } } { \__tblr_get_span_vertical_sizes:NNNNN #1 #2 @@ -3872,7 +4194,7 @@ \c__tblr_valign_m_tl { \vfil - \tl_if_empty:NT \l__tblr_cell_rowspan_tl + \int_compare:nNnT { \l__tblr_cell_rowspan_tl } < {2} { \box_set_ht:Nn \l__tblr_a_box { \__tblr_data_item:nen { row } {#1} { @row-upper } } @@ -3892,7 +4214,7 @@ \c__tblr_valign_f_tl { \vfil - \tl_if_empty:NTF \l__tblr_cell_rowspan_tl + \int_compare:nNnTF { \l__tblr_cell_rowspan_tl } < {2} { \box_set_dp:Nn \l__tblr_a_box { \__tblr_data_item:nen { row } {#1} { @row-foot } } @@ -3924,11 +4246,11 @@ \cs_new_protected:Npn \__tblr_build_cell_background:NN #1 #2 { - \__tblr_prop_if_in:nxF {cell} { [#1][#2] / omit } + \int_compare:nNnT { \__tblr_data_item:neen { cell } {#1} {#2} { omit } } = {0} { \group_begin: \tl_set:Nx \l__tblr_b_tl - { \__tblr_prop_item:ne { cell } { [#1][#2] / background } } + { \__tblr_data_item:neen { cell } {#1} {#2} { background } } \tl_if_empty:NF \l__tblr_b_tl { \__tblr_get_cell_background_width:NNN #1 #2 \l_tmpa_dim @@ -3946,7 +4268,7 @@ %% #1: row number; #2: column number; #3 resulting dimension \cs_new_protected:Npn \__tblr_get_cell_background_width:NNN #1 #2 #3 { - \tl_if_empty:NTF \l__tblr_cell_colspan_tl + \int_compare:nNnTF { \l__tblr_cell_colspan_tl } < {2} { \dim_set:Nn #3 { \l__tblr_x_tl + \l__tblr_w_tl + \l__tblr_y_tl } } { \dim_set:Nn #3 { \l__tblr_o_dim + \l__tblr_cell_wd_dim + \l__tblr_q_dim } @@ -3956,7 +4278,7 @@ %% #1: row number; #2: column number; #3 resulting dimension \cs_new_protected:Npn \__tblr_get_cell_background_depth:NNN #1 #2 #3 { - \tl_if_empty:NTF \l__tblr_cell_rowspan_tl + \int_compare:nNnTF { \l__tblr_cell_rowspan_tl } < {2} { \dim_set_eq:NN #3 \l__tblr_row_dp_dim } { \dim_set:Nn #3 @@ -4014,7 +4336,7 @@ \cs_new_protected:Npn \__tblr_get_span_horizontal_sizes:NNNNN #1 #2 #3 #4 #5 { \dim_set:Nn #3 - { \__tblr_prop_item:ne { column } { [#2] / leftsep} } + { \__tblr_data_item:nen { column } {#2} { leftsep } } \dim_zero:N #4 \int_step_inline:nnn { #2 } { #2 + \l__tblr_cell_colspan_tl - 2 } { @@ -4033,8 +4355,8 @@ } \dim_set:Nn #5 { - \__tblr_prop_item:ne { column } - { [\int_eval:n {#2 + \l__tblr_cell_colspan_tl - 1}] / rightsep } + \__tblr_data_item:nen { column } + { \int_eval:n {#2 + \l__tblr_cell_colspan_tl - 1} } { rightsep } } %\tl_log:x { cell[#1][#2] ~:~ \dim_use:N #3, \dim_use:N #4, \dim_use:N #5 } } @@ -4061,6 +4383,7 @@ \bool_new:N \g__tblr_tracing_rowspec_bool \bool_new:N \g__tblr_tracing_target_bool \bool_new:N \g__tblr_tracing_cellspan_bool +\bool_new:N \g__tblr_tracing_intarray_bool \keys_define:nn { tblr-set-tracing } { @@ -4088,6 +4411,8 @@ -target .code:n = \bool_gset_false:N \g__tblr_tracing_target_bool, +cellspan .code:n = \bool_gset_true:N \g__tblr_tracing_cellspan_bool, -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, all .code:n = \__tblr_enable_all_tracings:, none .code:n = \__tblr_disable_all_tracings:, } @@ -4106,6 +4431,7 @@ \bool_gset_true:N \g__tblr_tracing_rowspec_bool \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 } \cs_new_protected_nopar:Npn \__tblr_disable_all_tracings: @@ -4122,6 +4448,7 @@ \bool_gset_false:N \g__tblr_tracing_rowspec_bool \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 } \NewDocumentCommand \LogTabularrayTracing { m } @@ -4143,7 +4470,7 @@ \cs_new_protected:Npn \__tblr_log_tracing_text: { - \__tblr_prop_log:n { text } + \__tblr_text_log:n { text } } \cs_new_protected:Npn \__tblr_log_tracing_command: @@ -4158,7 +4485,7 @@ \cs_new_protected:Npn \__tblr_log_tracing_column: { - \__tblr_prop_log:n { column } + \__tblr_data_log:n { column } } \cs_new_protected:Npn \__tblr_log_tracing_row: @@ -4168,17 +4495,17 @@ \cs_new_protected:Npn \__tblr_log_tracing_cell: { - \__tblr_prop_log:n { cell } + \__tblr_data_log:n { cell } } \cs_new_protected:Npn \__tblr_log_tracing_vline: { - \__tblr_prop_log:n { vline } + \__tblr_text_log:n { vline } } \cs_new_protected:Npn \__tblr_log_tracing_hline: { - \__tblr_prop_log:n { hline } + \__tblr_text_log:n { hline } } \cs_new_protected:Npn \__tblr_log_tracing_colspec: diff --git a/Master/texmf-dist/tex/latex/tabularray/tabularray.sty b/Master/texmf-dist/tex/latex/tabularray/tabularray.sty index 4717992539e..2e3fa4eb5d0 100644 --- a/Master/texmf-dist/tex/latex/tabularray/tabularray.sty +++ b/Master/texmf-dist/tex/latex/tabularray/tabularray.sty @@ -12,18 +12,12 @@ \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} -\ProvidesExplPackage{tabularray}{2021-08-01}{2021M} +\ProvidesExplPackage{tabularray}{2021-09-01}{2021N} {Typeset tabulars and arrays with LaTeX3} \RequirePackage{xparse} -\AtBeginDocument - { - \@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{} - \@ifpackageloaded{hyperref}{\hypersetup{pdfborder={0 0 0}}}{} - } - -\ExplSyntaxOn +\AtBeginDocument{\@ifpackageloaded{xcolor}{\RequirePackage{ninecolors}}{}} %% Backport \tl_if_eq:NnTF for old texlive 2020 \cs_if_exist:NF \tl_if_eq:NnTF @@ -1114,11 +1108,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 @@ -1132,13 +1133,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: } @@ -1215,6 +1222,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, } @@ -1238,24 +1260,59 @@ \__tblr_get_childs:nx {#1} { \int_use:N \c@colcount } \clist_map_inline:Nn \l_tblr_childs_clist { - \__tblr_spec_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_spec_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_spec_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 } } @@ -1313,6 +1370,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} } @@ -1413,6 +1472,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, } @@ -1451,6 +1512,18 @@ { [##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 } + } } } @@ -1549,6 +1622,7 @@ { 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 }, @@ -1685,6 +1759,23 @@ } } } + %% 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 } @@ -1809,6 +1900,7 @@ { 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 }, @@ -1968,6 +2060,7 @@ { 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 }, @@ -2004,12 +2097,25 @@ } \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 { @@ -2271,6 +2377,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] } @@ -2333,7 +2440,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} @@ -2578,8 +2688,10 @@ { \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_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: } @@ -2599,6 +2711,15 @@ } } +\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: { @@ -2627,7 +2748,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 \q_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 } @@ -2637,26 +2758,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 \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 @@ -2701,8 +2822,8 @@ } { \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 } } } @@ -2764,6 +2885,7 @@ @vline-count = 0, } +\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: @@ -2812,6 +2934,7 @@ \__tblr_spec_gput:nen { vline } { [\int_eval:n { \c@colcount + 1}] / ##1 } {##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 } } @@ -3091,10 +3214,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: } @@ -3317,21 +3443,7 @@ \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__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 } } - } + \__tblr_get_cell_size_with_box: } } \tl_put_left:NV \l__tblr_c_tl \l__tblr_f_tl @@ -3339,6 +3451,54 @@ \group_end: } +\cs_new_protected:Npn \__tblr_get_cell_size_with_box: + { + \tl_if_eq:NnTF \l__tblr_inner_spec_measure_tl { vbox } + { \__tblr_get_cell_size_with_vbox: } + { \__tblr_get_cell_size_with_hbox: } + } + +%% 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 { @@ -3401,13 +3561,18 @@ \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 } { \regex_replace_all:nnN { . } { \c{string} \0 } #1 - \tl_set:Nx #1 { #1 } + \tl_set:Nx #1 { #1 \noexpand \empty } \exp_args:NV \tex_scantokens:D #1 } } @@ -3657,7 +3822,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 @@ -3672,6 +3838,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: } @@ -4154,8 +4328,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] } } @@ -4535,6 +4709,17 @@ \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 } { } @@ -4592,6 +4777,19 @@ \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 } %%% -------------------------------------------------------- @@ -4627,8 +4825,19 @@ { #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 } } } @@ -5005,9 +5214,10 @@ { \skip_vertical:n { \__tblr_spec_item:nn { outer } { presep } } } \LogTblrTracing { page } \nointerlineskip - \mode_leave_vertical: + \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: @@ -5024,16 +5234,25 @@ \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 { - \__tblr_do_if_tracing:nn { page } { \int_log:N \l__tblr_curr_i_int } - \int_compare:nNnF - { \l__tblr_prev_i_int - \l__tblr_long_from_int } < {0} + \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 @@ -5041,7 +5260,6 @@ \LogTblrTracing { page } \dim_set:Nn \l__tblr_remain_height_dim { \pagegoal - \pagetotal - \l__tblr_row_head_foot_dim - \l_tmpa_dim } - \int_set:Nn \l__tblr_long_from_int { \l__tblr_prev_i_int + 1 } } { \bool_if:NTF \l__tblr_page_break_curr_bool @@ -5073,7 +5291,10 @@ \__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 } } - \hrule height ~ 0pt + % 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 } @@ -5225,10 +5446,16 @@ \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 @@ -5236,18 +5463,50 @@ \bool_lazy_or:nnT { \int_compare_p:nNn { \l__tblr_i_tl } > {#1} } { \bool_if_p:N \l__tblr_build_first_hline_bool } - { \hbox:n { \__tblr_build_hline:V \l__tblr_i_tl } } + { \__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 } \bool_if:NT \l__tblr_build_last_hline_bool - { \hbox:n { \__tblr_build_hline:n { \int_eval:n {#2 + 1} } } } + { + \__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 { @@ -5411,10 +5670,13 @@ \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_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 } @@ -5448,12 +5710,69 @@ } } +\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} @@ -5462,12 +5781,21 @@ \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 @@ -5500,6 +5828,28 @@ } \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 { @@ -5530,12 +5880,6 @@ { \tl_set:Nx \l__tblr_s_tl { \__tblr_prop_item:ne { inner } { rulesep } } - \tl_set:Nx \l__tblr_b_tl - { - \__tblr_spec_item:ne { hline } - { [\int_eval:n{#1 + 1}](1) / @hline-height } - } - \tl_if_empty:NT \l__tblr_b_tl { \tl_set:Nn \l__tblr_b_tl { 0pt } } \hbox_set:Nn \l__tblr_a_box { \int_step_inline:nn { \l__tblr_n_tl } @@ -5548,10 +5892,12 @@ \tl_set:Nx \l__tblr_f_tl { \__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 @@ -5565,6 +5911,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 @@ -5609,9 +6017,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 } { @@ -6043,10 +6455,56 @@ \NewTblrLibrary { booktabs } { - \NewTableCommand \toprule [1] [] { \hline [0.08em, ##1] } - \NewTableCommand \midrule [1] [] { \hline [0.05em, ##1] } - \NewTableCommand \bottomrule [1] [] { \hline [0.08em, ##1] } - \NewTableCommand \cmidrule [2] [] { \cline [0.03em, ##1] { ##2 } } + % 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 diagbox and command \diagbox @@ -6136,4 +6594,12 @@ } } -\ExplSyntaxOff +%% 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 } + } + |