1

On 2013 I did ask this question and was answered, but implementing on another code I've new issues not presented before.

I have a three column tabularx in which two of them are l, r or c and the middle column is an X column. If the X column takes more than one line, the desired behavior is that the first column (say the l column) to be top aligned (in the same row as the first line of the X column, and the third column to be bottom aligned (in the same row as the last line of X column). The blank columns are filled with something like a \cdot.

The original post is available at [1]; the solution provided by David Carlisle involved new commands to take measurements and to put the text in the desired positions: \xleft, \xright, \xstart, \xend and \xpad. It worked perfectly until now.

  1. If cells on the first and third columns contains more than one character of text, the filled cells will be aligned horizontally to the beginning/end of the text on the other cells involved instead of being centered, that is the desired appearance.
  2. The use of \hbox to print the contents of the cells inhibits the use of stretchable spaces like \hfill, and one cell on the right column must have the pattern text\hfill text to expand the space between the two words until the column width (taken from the longer cell, in my case the column title).

The following code is the solution by David Carlisle exemplified to show what I want now:

\documentclass{article}
\usepackage{tabularx}

\makeatletter
\def\savepos#1{\leavevmode\pdfsavepos\write\@auxout{%
\gdef\noexpand#1{\the\pdflastypos sp }}}

\def\xstart#1{\expandafter\savepos\csname save@start@#1\endcsname}
\def\xend#1{\expandafter\savepos\csname save@end@#1\endcsname}
\def\xpad#1#2#3{%
\vtop{%
\baselineskip\normalbaselineskip
#2%
\expandafter\ifx\csname save@start@#1\endcsname\relax
\else
\dimen@\csname save@start@#1\endcsname\relax
\loop
\ifdim\dimen@>\csname save@end@#1\endcsname
\advance\dimen@-\baselineskip
\hbox{$\cdot$}%
\repeat
\fi
#3%
}}
\def\xleft#1#2{\xpad{#1}{\hbox{#2}}{}}
\def\xright#1#2{\xpad{#1}{}{\hbox{#2}}}

\begin{document}
\begin{tabularx}{5cm}{cXr}
title 1 & title 2 & title 3 \\

 \xleft{a}{7890} & \xstart{a}qwer asdf zxcv qwer 
    asdf zxcv qwer asdf
    zxcv\xend{a} & \xright{a}{1} \\
 \xleft{b}{50} & \xstart{b}qwer asdf zxcv\xend{b} & \xright{b}{A\hfill1} \\
 90 & ..... & B\hfill2
\end{tabularx}
\end{document}

As we can see, the dots below "7890" are aligned to the beginning of this cell, i.e. below the number "7", and the dot below the "50" cell is just below the "5". The overall appearance is that it is all misaligned. I prefer having them all centered on both first and third columns (c and r columns).

The second point refers to the use of \hfill. In the example, the \hfill in A\hfill1 expands to nothing, so the text displayed is "A1", but the next row contains A\hfill2 in which the stretchable space expands until the size of the widest cell (the first one: "title 3"). Would be great if the effect of \hfill can also be achieved with the rows on which the X column may wrap.

TIA.

[1] tabularx: bottom alignment on r or l-columns when X column wraps

1

Simplest thing without rewriting it all is to allow you to specify a width to use for the box, to allow the \hfill to stretch. It would be possible (I suppose) to use the \pdflatstpos mechanism used to measure the vertical extent of the X column to measure the horizontal extend of the 1st and 3rd columns, but it adds a lot of complication for what is perhaps little practical use. Rather than use 2cm fixed width as here you could use \settowidth to get the width of what you know to be the widest entry.

enter image description here

\documentclass{article}
\usepackage{tabularx}

\makeatletter
\def\savepos#1{\leavevmode\pdfsavepos\write\@auxout{%
\gdef\noexpand#1{\the\pdflastypos sp }}}

\def\xstart#1{\expandafter\savepos\csname save@start@#1\endcsname}
\def\xend#1{\expandafter\savepos\csname save@end@#1\endcsname}
\def\xpad#1#2#3{%
\vtop{%
\baselineskip\normalbaselineskip
#2%
\expandafter\ifx\csname save@start@#1\endcsname\relax
\else
\dimen@\csname save@start@#1\endcsname\relax
\loop
\ifdim\dimen@>\csname save@end@#1\endcsname
\advance\dimen@-\baselineskip
\hbox{$\cdot$}%
\repeat
\fi
#3%
}}
\def\xleft#1#2#3{\xpad{#1}{\hbox\ifx!#3!\else to #3\fi{#2}}{}}
\def\xright#1#2#3{\xpad{#1}{}{\hbox\ifx!#3!\else to #3\fi{#2}}}

\begin{document}
\begin{tabularx}{5cm}{lXr}
\multicolumn{1}{c}{title 1}& title 2 & title 3 \\

 \xleft{a}{7890}{} & \xstart{a}qwer asdf zxcv qwer 
    asdf zxcv qwer asdf
    zxcv\xend{a} & \xright{a}{1}{2cm} \\
 \xleft{b}{50}{} & \xstart{b}qwer asdf zxcv\xend{b} & \xright{b}{A\hfill1}{2cm} \\
 90 & ..... & B\hfill2
\end{tabularx}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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