7

I'm trying to test tblr tabular provided by tabularray package in an RTL context by adding \textdir TRT (lualatex engine), everything looks fine except for this issue shown in this example

\documentclass{article}
\usepackage{tabularray}

\textdir TRT 
\begin{document}

\begin{tblr}{|c|}
\hline
one\\
\hline 
\end{tblr}

\end{document}

The output appears fine, but if you take a great zoom the following defect can be seen ( horizontal lines cross the left side of the table )

enter image description here

With double vlines the defect becomes greater, hlines are shifted more to the left

\documentclass{article}
\usepackage{tabularray}

\textdir TRT
\begin{document}

a%
\begin{tblr}{|c||}
\hline
one\\
\hline 
\end{tblr}%
b
\end{document}

enter image description here

Remark

Tabular must be in RTL context not enclosed in LTR group so second column must be on the left of the first column.

2 Answers 2

3

The issue come from \mathdir, tblr use \vcenter command like standard tabular environment so basically we are in math mode in the beginning of the tabular, and the mathdir is TLT we need to change it to TRT for tabular in right to left context.

The math direction needs to be restored inside tabular cells (math direction in RTL context is always LTR), this can be done with \SetTblrInner{cells={preto={\mathdir TLT}}} (thanks to @UdiFogiel)

\documentclass{article}

\usepackage{tabularray}
\setlength\parindent{0pt}

\AddToHook{env/tblr/begin}{%
\ifnum\textdirection=0\else \mathdir TRT\fi
}

\SetTblrInner{cells={preto={\mathdir TLT}}}

\begin{document}

Hello\par
\begin{tblr}{|c||c|||}
\hline
one & two \\
\hline
\end{tblr}

\textdir TRT 

Hello\par
\begin{tblr}{|c||c|||}
\hline
one & two $ax+b$\\
\hline
\end{tblr}

$ax+b$

\end{document}
2
+50

I couldn't find the root of the problem, but you might be satisfied with enclosing the tabular in LTR group and reverse the horizontal order of the cells (internally, not typing them in reverse, and the cells themselves would still be RTL).

\documentclass{article}
\usepackage{tabularray}


\ExplSyntaxOn
\makeatletter

\bool_new:N \__tblr_RTL_bool
\cs_set_protected:Npn \__tblr_split_one_line:nn #1 #2
{
    \seq_set_split:Nnn \l_tmpa_seq { & } { #2 }
    \bool_if:NTF \__tblr_RTL_bool
    { 
        \seq_reverse:N \l_tmpa_seq 
    }
    { }
    \int_set:Nn \c@rownum {#1}
    \int_zero:N \c@colnum
    \seq_map_inline:Nn \l_tmpa_seq
    {
        \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
        \bool_if:NTF \__tblr_RTL_bool
        { 
            \tl_if_empty:NTF \l_tmpa_tl { } {\tl_put_left:Nn \l_tmpa_tl { \textdir TRT } }
        }
        {  }
        \__tblr_trim_par_space_tokens:N \l_tmpa_tl
        \__tblr_spec_gput:neV { text } { [#1][\int_use:N \c@colnum] } \l_tmpa_tl
    }
    \bool_lazy_all:nTF
    {
        { \int_compare_p:nNn {#1} = {\c@rowcount} }
        { \int_compare_p:nNn {\c@colnum} = {1} }
        { \tl_if_empty_p:N \l_tmpa_tl }
    }
    { \int_decr:N \c@rowcount }
    {
        \__tblr_prop_gput:nnx
        {row} { [#1] / cell-number } { \int_use:N \c@colnum }
        \int_compare:nT { \c@colnum > \c@colcount }
        {
            \int_set_eq:NN \c@colcount \c@colnum
        }
    }
}

\cs_set_protected:Npn \__tblr_environ_code:nnnn #1 #2 #3 #4
{
    \group_align_safe_begin:
    \int_gincr:N \g__tblr_table_count_int
    \tl_set:Nn \l__tblr_env_name_tl {#1}
    \mode_if_math:TF
    { \bool_set_true:N \l__tblr_math_mode_bool }
    { \bool_set_false:N \l__tblr_math_mode_bool }
    \str_if_eq:eeTF { TRT } { \lua_now:n { tex.print(tex.textdir) } }
    { 
        \bool_set_true:N \__tblr_RTL_bool
        \textdir TLT
    }
    { }
    \__tblr_builder:nnn {#2} {#3} {#4}
    \group_align_safe_end:
}
\makeatother
\ExplSyntaxOff

\pagedir TRT \bodydir TRT \pardir TRT \textdir TRT
\begin{document}

    \begin{tblr}{|c|c|}
        \hline
        one & two\\
        \hline 
    \end{tblr}

\begin{tblr}{|c|c||}
    \hline
    one & two\\
    \hline 
\end{tblr}%

\end{document}

With the above code all the horizontal coordinates related to inner specification will be reversed, e.g. in the second tabular the double vlines are on the right and not on the left. I believe it can be fixed too, but i found this behavior more convenient.

Remark

I think the problem is related to the leftpos, rightpos, abovepos and belowpos Inner specification keys, see how they affect the examples you gave

\documentclass{article}
\usepackage{tabularray}

\textdir TRT 
\begin{document}
    
    \begin{tblr}{hlines={rightpos=0},vlines={abovepos=1}}
        one\\
    \end{tblr}
    
    
        a%
        \begin{tblr}{colspec={|c||},hlines={rightpos=0},vlines={abovepos=1}}
            one\\
        \end{tblr}%
        b
    \end{document}
\end{document}

maybe the function \__tblr_get_hline_left_right_skips:nnn is the cause for this problem.

Edit

I wanted to add a few things to Salim Bou's great solution. Instead of using hooks, we can patch the command \__tblr_environ_code:nnnn to test the text direction, this way we won't need to hook the test \ifnum\textdirection=0\else \mathdir TRT\fi for each environment defined via \NewTblrEnviron. It can be done with

\ExplSyntaxOn
\cs_set_protected:Npn \__tblr_environ_code:nnnn #1 #2 #3 #4
{
    \ifnum\textdirection=0\else \mathdir TRT\fi % <<< new
    \group_align_safe_begin:
    \int_gincr:N \g__tblr_table_count_int
    \tl_set:Nn \l__tblr_env_name_tl {#1}
    \mode_if_math:TF
    { \bool_set_true:N \l__tblr_math_mode_bool }
    { \bool_set_false:N \l__tblr_math_mode_bool }
    \__tblr_builder:nnn {#2} {#3} {#4}
    \group_align_safe_end:
}
\ExplSyntaxOff

Another observation is that a Tblr with the outer property long is not using math mode, as can be seen in the following code:

\documentclass{article}

\usepackage{tabularray}

\begin{document}
    
    
    \pagedir TRT \bodydir TRT  
    
    Hello\par
    \begin{longtblr}{|c||c|||}
        \hline
        one & two $ax+b$\\
        \hline
    \end{longtblr}
\end{document}

But it needs \pagedir and \bodydir to be TRT to typeset in RTL.

A final note is that using \SetTblrInner[tblr,longtblr]{cells={cmd={\mathdir TLT}}} will fail if the cell is warped with more than a couple of braces, for example in the following table the direction of the equation is wrong

\documentclass{article}

\usepackage{tabularray}


\AddToHook{env/tblr/begin}{%
\ifnum\textdirection=0\else \mathdir TRT\fi
}

\SetTblrInner{cells={cmd={\mathdir TLT}}}

\begin{document}

\textdir TRT 

Hello\par
\begin{tblr}{|c||c|||}
\hline
one & {{{two $ax+b$}}}\\
\hline
\end{tblr}

$ax+b$

\end{document}

Hence it might be better using \SetTblrInner{cells={preto={\mathdir TLT}}}, or again we can patch things up so we won't have to add the inner specification to each environment defined with \NewTblrEnviron with the following

\ExplSyntaxOn
\makeatletter

\cs_set_protected:Npn \__tblr_split_one_line:nn #1 #2
{
    \seq_set_split:Nnn \l_tmpa_seq { & } { #2 }
    \int_set:Nn \c@rownum {#1}
    \int_zero:N \c@colnum
    \seq_map_inline:Nn \l_tmpa_seq
    {
        \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
        \tl_if_empty:NF \l_tmpa_tl {\tl_put_left:Nn \l_tmpa_tl { \mathdir TLT } } % <<< new
        \__tblr_spec_gput:neV { text } { [#1][\int_use:N \c@colnum] } \l_tmpa_tl
    }
    %% Decrease row count by 1 if the last row has only one empty cell text
    %% We need to do it here since the > or < column type may add text to cells
    \bool_lazy_all:nTF
    {
        { \int_compare_p:nNn {#1} = {\c@rowcount} }
        { \int_compare_p:nNn {\c@colnum} = {1} }
        { \tl_if_empty_p:N \l_tmpa_tl }
    }
    { \int_decr:N \c@rowcount }
    {
        \__tblr_prop_gput:nnx
        {row} { [#1] / cell-number } { \int_use:N \c@colnum }
        \int_compare:nT { \c@colnum > \c@colcount }
        {
            \int_set_eq:NN \c@colcount \c@colnum
        }
    }
}

\makeatother
\ExplSyntaxOff
4
  • For columns type |c|c|| double vlines should be on the left side (same order as columns) like this: || wot | eno |
    – Salim Bou
    Jan 23, 2023 at 21:37
  • @SalimBou, It depends on your perspective on how things "should" be... As I stated I find it more natural that if I specify a double vlines on the right, they would appear on the right side, they are the same order as the columns specification, as I pointed out in my answer with the above code the cells index remain as if you type the tabular in LTR. I will try to reverse the index as well.
    – Udi Fogiel
    Jan 23, 2023 at 21:45
  • Thanks for the correction about longtblr environment and for patchs, the only baffling thing is why cmd=\mathdir TRT work fine inside cells warped with two braces and do not work with those wraped with three braces !
    – Salim Bou
    Jan 31, 2023 at 20:29
  • @SalimBou Thank you for finding the root of the problem! It seems to be intentional (and related to to the cmd option, not to \mathdir ), see github.com/lvjr/tabularray/issues/90 . It is also documented, though it hidden as a comment in the source code (see the definition of \__tblr_get_cell_text_real in page 117 of the documentation). There might better locations for the patchs, but I will leave that for the developer :)
    – Udi Fogiel
    Jan 31, 2023 at 20:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .