Leider habe ich ein Problem mitM-Spalten( array
Paket) in Tabellen mitZeilenhöhe angepasst. Irgendwie in derletzte Spalte(nur dort) der Text istnicht zentriertvertikal.
Hör zu:
\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}
Antwort1
Meiner Meinung nach handelt es sich um einen Fehler, der gemeldet werden sollte. Ein Tipp für Ungeduldige: Fügen Sie eine zusätzliche Spalte mit der Breite Null und ohne Polsterung hinzu. Denken Sie daran , den problematischen Zeilen ein „ \\
mit“ voranzustellen !&
\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}
Antwort2
Sowohl die Frage als auch die Antwort von @tohecz weisen darauf hin, dass zumindest ein grundlegendes Missverständnis darüber besteht, was die Präambel-Token „m“, „b“ usw. bewirken und wie sich dies auf \\
ihr optionales Argument bezieht.
Das „m“-Tokenist nichtZentrieren Sie das Material vertikal im verfügbaren Raum!
Die Token "c", "l" und "r" erzeugen horizontale Zellen (eine Zeile hoch) und ihr vertikaler Ausrichtungspunkt ist einfach die Grundlinie jeder Zelle. Nun erzeugen "p", "m" und "b" Zellen einer bestimmten Breite und möglicherweise mehrerer Zeilen. Ihre vertikale Ausrichtung ist jeweils die erste Zeile, die Mitte der Box und die unterste Zeile. Ändern wir also das Beispiel ein wenig und führen es aus:
\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}
und was wir bekommen ist
Dies wird also alles relativ zur Grundlinie der Zelle positioniert, die „d“ enthält.
Das optionale Argument \\
erweitert nun nur den Abstand vom Ausrichtungspunkt nach unten.nichtdie Größe der eigentlichen Zellen erweitern. Außerdem wird dieser Platz nicht wirklich hinzugefügt, sondern nur sichergestellt, dass zur nächsten Zeile mindestens so viel Platz vorhanden ist. Im obigen Fall \\[2ex]
hätte dies beispielsweise keine Auswirkung, da die Zelle in der ersten Spalte weiter nach unten geht.
Kommen wir also zurück zur ursprünglichen Frage und ihrer Eingabe: Da jede Zelle nur eine einzige Linie hat, sollten sie alle in einer Reihe stehen, aber das "m" würdenichthat den Effekt, dass der Inhalt im verfügbaren Platz zentriert wird. Stattdessen \\[2ex]
würde der von angeforderte zusätzliche Platz dahinter stehen (oder sollte ... das ist der Fehler).
Fügen wir also eine Spalte „l“ hinzu, um den Fehler zu vermeiden, und sehen wir, was passiert:
\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}
Ergebnis ist
Die erste Reihe zeigt, dass „m“ und „l“ nebeneinander stehen, wenn das „m“ nur aus einem Strich besteht und das 2ex zwischen der Grundlinie und der nächsten Reihe liegt.
Die zweite Zeile hat ein „m“ mit 2 Strichen darin und dort sieht man wieder, dass die 2ex von der Zeilengrundlinie zur nächsten Zeile geht und das „m“ auch nicht vertikal zentriert ist.
Der Vorschlag, eine zusätzliche (eine Art versteckte Zeile) zu verwenden, wie
\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}
nutzt tatsächlich den aktuellen Fehler aus, d. h. der „Raum“ in dieser versteckten Frage wird tatsächlich nach oben verschoben, sodass die sichtbaren Zeilen nun mehr oder weniger zentriert erscheinen (was ich durch Einfügen eines „x“ oben sichtbar gemacht habe):
Sobald dies behoben ist, funktioniert der obige Trick nicht mehr.
Also, was ist der Fehler?
Das Problem ist sehr subtil. Damit eine Tabelle mit Regeln funktioniert, ist es nicht möglich, vertikal nach unten zu springen \\[2ex]
. Stattdessen wird in einer der Zeilen eine unsichtbare Regel/Box platziert, deren Tiefe die normale Tiefe um überschreitet 2ex
. Wenn Sie dies nicht tun, wird jede vertikale Regel an den Stellen unterbrochen, an denen Sie zusätzlichen vertikalen Platz hinzufügen.
Der Nachteil dabei ist, dass bei einer ungewöhnlichen Tiefe einer Reihe dieser zusätzliche Platz möglicherweise zu kurz kommt, da er im Verhältnis zur „normalen“ Tiefe gemessen wird.
Außerdem – und das ist der „Fehler“ – geht es bei der Platzierung dieser unsichtbaren Strebe am Ende des Materials in der letzten Reihe einfach schief, da diese vertikal zentriert sind. Daher sehen Sie hier, wie sich das „c“ nach oben bewegt, da die Strebe in einer Art statt array
endet .$\vcenter{... c \strut}$
$\vcenter{... c}$\strut
Der Grund hierfür ist das seltsame Verhalten des zugrunde liegenden \halign
Mechanismus von TeX, der zum Erstellen von Tabellen verwendet wird: Wenn wir ankommen, \\[2ex]
hat LaTeX $\vcenter{... c
das verbleibende Material, das die Spalte bildet, zwar verarbeitet, aber noch nicht gesehen, d. h. }$
.
Berechnet und fügt also \\[ex]
die Strebe hinzu und teilt TeX dann mit, dass die Spalte fertig ist (wird \cr
intern verwendet), und das führt dazu, dass TeX den verbleibenden Teil der Spaltenvorlage ( }$
... plus Leerzeichen und Regel) in den Eingabestrom kopiert, und Bingo, Sie haben am Ende die Strebe darin vcenter
.
Eine mögliche Lösung wäre, die Platzierung der Streben zu verzögern, um sicherzustellen, dass dies nur im rechten Teil der Spaltenvorlage geschieht. Das wiederum ist etwas knifflig, da bis dahin die Gültigkeitsbereiche die Werte wieder geändert haben usw. Dies muss also eine globale Operation sein.
\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}
Wie gesagt, das ist eine ziemlich heikle Angelegenheit, daher bin ich mir nicht sicher, ob es sicher ist, derartige Änderungen vorzunehmen, ohne eine Menge anderer Dinge kaputt zu machen (schließlich handelt es array
sich um ein wirklich altes Paket (über 25 Jahre), das ziemlich oft verwendet wird, und dieses Problem besteht von Anfang an).
Wie dem auch sei, mit der obigen Änderung erhalten wir jetzt:
das ist, was wir tun sollten, aber vielleicht nicht, was die Leute erhofft haben, als sie dachten, sie würden eine „m“-Spalte angeben.
Aktualisieren
Ab der 2018-04-Version von LaTeX (oder sogar einer Version früher) wurde der eigentliche Fehler nun wie oben beschrieben behoben. Das bedeutet (leider), dass der oben vorgeschlagene und als richtige Antwort markierte Trick nicht mehr funktioniert, aber wie ich erklärt habe, basierte er auf einer falschen Annahme der Spezifikation von „m“.