# Vertical alignment with multirow in tabularx

I have looked around for a solution that allows me to vertically centrally align a multirow row that spans two intermediate rows, which potentially span multiple lines since the tabular environment is tabularx.

Some other questions that don't quite get to the solution are here, here, and here. These solutions use the fixup parameter to multirow that I really would not like to use, or they are not quite applicable to my case.

So, to give an example

\documentclass{article}
\usepackage{tabularx, multirow, booktabs, lipsum}
\begin{document}

\begin{table}[ht]
\begin{tabularx}{\textwidth}{XXX}
\toprule
a & the first very, very, very, very, very, very, very, very, very, very, very long line. & a \\
\multirow{2}{*}{b} & a very, very, very, very, very, very, very, very, very, very, very long line. & \multirow{2}{*}{b} \\
& another very, very, very, very, very, very, very, very, very, very, very long line. &  \\
\bottomrule
\end{tabularx}
\end{table}
\end{document}


I would like the "b"s to be vertically centrally aligned. I am not tied in any way to multirow, but I am to tabularx and would very much prefer an automatic solution.

-
What do you mean that you are not "tied in any way to multirow"? If you are just after centering the text vertically as well as horizontally in each cell (not in multirow cells), then \renewcommand{\tabularxcolumn}[1]{>{\arraybackslash}m{#1}} will work. Then you can also define a new column type for horizontal centering. –  hpesoj626 Oct 17 '12 at 7:37
Well, not tied in any way to multirow means that if some other package can be used (as I got the impression from the other solutions) to achieve the outcome, then that is fine. Your solution would not center it to both the cells, right? –  fg nu Oct 17 '12 at 7:41
I'm sorry. I am lost. I don't know of a package that does what the multirow package does. But I might be mistaken. –  hpesoj626 Oct 17 '12 at 7:46
multirow enables one to write text that spans several rows. As explained by @Philipp in his answer here, "multirow is not capable of a correct vertical alignment, if it spans multi-line cells" –  hpesoj626 Oct 17 '12 at 7:53
I am not claiming that such a package exists. I am saying that if it did, I would abandon multirow in its favor. A number of the other solutions linked in the main question do just that, build solutions which do not require the use of the multirow package. –  fg nu Oct 17 '12 at 7:53

## 1 Answer

This is using a pdftex primitive but it or similar are available in other engines. It takes a couple of runs to settle down and assumes that the spanning rows are bigger than the entry being placed in the span (if the text in \centerbetween is to big it will overprint surrounding text with no warning). The \advance\dimen@\ht\strutbox factor in the code may need adjusting for your visual vertical centering. Without it it centers the middle of the text box between the top and bottom _baseline_s of the spanning rows which isn't usually quite what you want.

\documentclass{article}
\usepackage{tabularx, multirow, booktabs, lipsum}
\begin{document}

\makeatletter
\def\savepos#1{\pdfsavepos\write\@auxout{%
\gdef\expandafter\string\csname savepos@#1@x\endcsname{\the\pdflastxpos}^^J%
\gdef\expandafter\string\csname savepos@#1@y\endcsname{\the\pdflastypos}}}

\def\centerbetween#1#2#3{%
\expandafter\ifx\csname savepos@#1@x\endcsname\relax
\dimen@\z@
\else
\dimen@\csname savepos@#2@y\endcsname sp %
\advance\dimen@-\csname savepos@#1@y\endcsname sp %
\advance\dimen@\ht\strutbox
\fi
\smash{\raisebox{\dimen@}{\parbox[c]{\hsize}{#3}}}}
\makeatother

\begin{table}[ht]
\begin{tabularx}{\textwidth}{XXX}
\toprule
a & the first very, very, very, very, very, very, very, very, very, very, very long line. & a \\
\strut\savepos{a}%
\centerbetween{a}{b}{bbb}
& a very, very, very, very, very, very, very, very, very, very, very long line. &
\centerbetween{a}{b}{ccc} \\
\vfill\strut\savepos{b}
& another very, very, very, very, very, very, very, very, very, very, very long line. &  \\
\bottomrule
\end{tabularx}
\end{table}
\end{document}

-