表の垂直配置: 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

私の意見では、これはバグなので報告する必要があります。せっかちな人のために調整します。幅がゼロでパディングのない列を 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」などが何を行うのか、またこれがオプションの\\引数とどのように関係するのかについて、少なくとも 1 つの基本的な誤解があることを示しています。

「m」トークンではありません利用可能なスペース内で素材を垂直に中央に配置します。

トークン「c」、「l」、「r」は水平セル(1 行の高さ)を生成し、垂直方向の配置ポイントは各セルのベースラインです。次に、「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]最初の列のセルがこれよりも下に行くため、効果はありません。

元の質問とその入力に戻ります。各セルには1行しかないため、すべて一列に並ぶはずですが、「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」の中に 1 本の線しかなく、2ex がベースラインと次の行の間にある場合、「m」と「l」が並んでいることを示しています。

2 行目には、内部に 2 本の線がある「m」があり、ここでも 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]。代わりに、行の 1 つに、通常の深さを だけ拡張した深さを持つ目に見えない罫線/ボックスが配置されます2ex。これを行わないと、垂直方向のスペースを追加した場所で垂直罫線が乱れてしまいます。

この方法の欠点は、列の深さが通常とは異なる場合、余分なスペースは「通常の」深さを基準に測定されるため、足りなくなる可能性があることです。

さらに、これはマテリアルの最後の行にこの見えない支柱を配置する際の「バグ」ですが、m 列は垂直方向に中央揃えされているため、単に間違っています。したがって、ここでは、支柱がではなく のようなarrayに終わるため、「c」が上方向に移動しているのがわかります。$\vcenter{... c \strut}$$\vcenter{... c}$\strut

その理由は、\halign表を作成するために使用される TeX の基本的なメカニズムの奇妙な動作にあります。つまり、 に到達したときに、\\[2ex]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」列を指定したと考えたときに期待していたことではないかもしれません。

アップデート

LaTeX の 2018-04 リリース (または 1 つ前のリリース) の時点で、実際のバグは上記のように修正されました。つまり、(残念ながら) 上記で提案され、正解としてマークされたトリックはもはや機能しませんが、私が説明したように、それは「m」の仕様が何であるかについての誤った仮定に基づいていました。

関連情報