nicematrix 的奇怪居中行为

nicematrix 的奇怪居中行为

使用该包,nicematrix我尝试创建一个NiceTabular能够使用块的程序。在此过程中,我进行了一些有趣/奇怪的观察。

我意识到的第一件事是:块和规则不适合在一起,正如您在以下结果中看到的那样:

在此处输入图片描述

只有一个站点符合规则,另一个站点则走得太远了。

到目前为止,一切都很好。

在我看来,奇怪的行为发生在我查看这些块内的居中时:水平标题不是以其块为中心,而是以 为中心\cmidrule。很好,这很好。但相反,垂直标题不是以其为中心,\vrule而是以块边界为中心。

为了形象化地展示这一点,我用一些比较字符串替换了“标题”这个词,并画了一些线条。

在此处输入图片描述

结果,水平标题完全按照预期居中,但垂直居中有点太低。它也应该根据 vrule 居中。

为什么会有这种差异?我怎样才能使垂直居中也符合规则?谢谢!:)

这是我的复现代码:

\documentclass{scrreprt}

\usepackage{booktabs}
\usepackage{makecell}
\usepackage{nicematrix}
\newcommand{\nicewidth}{\dimexpr .13333\textwidth-2\tabcolsep}
\renewcommand\theadfont{\bfseries}

\begin{document}

\begin{minipage}[t]{.5\textwidth}
  \centering
  \begin{NiceTabular}{@{}wc{\nicewidth}!{\vrule}*{4}{wc{\nicewidth}}@{}}
    \toprule
    \multicolumn{2}{c}{} & \Block[fill=red!15]{1-*}{\thead{Headings}} \\
    \cmidrule(l){3-5}
    \multicolumn{2}{c}{} & \thead{X} & \thead{Y} & \thead{Z} \\
    \Block[fill=red!15]{*-1}{\rotate\thead{Headings}}& \thead{A} & ax & ay & az \\
    & \thead{B} & bx & by & bz \\
    & \thead{C} & cx & cy & cz \\
    & \thead{D} & dx & dy & dz \\
    \bottomrule
  \end{NiceTabular}
\end{minipage}
\begin{minipage}[t]{.5\textwidth}
  \centering
  \begin{NiceTabular}{@{}wc{\nicewidth}!{\vrule}*{4}{wc{\nicewidth}}@{}}
    \toprule
    \multicolumn{2}{c}{} & \Block[fill=red!15]{1-*}{\thead{--------.--------}} \\
    \cmidrule(l){3-5}
    \multicolumn{2}{c}{} & \thead{X} & \thead{Y} & \thead{Z} \\
    \Block[fill=red!15]{*-1}{\rotate\thead{---------.---------}}& \thead{A} & ax & ay & az \\
    & \thead{B} & bx & by & bz \\
    & \thead{C} & cx & cy & cz \\
    & \thead{D} & dx & dy & dz \\
    \bottomrule
  \end{NiceTabular}
\end{minipage}

\end{document}

答案1

(我是该包的作者nicematrix)。


关于规则。

  • 在 中绘制垂直规则的标准方法{NiceTabular}是使用|前言中的说明符。在 中,此说明符被重新定义(与的{NiceTabular}标准相比),并且规则由 PGF/Tikz 绘制。此类规则旨在与 的水平规则兼容(见图)。另一方面,如果您在 中放入前言(如您所做),则说明符的标准定义与 不兼容(但是,本着 的精神,永远不要使用垂直规则...)。|{tabular}booktabs!{\vrule}|{tabular}booktabsbooktabs

  • 关于水平规则,您已输入。该命令的\cmidrule(l){3-5}选项(它是 的命令)缩短了左侧的规则。因此,您的输出并不令人意外。(l)cmidrulebooktabs

以下是经过这两项修正后的输出。

第一个表格


关于块中标签的位置。

您遇到的问题源于@{}您在序言两侧所给出的说明。

\begin{NiceTabular}{@{}wc{\nicewidth}!{\vrule}*{4}{wc{\nicewidth}}@{}}

如果没有这些说明,标签的位置就不那么令人惊讶了。

第二个表格

这些发生了什么事@{}

  • 关于水平单词“标题”,nicematrix倾向于根据相应列中的文本将该文本居中(这是不是根据 居中\cmidrule):当块未填充时,输出看起来很完美。我同意,当块已填充时,结果可能看起来令人失望。

  • 关于垂直单词“标题”,序言开头的 的存在@{}导致水平位置不在块的中心。但这似乎并不困扰你(因为你没有提到这一点)。关于垂直位置,它与块边界相对应,正如你所说:它没有以你绘制的垂直规则为中心,因为你绘制的垂直规则不符合 的精神{NiceTabular}{NiceTabular}应该在序言中绘制符合精神的垂直规则|,而不是!{\vrule})。


\documentclass{scrreprt}

\usepackage{booktabs}
\usepackage{makecell}
\usepackage{nicematrix}
\newcommand{\nicewidth}{\dimexpr .13333\textwidth-2\tabcolsep}
\renewcommand\theadfont{\bfseries}

\begin{document}

\begin{minipage}[t]{.5\textwidth}
  \centering
  \begin{NiceTabular}{@{}wc{\nicewidth}|*{4}{wc{\nicewidth}}@{}}
    \toprule
    \multicolumn{2}{c}{} & \Block[fill=red!15]{1-*}{\thead{Headings}} \\
    \cmidrule{3-5}
    \multicolumn{2}{c}{} & \thead{X} & \thead{Y} & \thead{Z} \\
    \Block[fill=red!15]{*-1}{\rotate\thead{Headings}}& \thead{A} & ax & ay & az \\
    & \thead{B} & bx & by & bz \\
    & \thead{C} & cx & cy & cz \\
    & \thead{D} & dx & dy & dz \\
    \bottomrule
  \end{NiceTabular}
\end{minipage}

\vspace{2cm}

\begin{minipage}[t]{.5\textwidth}
  \centering
  \begin{NiceTabular}{wc{\nicewidth}|*{4}{wc{\nicewidth}}}
    \toprule
    \multicolumn{2}{c}{} & \Block[fill=red!15]{1-*}{\thead{Headings}} \\
    \cmidrule{3-5}
    \multicolumn{2}{c}{} & \thead{X} & \thead{Y} & \thead{Z} \\
    \Block[fill=red!15]{*-1}{\rotate\thead{Headings}}& \thead{A} & ax & ay & az \\
    & \thead{B} & bx & by & bz \\
    & \thead{C} & cx & cy & cz \\
    & \thead{D} & dx & dy & dz \\
    \bottomrule
  \end{NiceTabular}
\end{minipage}

\end{document}

答案2

@F. 潘蒂尼

我知道你booktabs根本不喜欢 vrules,这是可以理解的。但对我来说,我使用的垂直线更像是标题的旋转下划线,而不是列的垂直分隔。一种旋转\cmidrule。这就是我想要这个的原因。

这也是为什么我不想让 vrule 接触 bottomrule 的原因。我想保留一个小间隙,因为它不是列分隔,而是一种下划线。所以我故意使用了!{\vrule}insted |

因此,我需要一个解决方案来解决这个问题。在规则之间留出一个小间隙,并保持内容以规则为中心。

我找到了一个解决方法,因为我保留了,!{vrule}但向行标题添加了一些\hspace*{\aboverulesep}。这给了我间隙,并且标题居中(是吗?):

\begin{NiceTabular}{wc{\nicewidth}!{\vrule}*{4}{wc{\nicewidth}}}
  \toprule
  \multicolumn{2}{c}{} & \Block{1-*}{\thead{--------.--------}} \\
  \cmidrule{3-5}
  \multicolumn{2}{c}{} & \thead{X} & \thead{Y} & \thead{Z} \\
  \Block{*-1}{\rotate{\hspace*{\aboverulesep}\thead{---------.---------}}} & \thead{A} & ax & ay & az \\
  & \thead{B} & bx & by & bz \\
  & \thead{C} & cx & cy & cz \\
  & \thead{D} & dx & dy & dz \\
  \bottomrule
\end{NiceTabular}

在此处输入图片描述

但我认为这不是一个干净的“解决方案”,因为使用这种方法我只调整了 vrule 和标题位置,但没有调整表格本身的内容。所以我猜一定存在一些不均衡。

这就引出了一个问题:是否nicematrix有更好的方法来获得表格内容和\bottomrule(和/或\toprule)之间的间隙。一种干净的方法来降低底部规则,而无需以相同的方式扩展块,以便底部规则和表格的最后一个块之间有间隙。

这样你就不必再担心居中问题了,因为你不必操纵 vrules 或标题位置。但是该怎么做呢?

这张(经过处理的)图像展示了我的想法:(现在我再次使用填充块,只是为了使块及其边界可见。)

在此处输入图片描述

答案3

@Max16hr,

作为对您的回答的回答,我试图编写一些程序来做您想做的事情(不修改nicematrix也不使用的内部结构nicematrix)。

使用\TopRuleand\BottomRule代替\topruleand \bottomrule

\documentclass{scrreprt}

\usepackage{booktabs}
\usepackage{nicematrix}
\usepackage{makecell}
\newcommand{\nicewidth}{\dimexpr .13333\textwidth-2\tabcolsep}
\renewcommand\theadfont{\bfseries}
\usepackage{tikz}


\ExplSyntaxOn
\makeatletter

\NewDocumentCommand { \TopRule } { }
  { \tl_gput_right:Nn \g_nicematrix_code_after_tl { \__max_TopRule: } }

\cs_new_protected:Npn \__max_TopRule: 
  {
    \begin{tikzpicture}
    \draw [line~width = \heavyrulewidth] 
     ([yshift=\aboverulesep]row-1-|col-1) 
      -- ([yshift=\aboverulesep]row-1-|col- \int_eval:n { \c@jCol + 1 } ) ;
    \end{tikzpicture}
  }

\NewDocumentCommand { \BottomRule } { } 
  { \tl_gput_right:Nn \g_nicematrix_code_after_tl { \__max_BottomRule: } }

\cs_new_protected:Npn \__max_BottomRule: 
  {
    \begin{tikzpicture}
    \draw [line~width = \heavyrulewidth] 
    ([yshift=-\belowrulesep]row - \int_eval:n { \c@iRow + 1 } -|col-1) 
    -- ([yshift=-\belowrulesep]row- \int_eval:n { \c@iRow + 1 } -|col- \int_eval:n { \c@jCol + 1} ) ;
    \end{tikzpicture}
  }

\makeatother
\ExplSyntaxOff

\begin{document}

\begin{minipage}[t]{.5\textwidth}
\centering
\begin{NiceTabular}{@{}wc{\nicewidth}|*{4}{wc{\nicewidth}}@{}}
\TopRule
\Block{2-2}{} & & \Block[fill=red!15]{1-*}{\thead{--------.--------}} \\
\cmidrule(l){3-5}
              & & \thead{X} & \thead{Y} & \thead{Z} \\
\Block[fill=red!15]{*-1}{\rotate\thead{--------.--------}}& \thead{A} & ax & ay & az \\
& \thead{B} & bx & by & bz \\
& \thead{C} & cx & cy & cz \\
& \thead{D} & dx & dy & dz 
\BottomRule
\end{NiceTabular}
\end{minipage}

\end{document}

上述代码的输出

不过,我有一些意见。

  • \TopRule\Bottomrule由 Tikz 在 之外绘制的{minipage}

  • 该命令\TopRule不可扩展,这就是为什么您不能\multicolumn在 之后放置\TopRule。这就是我所做的更改,我使用了\Block(尽管如此,这更符合 的精神nicematrix)。

  • 当然,我|在序言中为垂直规则使用了标准说明符,因为使用!{\rule}只是为了使垂直规则不与接触的一种解决方法\bottomrule

  • 你必须不是将 a 放在\\之前的最后一行\BottomRule

答案4

好吧,我终于有了一个我喜欢的解决方案:) 居中标题,顶部/底部规则和表格内容之间的间隙(大小相同)以及几乎符合规则的框。

\documentclass{scrreprt}

\usepackage{booktabs}
\usepackage{makecell}
  \renewcommand\theadfont{\bfseries}
\usepackage{nicematrix}
  \setlength\belowrulesep{\aboverulesep}
  \newcommand{\nicewidth}{\dimexpr .128\textwidth-2\tabcolsep}

\begin{document}

\begin{minipage}[t]{.48\textwidth}
  \centering
  \begin{tabular}{@{}c@{}}
    \toprule
    \begin{NiceTabular}{wc{\nicewidth}|*{4}{wc{\nicewidth}}}
      \multicolumn{2}{c}{} & \Block{1-*}{\thead{Headings}} \\[-\aboverulesep]
      \cmidrule{3-5}
      \multicolumn{2}{c}{} & \thead{X} & \thead{Y} & \thead{Z} \\
      \Block{*-1}{\rotate\thead{Headings}} & \thead{A} & ax & ay & az \\
      & \thead{B} & bx & by & bz \\
      & \thead{C} & cx & cy & cz \\
      & \thead{D} & dx & dy & dz
    \end{NiceTabular} \\
    \bottomrule
  \end{tabular}
\end{minipage}
\hfill
\begin{minipage}[t]{.48\textwidth}
  \centering
  \begin{tabular}{@{}c@{}}
    \toprule
    \begin{NiceTabular}{wc{\nicewidth}|*{4}{wc{\nicewidth}}}
      \multicolumn{2}{c}{} & \Block[fill=red!15]{1-*}{\thead{--------.--------}} \\[-\aboverulesep]
      \cmidrule{3-5}
      \multicolumn{2}{c}{} & \thead{X} & \thead{Y} & \thead{Z} \\
      \Block[fill=red!15]{*-1}{\rotate\thead{---------.---------}} & \thead{A} & ax & ay & az \\
      & \thead{B} & bx & by & bz \\
      & \thead{C} & cx & cy & cz \\
      & \thead{D} & dx & dy & dz
    \end{NiceTabular} \\
    \bottomrule
  \end{tabular}
\end{minipage}

\end{document}

在此处输入图片描述

只剩下一个问题:垂直框似乎没有与垂直规则完美贴合。顶部贴合得很好,但底部贴合不好。似乎有一个小悬垂。也许这是一个小错误nicematrix

再次感谢@F. Pantigny 的大力帮助!

相关内容