在 RTL 上下文中,tblr 表格中的移位 hlines

在 RTL 上下文中,tblr 表格中的移位 hlines

我正在尝试tabularray通过添加(lualatex 引擎)在 RTL 上下文中测试包提供的 tblr 表格\textdir TRT,除了本例中显示的这个问题之外,一切看起来都很好

\documentclass{article}
\usepackage{tabularray}

\textdir TRT 
\begin{document}

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

\end{document}

输出看起来不错,但如果放大,可以看到以下缺陷(水平线穿过表格左侧)

在此处输入图片描述

对于双 v 线,缺陷变得更大,h 线向左移动更多

\documentclass{article}
\usepackage{tabularray}

\textdir TRT
\begin{document}

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

在此处输入图片描述

评论

表格必须在 RTL 上下文中,不能包含在 LTR 组中,因此第二列必须位于第一列的左侧。

答案1

问题来自于\mathdirtblr使用\vcenter类似标准表格环境的命令,所以基本上我们在表格开头处于数学模式,并且 mathdir 是 TLT,我们需要在从右到左的上下文中将其更改为 TRT 以便进行表格处理。

需要在表格单元格内恢复数学方向(RTL 上下文中的数学方向始终是 LTR),这可以通过以下方式完成\SetTblrInner{cells={preto={\mathdir TLT}}}(感谢@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

我找不到问题的根源,但您可能会满足于将表格括在 LTR 组中并反转单元格的水平顺序(在内部,不以反向方式输入它们,并且单元格本身仍然是 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}

使用上述代码,与内部规范相关的所有水平坐标都将被反转,例如在第二个表格中,双垂直线位于右侧而不是左侧。我相信它也可以修复,但我发现这种行为更方便。

评论

leftpos我认为问题与、rightposabovepos内部规范键有关belowpos,看看它们如何影响您给出的示例

\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}

也许该功能\__tblr_get_hline_left_right_skips:nnn是造成此问题的原因。

编辑

我想在 Salim Bou 的出色解决方案中添加一些内容。我们可以修补命令\__tblr_environ_code:nnnn来测试文本方向,而不是使用钩子,这样我们就不需要\ifnum\textdirection=0\else \mathdir TRT\fi为每个通过定义的环境钩住测试\NewTblrEnviron。可以使用

\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

另一个观察结果是,具有外部属性的 Tblrlong没有使用数学模式,如下面的代码所示:

\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}

但它需要\pagedir以RTL 排版\bodydirTRT

最后要注意的是,\SetTblrInner[tblr,longtblr]{cells={cmd={\mathdir TLT}}}如果单元格扭曲了多个括号,则使用将失败,例如下表中方程的方向是错误的

\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}

因此,使用可能会更好\SetTblrInner{cells={preto={\mathdir TLT}}},或者我们可以再次修补,这样我们就不必将内部规范添加到\NewTblrEnviron使用以下内容定义的每个环境中

\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

相关内容