表形式の環境内で \setlength が効果がないのはなぜですか?

表形式の環境内で \setlength が効果がないのはなぜですか?

\setlength環境内ではなぜ効果がないのでしょうかtabular? MWE は次のとおりです。

\documentclass{article}
\newlength{\globallength}
\newlength{\locallength}
\begin{document}
\setlength{\globallength}{10pt}%
\begin{tabular}{l}
\setlength{\locallength}{10pt}%

\hspace*{10pt}. \\

\hspace*{\globallength}. \\

\hspace*{\locallength}. \\

\hspace*{0pt}. \\

\end{tabular}
\end{document}

最初の 2 つのドットは適切に配置されていますが、3 つ目のドットは異なり、\locallengthであるかのように動作します0pt。 これはなぜでしょうか。また、どうすればよいでしょうか。環境\setwidth内でを使用したいのでtabular、環境外で長さを設定することは実際には選択肢ではありません。

答え1

アライメント セルは暗黙的なグループ内で処理されるため、グループが終了すると変数へのローカル割り当ては元に戻されます。

のカーネル定義\setlength

% latex.ltx, line 2181:
\def\setlength#1#2{#1 #2\relax}

というわけで\global\setlength 思われる働く。一方、の定義\settowidth

% latex.ltx, line 2187:
\def\settowidth {\@settodim\wd}

の定義\@settodim

% latex.ltx, line 2183:
\def\@settodim#1#2#3{\setbox\@tempboxa\hbox{{#3}}#2#1\@tempboxa
       \setbox\@tempboxa\box\voidb@x}

つまり\global\settowidth{\locallength}{abc}

\global\setbox\@tempboxa\hbox{{abc}}\locallength\wd\@tempboxa\setbox\@tempboxa\box\voidb@x

もちろん、これは へのグローバル割り当てを行うには効果がありません\locallength

はい、\settowidth{\global\locallength}{abc}うまくいくでしょうが、それは単なる偶然です。

LaTeX ではグローバルな次元/スキップ割り当てはサポートされていないため、低レベルのコマンドを使用する必要があります。そのため、より安全な方法は、新しいコマンドを定義することです。

\makeatletter
\newlength\local@length@for@global
\newcommand\gsetlength[2]{%
  \setlength{\local@length@for@global}{#2}%
  \global#1\local@length@for@global
}
\newcommand{\gsettowidth}[2]{%
  \settowidth{\local@length@for@global}{#2}%
  \global#1\local@length@for@global
}
\makeatother

\gsettoheight必要に応じて、 およびについても同様に行います\gsettodepth

calcこれは、がロードされていて、「ローカル」コマンドの特定の実装を利用しない場合でも機能します。

答え2

どちらも\global\setlength{\locallength}{10pt}機能\setlength{\global\locallength}{10pt}しているように見えますが、なぜそれが必要なのかはわかりません。

https://tex.stackexchange.com/a/210598/30810私も試してみましたが、@ChristianHupfer のコメントでその理由が説明されています。

私の長い文書では、\global\settowidth{...}動作しません\settowidth{\global...}でした。

関連情報