Warum ist \setlength in einer tabellarischen Umgebung wirkungslos?

Warum ist \setlength in einer tabellarischen Umgebung wirkungslos?

Warum ist \setlengtheine Umgebung ineffektiv tabular? Hier ist ein 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}

Während die ersten beiden Punkte gut ausgerichtet sind, ist der dritte anders und verhält sich, als ob \locallengther wäre . Warum ist das so und was kann ich tun? Ich möchte innerhalb der Umgebung 0ptverwenden , daher ist das Festlegen der Länge außerhalb der Umgebung keine wirkliche Option.\setwidthtabular

Antwort1

Ausrichtungszellen werden innerhalb einer impliziten Gruppe verarbeitet, sodass lokale Zuweisungen zu Variablen rückgängig gemacht werden, wenn die Gruppe endet.

Die Kerneldefinition von \setlengthist

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

weshalb\global\setlength scheintzu arbeiten. Andererseits \settowidthist die Definition von

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

und die Definition von \@settodimist

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

So \global\settowidth{\locallength}{abc}würde

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

was natürlich bei einer globalen Zuweisung ineffektiv ist \locallength.

Ja, \settowidth{\global\locallength}{abc}würde funktionieren, ist aber reiner Zufall.

LaTeX unterstützt keine globalen Dimensions-/Überspringzuweisungen und Sie sollten sich auf Befehle auf niedrigerer Ebene verlassen. Eine sicherere Methode ist daher die Definition neuer Befehle:

\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

und ebenso für \gsettoheightund \gsettodepthbei Bedarf.

Dies funktioniert auch, wenn calcgeladen ist und keine besondere Implementierung der „lokalen“ Befehle nutzt.

Antwort2

Beides \global\setlength{\locallength}{10pt}scheint \setlength{\global\locallength}{10pt}zu funktionieren, aber ich habe keine Ahnung, warum das erforderlich sein sollte.

https://tex.stackexchange.com/a/210598/30810hat mich dazu gebracht, es zu versuchen, und der Kommentar von @ChristianHupfer erklärt, warum.

In meinem längeren Dokument \global\settowidth{...}hat es nicht funktioniert; hat aber \settowidth{\global...}funktioniert.

verwandte Informationen