[Tex/LaTex] Vertical alignment with multirow in tabularx

multirowtablestabularx

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.

Best Answer

enter image description here

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}
Related Question