tabularx で 'X' 列が折り返される場合の列の配置が異なります

tabularx で 'X' 列が折り返される場合の列の配置が異なります

2013 年にこの質問をして回答を得ましたが、別のコードに実装すると、これまでになかった新しい問題が発生します。

3 つの列がありtabularx、そのうち 2 つはlr、またはcで、中央の列はX列です。X列が複数行にわたる場合、望ましい動作は、最初の列 (l列とします) が上揃え (列の最初の行と同じ行) になりX、3 番目の列が下揃え (列の最後の行と同じ行X) になることです。空白の列は のようなもので埋められます\cdot

オリジナルの投稿は[1]で閲覧できます。David Carlisleが提供した解決策には、測定を行い、テキストを目的の位置に配置するための新しいコマンド、、、、が含まれていました\xleft。これは今まで完璧に機能していました。\xright\xstart\xend\xpad

  1. 1 列目と 3 列目のセルに 1 文字以上のテキストが含まれている場合、塗りつぶされたセルは中央揃えになるのではなく、関連する他のセルのテキストの先頭/末尾に合わせて水平に揃えられ、これが望ましい外観になります。
  2. \hboxセルの内容を印刷するために を使用すると、 のような伸縮可能なスペースの使用が妨げられ、右の列の 1 つのセルには、列幅 (長い方のセルから取得、私の場合は列タイトル) まで 2 つの単語間のスペースを拡張する\hfillパターンが必要です。text\hfill text

次のコードは、私が今望んでいることを示すために David Carlisle が例示したソリューションです。

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

ご覧のとおり、「7890」の下のドットはこのセルの先頭、つまり数字「7」の下に揃えられており、「50」セルの下のドットは「5」のすぐ下にあります。全体的に見ると、すべてがずれているように見えます。私は、これらをすべて 1 列目と 3 列目 (cおよびr列) の両方の中央に配置することを好みます。

2 番目のポイントは、 の使用に関するものです\hfill。この例では、\hfillの はA\hfill1何も展開されないため、表示されるテキストは「A1」ですが、次の行には が含まれており、伸縮可能なスペースは最も幅の広いセル (最初のセル:「タイトル 3」) のサイズまで展開されます。 の効果が、列が折り返される可能性のある行でも実現できれA\hfill2ば素晴らしいと思います。\hfillX

ティア。

[1]tabularx: X 列が折り返される場合の r 列または l 列の下揃え

答え1

すべてを書き直さずに最も簡単なのは、ボックスに使用する幅を指定して、ボックスを\hfill伸縮できるようにすることです。X\pdflatstpos列の垂直方向の拡張を測定するために使用されるメカニズムを使用して、1 列目と 3 列目の水平方向の拡張を測定することは可能 (だと思います) ですが、これはおそらくほとんど実用的ではないのに非常に複雑になります。ここでのように 2cm の固定幅を使用するのではなく、\settowidth最も広いエントリであることがわかっている幅を取得するために使用できます。

ここに画像の説明を入力してください

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

関連情報