Tengo dos comandos \testone
y \testtwo
. \testtwo
Aparece sólo si hubo un \testone
antes relevante y toma los mismos argumentos. Por lo tanto, quiero \testone
almacenar sus argumentos en \@repeat@me
donde \testtwo
los recoja nuevamente para no tener que escribirlos dos veces.
Sin embargo, esto sólo funciona si ambos están en el mismo entorno. Pero en algunos casos decide que \@repeat@me
se debe ignorar el valor modificado de.
\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}
Respuesta1
Si desea una asignación global (para escapar de grupos y entornos, necesita) \global\def
(o \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}
Respuesta2
Tenga en cuenta que TeX impone un alcance dentro del cual las (re)definiciones pueden vivir y revertirse afuera. Eso es lo que está pasando aquí. Veamos las expansiones:
\testone{Hello World} \testtwo{}
se expande a (con comentarios)
\def\@repeat@me{Hello World}\emph{\@repeat@me} % \testone{Hello World}
\textbf{\@repeat@me}\def\@repeat@me{}% \testtwo{}
que se expande a
\emph{Hello World} \textbf{Hello World}% Using the new definition of \@repeat@me
Ahora mire las expansiones del segundo conjunto de macros:
\textbf{\testone{Hello World}} \testtwo{}
se expande a (con comentarios)
\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{}
que se expande a
\textbf{\emph{Hello World}} % At scope-end, \@repeat@me reverts to its original definition
\textbf{}% Since \@repeat@me is empty {}
El uso de una definición global como \gdef
hace que la redefinición de \@repeat@me
sobrevivir vaya más allá del alcance proporcionado por \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}