Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Unfortunatly, I have a problem with m-columns (array package) in tables with adjusted row height. Somehow in the last column (only there) the text is not centered vertically.

Check it out:

enter image description here

\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}
share|improve this question
add comment

2 Answers

up vote 15 down vote accepted

In my opinion, it is a bug and should be reported. Tweak for the impatient: add one extra column with zero width and no padding. Remember to pre-pend \\ with & on the problematic lines!

\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}
share|improve this answer
    
Do you know if the bug was reported? How is it's status? –  student Oct 18 '12 at 17:36
    
@student I was not reporting it so I have no clue. –  tohecz Oct 18 '12 at 17:37
2  
add comment

I guess you can call this a bug :-), but the issue is very subtle. To make a table with rules work it is not possible to vertically skip downwards on \\[2ex], instead what happens is that in one of the row an invisible rule/box is placed that has a depth extending the normal depth by 2ex. If you don't do this then any vertical rule gets a disruption in places where you add additional vertical space.

The downside of this is, that if a row has an unusual depth, any such exstra space may come out short because it is measured in relation to the "normal" depth.

In addition and that is the "bug" in array putting this invisual strut at the end of the material in the last row, simply goes wrong for m-columns as they are vertically centered. Thus here you see the "c" moving upwards as the strut ends up in some sort of $\vcenter{... c \strut}$ instead of $\vcenter{... c}$\strut.

The reason for this is the strange behavior of the underlying \halign mechanism of TeX that is used to build tables: when we reach \\[2ex] LaTeX has processed $\vcenter{... c but not yet seen the remaining material that forms the column, i.e., }$.

So \\[ex] calculates and adds the strut and then tells TeX that the column is finished (using \crinternally) and that results in TeX copying the remaining part of the column template (`}$...plus space and rule) into the input stream and bingo you end up with the strut inside vcenter.

A possible fix would be to delay the strut placement to ensure that this happens only in the right part of the column template. That in turn is a bit tricky as by that time scoping will have changed values back etc. So this needs to be a global operation.

\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}

As I said this is rather delicate so I'm not sure it is safe to make that type of change without breaking a lot of other stuff (after all array is a really old package (25+ years) which is used quite a lot and that issue is in there from the beginning.

Anyway with the above change we now get:

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.