tabular環境内でのsetlength後、改行で長さ0ptにリセットされる

tabular環境内でのsetlength後、改行で長さ0ptにリセットされる

- 六連星 昴 の投稿
返信数: 3
環境はTeXLive2018+Windows10+lualatex環境(pdflatexでの再現も可能)です

現在下記のような表組み(セル内上揃え、セル内改行時に水平線を入れる場合がある)を作成しようとしています。(このとき、Line2の文字列長さが長い場合は自動的にフォントサイズを下げる機能などをつけようとしています)
Line1

Line2
CLine1
CLine2

CLine3
RLine1
RLine2
RLine3
RLine4
静的な値を代入しての作成は出来たのですが、いざ\setlengthや\settowidth等を利用して計算した値を作成し、セル内で利用した場合に数値が0ptになる現象に遭遇しました。

最小再現コードは以下の通りです。
\documentclass[a4paper,lualatex,ja=standard]{bxjsarticle} \newlength{\len} \newcommand\testlen[1]{  #1\\%  #1\\% } \begin{document}  \begin{tabular}{|c|}  \hline\setlength{\len}{8.21136pt}\testlen{\the\len} \\\hline  \end{tabular} \end{document}
想定出力は
8.21136pt
8.21136pt
ですが、実際の出力は

8.21136pt
0.0pt
です。コンパイルエラー等はなかったため、何が原因で0にセットされているのかが掴めませんでした。(testlen内1行目を#1→0などに置き換えても2行目は0.0pt)

上記値は例えばLine2のフォントサイズを縮小してwidthに収めるために使うために使用(\fontsize{#1}{0pt}……)していて、2行目の値として利用される場合に0ptとして代入されエラーとなってしまいます。
この問題の回避方法についてご教授願います。
六連星 昴 への返信

Re: tabular環境内でのsetlength後、改行で長さ0ptにリセットされる

- 帯田 木偶太 の投稿

tabular 環境内では、各要素(表計算ソフトなどでいうところのセル)は
暗黙のうちにグルーピングされています。\setlength で値を設定しても、
\testlen に含まれている \\ によって別のグループに移動したときに
自動的にグローバルな値にリセットされてしまいます。

ご所望の結果を得る方法としては、代入を
    \global\len=8.21136pt
というようなグローバルなものにする事が考えられると思います。
ただし、グローバルな代入では、tabular 環境の外側にまで
代入結果が伝わるので、副作用が出ないように注意する必要が
あるでしょう。

帯田 木偶太 への返信

Re: tabular環境内でのsetlength後、改行で長さ0ptにリセットされる

- 帯田 木偶太 の投稿

ちょっと気の利いた(ものかもしれない)別解です。

\documentclass[a4paper,lualatex,ja=standard]{bxjsarticle}
%\documentclass{jarticle}\relax
\newbox\lenbox
\newenvironment{lentabular}{%
    \setbox\lenbox=\null
    \begin{tabular}%
}{%
    \end{tabular}%
}
\newcommand*{\setlenbox}[1]{%
    \wd\lenbox=#1\relax
}
\newcommand\testlen[1]{
    #1\\%
    #1\\%
}
\begin{document} 
    \begin{lentabular}{|c|} 
        \hline
        \setlenbox{8.21136pt}
        \testlen{\the\wd\lenbox}
        \\\hline 
    \end{lentabular}
\end{document}

\len の代わりに \wd\lenbox を使うようにすれば、lentabular 環境外に
副作用が現れる心配はないでしょう。

ボックスの寸法への代入は常に(ボックスの中身への代入時と同じ
グルーピング・レベルにおいて)グローバルであるという性質を
利用しています。
※  ボックスの寸法への代入が常にグローバルであるということは
    TeXbook にも記載されていますが、ボックスの中身への代入時の
    グループを抜けると、値がリセットされるというのは、
    あまり知られていないことだと思います。

帯田 木偶太 への返信

Re: tabular環境内でのsetlength後、改行で長さ0ptにリセットされる

- 六連星 昴 の投稿
ありがとうございます。

現象の理由について説明ありがとうございます。
ようやく時間を作って検証し、ifthenを用いて表示用と計算用を分けるという方法で必要な機能をなんとか実用化出来ました。

(というのも、セル内の文字列長に合わせたフォントサイズ計算→全セルの上揃え用スペース計算→実表示 という展開をする上、1レコードの引数が9個を超えるため、ユーザーコマンドを引数に入れるしかやりようがなかったので)
(代替案がありそうですが……)