
\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...}
でした。