我有两个命令,\testone
只有当之前有一个相关命令时才会出现,并且采用相同的参数。因此我想将其参数存储在再次拾取它们的位置,这样我就不必输入两次了。\testtwo
\testtwo
\testone
\testone
\@repeat@me
\testtwo
\@repeat@me
然而,这只有当两者都在同一个环境中时才有效。但在某些情况下,它会决定忽略改变的值。
\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}
答案1
如果您想要一个全局分配(为了逃离团体和环境,您需要)\global\def
(或\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}
答案2
请注意,TeX 强制规定了(重新)定义可以在其内存在并在外部恢复的范围。这就是这里发生的事情。让我们看看扩展:
\testone{Hello World} \testtwo{}
扩展为(带注释)
\def\@repeat@me{Hello World}\emph{\@repeat@me} % \testone{Hello World}
\textbf{\@repeat@me}\def\@repeat@me{}% \testtwo{}
扩展为
\emph{Hello World} \textbf{Hello World}% Using the new definition of \@repeat@me
现在看看第二组宏的展开:
\textbf{\testone{Hello World}} \testtwo{}
扩展为(带注释)
\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{}
扩展为
\textbf{\emph{Hello World}} % At scope-end, \@repeat@me reverts to its original definition
\textbf{}% Since \@repeat@me is empty {}
使用类似的全局定义\gdef
使得 survive 的重新定义\@repeat@me
超出了 提供的范围\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}