Desafortunadamente tengo un problema conm-columnas( array
paquete) en tablas conaltura de fila ajustada. De alguna manera en elúltima columna(solo ahí) el texto esno centradoverticalmente.
Échale un vistazo:
\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}
Respuesta1
En mi opinión, es un error y debería informarse. Ajuste para los impacientes: agregue una columna adicional con ancho cero y sin relleno. \\
¡ Recuerde anteponer &
las líneas problemáticas!
\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}
Respuesta2
Tanto la pregunta como la respuesta de @tohecz indican que existe al menos un error fundamental sobre lo que hacen los tokens de preámbulo "m", "b", etc. y cómo se relaciona esto con \\
su argumento opcional.
La ficha "m"no escentrando su material verticalmente en el espacio disponible!
Las fichas "c", "l" y "r" producen celdas horizontales (una línea de alto) y su punto de alineación vertical es solo la línea base de cada celda. Ahora "p", "m" y "b" generan celdas de cierto ancho y posiblemente de varias líneas. Su alineación vertical es la primera línea, la mitad del cuadro y la línea inferior, respectivamente. Entonces si modificamos un poco el ejemplo y ejecutamos:
\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}
y lo que obtenemos es
Entonces, todo esto está ubicado en relación con la línea base de la celda que contiene "d".
Ahora el argumento opcional de \\
solo extiende el espacio desde el punto de alineación hacia abajo.noampliando el tamaño de las celdas reales. Además, en realidad no se trata de agregar este espacio, sino de asegurarse de que haya al menos esa cantidad de espacio para la siguiente fila. Así, por ejemplo, en el caso anterior \\[2ex]
no tendría ningún efecto porque la celda de la primera columna va más abajo que esto.
Entonces, volviendo a la pregunta original y su entrada: debido a que cada celda tiene una sola línea, todas deberían alinearse, pero la "m" seríanotienen el efecto de centrar el contenido en el espacio disponible. En cambio, el espacio adicional solicitado por \\[2ex]
iría después (o debería... ese es el error).
Así que agreguemos una columna "l" para evitar el error y ver qué sucede:
\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}
El resultado es
La primera fila muestra que "m" y "l" están uno al lado del otro si la "m" tiene solo una línea dentro y que el 2ex está entre la línea de base y la siguiente fila.
La segunda línea tiene una "m" con 2 líneas adentro y ahí se vuelve a ver que el 2ex va desde la línea base de la fila a la siguiente fila y la "m" tampoco está centrada verticalmente.
Entonces la sugerencia de usar una fila adicional (una especie de fila oculta) como
\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}
en realidad está haciendo uso del error actual, es decir, el "espacio" en esa pregunta oculta en realidad se empuja hacia arriba de modo que las filas visibles ahora aparecen más o menos centradas (lo que hice visible al colocar una "x" arriba):
Entonces, en el momento en que esto se solucione, el truco anterior ya no funciona.
Entonces, ¿cuál es el error?
La cuestión es muy sutil. Para hacer que una tabla con reglas funcione no es posible saltar verticalmente hacia abajo \\[2ex]
, sino que lo que sucede es que en una de las filas se coloca una regla/cuadro invisible que tiene una profundidad que extiende la profundidad normal en 2ex
. Si no hace esto, cualquier regla vertical sufrirá una interrupción en los lugares donde agregue espacio vertical adicional.
La desventaja de esto es que si una fila tiene una profundidad inusual, cualquier espacio adicional puede quedarse corto porque se mide en relación con la profundidad "normal".
Además, y ese es el "error" al array
colocar este puntal invisible al final del material en la última fila, simplemente sale mal para las columnas m, ya que están centradas verticalmente. Por lo tanto, aquí se ve la "c" moviéndose hacia arriba cuando el puntal termina en una especie de $\vcenter{... c \strut}$
en lugar de $\vcenter{... c}$\strut
.
La razón de esto es el extraño comportamiento del \halign
mecanismo subyacente de TeX que se utiliza para construir tablas: cuando llegamos \\[2ex]
a LaTeX ya ha procesado $\vcenter{... c
pero aún no ha visto el material restante que forma la columna, es decir, }$
.
Entonces \\[ex]
calcula y agrega el puntal y luego le dice a TeX que la columna está terminada (usando \cr
internamente) y eso da como resultado que TeX copie la parte restante de la plantilla de la columna ( }$
...más el espacio y la regla) en el flujo de entrada y bingo, termina con el puntal adentro vcenter
.
Una posible solución sería retrasar la colocación del puntal para garantizar que esto suceda solo en la parte derecha de la plantilla de la columna. Esto, a su vez, es un poco complicado ya que para entonces el alcance habrá cambiado los valores, etc. Por lo tanto, esta debe ser una operación global.
\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}
Como dije, esto es bastante delicado, así que no estoy seguro de que sea seguro hacer ese tipo de cambio sin romper muchas otras cosas (después de todo, array
es un paquete muy antiguo (más de 25 años) que se usa bastante y que El problema está ahí desde el principio.
De todos modos con el cambio anterior ahora obtenemos:
que es lo que deberíamos, pero quizás no lo que la gente esperaba cuando pensaban especificar una columna "m".
Actualizar
A partir de la versión 2018-04 de LaTeX (o incluso una versión anterior), el error real se ha corregido como se describe anteriormente. Eso significa (desafortunadamente) que el truco sugerido anteriormente y marcado como la respuesta correcta ya no funciona, pero como expliqué se basó en una suposición errónea de cuál es la especificación de "m".