Infelizmente estou com um problemacolunas m( array
pacote) em tabelas comaltura da linha ajustada. De alguma forma noúltima coluna(somente lá) o texto énão centralizadoverticalmente.
Confira:
\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}
Responder1
Na minha opinião, é um bug e deve ser relatado. Ajuste para os impacientes: adicione uma coluna extra com largura zero e sem preenchimento. Lembre-se de pré-anexar \\
nas &
linhas 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}
Responder2
A pergunta, bem como a resposta de @tohecz, indicam que há pelo menos um equívoco fundamental sobre o que os tokens de preâmbulo "m", "b", \\
etc.
O token "m"não écentralizando seu material verticalmente no espaço disponível!
Os tokens "c", "l" e "r" produzem células horizontais (uma linha de altura) e seu ponto de alinhamento vertical é apenas a linha de base de cada célula. Agora "p", "m" e "b" geram células de uma certa largura e possivelmente de várias linhas. Seu alinhamento vertical é a primeira linha, o meio da caixa e a linha inferior, respectivamente. Então, se modificarmos um pouco o exemplo e executarmos:
\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}
e o que obtemos é
Então tudo isso está posicionado em relação à linha de base da célula que contém "d".
Agora, o argumento opcional de \\
apenas estende o espaço do ponto de alinhamento para baixo énãoestendendo o tamanho das células reais. Além disso, não se trata de adicionar esse espaço, mas apenas de garantir que haja pelo menos essa quantidade de espaço na próxima linha. Assim, por exemplo, no caso acima \\[2ex]
não teria efeito porque a célula da primeira coluna desce mais do que isso.
Então, voltando à pergunta original e sua entrada: como cada célula tem apenas uma linha, todas deveriam estar alinhadas, mas o "m" serianãotêm o efeito de centralizar o conteúdo no espaço disponível. Em vez disso, o espaço extra solicitado por \\[2ex]
iria atrás dele (ou deveria ... esse é o bug).
Então vamos adicionar uma coluna "l" para evitar o bug e ver o que acontece:
\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}
O resultado é
A primeira linha mostra que "m" e "l" ficam lado a lado se o "m" tiver apenas uma linha dentro e que o 2ex estiver entre a linha de base e a próxima linha.
A segunda linha tem um "m" com 2 linhas dentro e aí você vê novamente que o 2ex vai da linha de base da linha para a próxima linha e "m" também não está centralizado verticalmente.
Portanto, a sugestão de usar uma linha extra (uma espécie de linha 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}
na verdade está fazendo uso do bug atual, ou seja, o "espaço" naquela pergunta oculta é empurrado para cima para que as linhas visíveis agora apareçam mais ou menos centralizadas (o que tornei visível colocando um "x" acima):
Portanto, no momento em que isso fosse corrigido, o truque acima não funcionaria mais.
Então qual é o bug?
A questão é muito sutil. Para fazer uma tabela com regras funcionar não é possível pular verticalmente para baixo \\[2ex]
, em vez disso o que acontece é que em uma das linhas é colocada uma regra/caixa invisível que tem uma profundidade que se estende pela profundidade normal em 2ex
. Se você não fizer isso, qualquer regra vertical será interrompida em locais onde você adicionar espaço vertical adicional.
A desvantagem disso é que, se uma linha tiver uma profundidade incomum, qualquer espaço extra poderá ficar curto porque é medido em relação à profundidade "normal".
Além disso e esse é o "bug" em array
colocar esse suporte invisual no final do material na última linha, simplesmente dá errado para colunas m, pois elas são centralizadas verticalmente. Portanto, aqui você vê o "c" movendo-se para cima à medida que o suporte termina em algum tipo de $\vcenter{... c \strut}$
em vez de $\vcenter{... c}$\strut
.
A razão para isso é o comportamento estranho do \halign
mecanismo subjacente do TeX que é usado para construir tabelas: quando chegamos \\[2ex]
ao LaTeX já processou, $\vcenter{... c
mas ainda não viu o material restante que forma a coluna, ou seja, }$
.
Então \\[ex]
calcula e adiciona o strut e então diz ao TeX que a coluna está finalizada (usando \cr
internamente) e isso resulta no TeX copiando a parte restante do modelo de coluna ( }$
...mais espaço e regra) no fluxo de entrada e bingo você acaba com o suporte dentro vcenter
.
Uma possível solução seria atrasar o posicionamento das escoras para garantir que isso aconteça apenas na parte direita do modelo de coluna. Isso, por sua vez, é um pouco complicado, pois a essa altura o escopo terá alterado os valores de volta, etc. Portanto, esta precisa ser uma operação 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 eu disse, isso é bastante delicado, então não tenho certeza se é seguro fazer esse tipo de alteração sem quebrar muitas outras coisas (afinal, array
é um pacote muito antigo (mais de 25 anos) que é bastante usado e que a questão está aí desde o início.
De qualquer forma, com a alteração acima, agora temos:
que é o que deveríamos, mas talvez não o que as pessoas esperavam quando pensavam que especificavam uma coluna "m".
Atualizar
A partir da versão 2018-04 do LaTeX (ou mesmo uma versão anterior), o bug real foi corrigido conforme descrito acima. Isso significa (infelizmente) que o truque sugerido acima e marcado como a resposta correta não está mais funcionando, mas como expliquei, foi baseado em uma suposição errada de qual é a especificação de "m".