表中的垂直對齊:m 列,行大小 - 最後一列的問題

表中的垂直對齊:m 列,行大小 - 最後一列的問題

不幸的是,我有一個問題m 列array包)在表中調整後的行高。不知何故在最後一欄(僅在那裡)文本是不居中垂直。

一探究竟:

在此輸入影像描述

\documentclass{article}
\usepackage{array}

\begin{document}

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|}
\hline
a & b & c  \\[2ex]
\hline
0 & 0 & 0  \\
\hline
\end{tabular}

\end{document}

答案1

在我看來,這是一個錯誤,應該要報告。針對不耐煩的情況進行調整:新增一列寬度為零且無填滿的額外欄位。請記住\\&有問題的行前面添加!

\documentclass{article}
\usepackage{array}

\begin{document}

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|@{}m{0pt}@{}}
\hline
a & b & c &\\[2ex]
\hline
0 & 0 & 0 \\
\hline
\end{tabular}

\end{document}

答案2

這個問題以及 @tohecz 的回答表明,對於前導碼標記“m”、“b”等的作用以及其\\與它的可選參數的關係,至少存在一個基本的誤解。

“m”標記不是將其材料垂直居中於可用空間!

標記「c」、「l」和「r」產生水平單元格(一行高),它們的垂直對齊點就是每個單元格的基線。現在「p」、「m」和「b」產生一定寬度的儲存格,並且可能有幾行。它們的垂直對齊方式分別是第一行、框的中間和底線。因此,如果我們稍微修改一下範例並運行:

\begin{tabular}{|p{0.18cm}|m{0.18cm}|b{0.18cm}|l|}
\hline
a\newline a & b\newline b & c\newline c\newline c& d \\
\hline
\end{tabular}

我們得到的是

在此輸入影像描述

所以這都是相對於包含“d”的單元格的基線定位的。

現在,可選參數\\僅從對齊點向下擴展空間,它是不是擴展實際單元格的大小。此外,它實際上並沒有添加這個空間,而只是確保下一行至少有那麼多的空間。例如,在上述情況下\\[2ex]不會有任何影響,因為第一列中的儲存格比這更向下。

所以回到原來的問題及其輸入:因為每個單元格只有一行,所以它們應該全部排成一行,但「m」會不是具有將內容集中在可用空間的中心的效果。相反,所請求的額外空間\\[2ex]將在它之後(或應該......這就是錯誤)。

因此,讓我們新增一個「l」列來避免該錯誤,看看會發生什麼:

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|l|}
\hline
a & b & c & d \\[2ex]
\hline
a\newline a & b & c & d \\[2ex]
\hline
\end{tabular}

結果是

在此輸入影像描述

第一行顯示,如果「m」內部只有一行且 2ex 位於基線和下一行之間,則「m」和「l」並排放置。

第二行有一個“m”,裡面有 2 條線,您再次看到 2ex 從行基線到下一行,並且“m”也不是垂直居中的。

因此建議使用額外的(某種隱藏行),例如

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|@{}m{0pt}@{}}
\hline
a & b & c &             x\\[4ex]   % x normally being a space
\hline
a\newline a & b & c &   x\\[4ex]
\hline
\end{tabular}

實際上是在利用當前的錯誤,即隱藏問題中的“空間”實際上被向上推,以便可見的行現在或多或少地顯得居中(我通過在上面放入“x”使其可見):

在此輸入影像描述

因此,一旦這個問題得到解決,上述技巧就不再運作了。

那麼問題是什麼?

這個問題非常微妙。為了使帶有規則的表格起作用,不可能在 上垂直向下跳躍\\[2ex],而是在其中一行中放置了一個不可見的規則/框,其深度將正常深度擴展了2ex。如果您不這樣做,那麼任何垂直規則都會在您添加額外垂直空間的地方受到干擾。

這樣做的缺點是,如果一行具有不尋常的深度,則任何此類額外空間都可能會不足,因為它是相對於“正常”深度進行測量的。

此外,這就是array將這種不可見的支柱放在最後一行材料末尾的“錯誤”,對於 m 列來說只是錯誤的,因為它們是垂直居中的。因此,在這裡您可以看到“c”向上移動,因為支柱最終以某種形式$\vcenter{... c \strut}$而不是$\vcenter{... c}$\strut

原因是\halign用於建立表格的 TeX 底層機制的奇怪行為:當我們到達\\[2ex]LaTeX 時,LaTeX 已處理$\vcenter{... c但尚未看到形成列的剩餘材料,即}$

因此,\\[ex]計算並添加支柱,然後告訴 TeX 該列已完成(\cr內部使用),這會導致 TeX 將列模板的剩餘部分(}$...加上空格和規則)複製到輸入流中,最終得到結果與裡面的支柱vcenter

一種可能的解決方法是延遲支柱放置,以確保這種情況僅發生在柱模板的右側部分。這反過來又有點棘手,因為到那時範圍界定會改變值等。

\documentclass{article}
\usepackage{array}

\makeatletter
\def\@classz{\@classx
   \@tempcnta \count@
   \prepnext@tok
   \@addtopreamble{\ifcase \@chnum
      \hfil
      \d@llarbegin
      \insert@column
      \d@llarend\fmi@fix \hfil \or
      \hskip1sp\d@llarbegin \insert@column \d@llarend\fmi@fix \hfil \or
      \hfil\hskip1sp\d@llarbegin \insert@column \d@llarend\fmi@fix \or
   $\vcenter
   \@startpbox{\@nextchar}\insert@column \@endpbox $\fmi@fix
    \or
   \vtop \@startpbox{\@nextchar}\insert@column \@endpbox\fmi@fix \or
   \vbox \@startpbox{\@nextchar}\insert@column \@endpbox\fmi@fix
  \fi}\prepnext@tok}

\def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
   \let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
   \let\fmi@fix\relax
   \@temptokena{#1}\@tempswatrue
   \@whilesw\if@tempswa\fi{\@tempswafalse\the\NC@list}%
   \count@\m@ne
   \let\the@toks\relax
   \prepnext@tok
   \expandafter \@tfor \expandafter \@nextchar
    \expandafter :\expandafter =\the\@temptokena \do
   {\@testpach
   \ifcase \@chclass \@classz \or \@classi \or \@classii
     \or \save@decl \or \or \@classv \or \@classvi
     \or \@classvii \or \@classviii
     \or \@classx
     \or \@classx \fi
   \@lastchclass\@chclass}%
   \ifcase\@lastchclass
   \@acol \or
   \or
   \@acol \or
   \@preamerr \thr@@ \or
   \@preamerr \tw@ \@addtopreamble\@sharp \or
   \or
   \else  \@preamerr \@ne \fi
   \def\the@toks{\the\toks}}   


\def\@xargarraycr#1{\gdef\fmi@fix
 {\@tempdima #1\advance\@tempdima \dp\@arstrutbox
  \vrule \@depth\@tempdima \@width\z@\global\let\fmi@fix\relax}\cr}
\let\fmi@fix\relax

\makeatother

\begin{document}

\begin{tabular}{|m{0.18cm}|m{0.18cm}|}
\hline
a&c \\[2ex]
\hline
0& 0  \\
\hline
\end{tabular}

\end{document}

正如我所說,這是相當微妙的,所以我不確定在不破壞很多其他東西的情況下進行這種類型的更改是否安全(畢竟array是一個非常舊的軟體包(25 年以上),使用了很多而且問題從一開始就在那裡。

無論如何,透過上述更改,我們現在得到:

在此輸入影像描述

這是我們應該做的,但也許不是人們在認為指定了“m”列時所希望的。

更新

截至 2018 年 4 月發布的 LaTeX(甚至更早的一個版本),實際錯誤現已按照上面的概述得到糾正。這意味著(不幸的是)上面建議的並標記為正確答案的技巧不再起作用,但正如我所解釋的,它是基於對“m”的規範是什麼的錯誤假設。

相關內容