Überarbeitungsverlauf[Zurück]
Klicke auf Einblenden/Ausblenden von Überarbeitungen 2

07 Okt '18, 18:58

moewe's gravatar image

moewe
3.7k36

Alles, was sich innerhalb von `\foreach` abspielt abspielt, passiert implizit innerhalb einer Gruppe, daher müssen die Makros `\global` definiert sein, wenn sie außerhalb von `\foreach` genutzt werden sollen. Ferner kann nicht einfach `\newcommand{\testI}{\b}` genutzt werden, da `\b` nicht mehr bekannt ist oder nicht mehr den richtigen Wert hat, wenn `\testI` ausgeführt werden soll. Also muss `\b` entweder expandiert werden, oder wir müssen `\let` nutzen. Das kann man sich an folgenden Beispiel klarmachen. \documentclass{article} \begin{document} \def\b{aaa} \newcommand*{\testI}{\b} \def\b{bb} \newcommand*{\testII}{\b} \testI, \testII \end{document} TeX ist eine Makrosprache und `\newcommand{\testI}{\b}` oder `\def\testI\b` heißt einfach: "Ersetze jedes Vorkommen von `\testI` mit `\b`". Du möchtest aber `\testI` durch den Wert von `\b` zur Definitionszeit ersetzen. Das bekommt man mit `\edef` hin (`\xdef` ist ein globales `\edef`), dabei wird die Definition vollständig expandiert, `\edef\testI{\b}` ist also das gleiche wie `\def\testI{aaa}`, wenn `\b` zu `aaa` expandiert. Mit `\expandonce` können wir das zu einer einmaligen Expansion umbauen, das ist hier nicht relevant, aber interessant, wenn `\b` selbst mittels eines anderen Makros `\c` definiert ist. `\let\testI\b` weist `\testI` die Definition von `\b` zu, es ist dabei sehr ähnlich zu der Zuweisung mit `\edef` und einmaliger Expansion mittels `\expandonce`. Möglich wären also also mindestens \documentclass{article} \usepackage{pgffor} \usepackage{etoolbox} \begin{document} \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \global\expandafter\let\csname test\a\endcsname\b } \testI, \testII, \testIII % \cslet von etoolbox \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \global\cslet{tost\a}\b \global\cslet{tost\a}\b } \tostI, \tostII, \tostIII % \csxdef von etoolbox \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \csxdef{tust\a}{\expandonce{\b}} } \tustI, \tustII, \tustIII % \csxdef \csgdef von etoolbox \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \expandafter\csgdef\expandafter{tast\a\expandafter}\expandafter{\b} } \tastI, \tastII, \tastIII % \csxdef von etoolbox \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \csxdef{tist\a}{\b} } \tistI, \tistII, \tistIII \end{document}
Klicke auf Einblenden/Ausblenden von Überarbeitungen 1

07 Okt '18, 18:44

moewe's gravatar image

moewe
3.7k36

Alles, was sich innerhalb von `\foreach` abspielt passiert implizit innerhalb einer Gruppe, daher müssen die Makros `\global` definiert sein, wenn sie außerhalb von `\foreach` genutzt werden sollen. Ferner kann nicht einfach `\newcommand{\testI}{\b}` genutzt werden, da `\b` nicht mehr bekannt ist oder nicht mehr den richtigen Wert hat, wenn `\testI` ausgeführt werden soll. Also muss `\b` entweder expandiert werden, oder wir müssen `\let` nutzen. Das kann man sich an folgenden Beispiel klarmachen. \documentclass{article} \begin{document} \def\b{aaa} \newcommand*{\testI}{\b} \def\b{bb} \newcommand*{\testII}{\b} \testI, \testII \end{document} Möglich wären also \documentclass{article} \usepackage{pgffor} \usepackage{etoolbox} \begin{document} \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \global\expandafter\let\csname test\a\endcsname\b } \testI, \testII, \testIII % \cslet von etoolbox \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \global\cslet{tost\a}\b } \tostI, \tostII, \tostIII % \csxdef von etoolbox \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \csxdef{tust\a}{\expandonce{\b}} } \tustI, \tustII, \tustIII % \csxdef von etoolbox \foreach \a/\b in{I/aaa,II/bbb,III/ccc}{ \csxdef{tist\a}{\b} } \tistI, \tistII, \tistIII \end{document}