Ich habe zwei Befehle \testone
und \testtwo
. \testtwo
erscheint nur, wenn vorher ein relevanter Befehl vorhanden war \testone
und dieselben Argumente verwendet. Daher möchte ich \testone
seine Argumente dort speichern, \@repeat@me
wo \testtwo
sie wieder abgerufen werden, damit ich sie nicht zweimal eingeben muss.
Dies funktioniert jedoch nur, wenn sich beide in derselben Umgebung befinden. In einigen Fällen wird jedoch entschieden, dass der geänderte Wert \@repeat@me
ignoriert werden soll.
\documentclass{article}
\makeatletter
\def\@repeat@me{}
\newcommand\testtwo{\bf{\@repeat@me}% print what is currently defined.
% reset the definition so it does not interfere with next call
\def\@repeat@me{}}
% print it and then remember it.
\newcommand\testone[1]{\def\@repeat@me{#1}\emph{\@repeat@me}}%
\makeatother
\begin{document}
% prints: \emph{Hello World} \bf{Hello World}
\testone{Hello World} \testtwo{}
% prints: \bf{\emph{Hello World}}
% intended: \bf{\emph{Hello World}} \bf{Hello World}
\bf{\testone{Hello World}} \testtwo{}
\end{document}
Antwort1
Wenn Sie eine globale Zuweisung wünschen (um Gruppen und Umgebungen zu entkommen, benötigen Sie) \global\def
(oder \gdef
):
\documentclass{scrartcl}
\makeatletter
\newcommand*\@repeat@me{}
\newcommand*\testtwo{\textbf{\@repeat@me}\gdef\@repeat@me{}}
\newcommand\testone[1]{\gdef\@repeat@me{#1}\emph{\@repeat@me}}
\makeatother
\begin{document}
\testone{Hello World} \testtwo
\textbf{\testone{Hello World}} \testtwo
\end{document}
Antwort2
Beachten Sie, dass TeX einen Bereich erzwingt, innerhalb dessen (Neu-)Definitionen bestehen bleiben und außerhalb davon rückgängig gemacht werden können. Genau das passiert hier. Sehen wir uns die Erweiterungen an:
\testone{Hello World} \testtwo{}
erweitert zu (mit Kommentaren)
\def\@repeat@me{Hello World}\emph{\@repeat@me} % \testone{Hello World}
\textbf{\@repeat@me}\def\@repeat@me{}% \testtwo{}
das sich ausdehnt auf
\emph{Hello World} \textbf{Hello World}% Using the new definition of \@repeat@me
Schauen Sie sich nun die Erweiterungen des zweiten Makrosatzes an:
\textbf{\testone{Hello World}} \testtwo{}
erweitert zu (mit Kommentaren)
\textbf{% <--- start of a group/scope
def\@repeat@me{Hello World}\emph{\@repeat@me}% \testone{Hello World}
} % <--- end of a group/scope
\textbf{\@repeat@me}\def\@repeat@me{}% \testtwo{}
das sich ausdehnt auf
\textbf{\emph{Hello World}} % At scope-end, \@repeat@me reverts to its original definition
\textbf{}% Since \@repeat@me is empty {}
Die Verwendung einer globalen Definition wie \gdef
führt dazu, dass die Neudefinition von \@repeat@me
über den durch bereitgestellten Rahmen hinaus überlebt \textbf{..}
.
\documentclass{article}
\makeatletter
\def\@repeat@me{}
% print it and then remember it.
\newcommand\testone[1]{\gdef\@repeat@me{#1}\emph{\@repeat@me}}%
\newcommand\testtwo{\textbf{\@repeat@me}% print what is currently defined.
% reset the definition so it does not interfere with next call
\def\@repeat@me{}}
\makeatother
\begin{document}
% prints: \emph{Hello World} \textbf{Hello World}
\testone{Hello World} \testtwo{}
% prints: \textbf{\emph{Hello World}} \textbf{Hello World}
\textbf{\testone{Hello World}} \testtwo{}
\end{document}