我想在\foreach
循环中定义和扩展宏。宏的名称取决于迭代步骤。我定义的宏被解释为字符串,而不是我实际想要的数字集。这是一个最简单的例子,可以更准确地说明问题。
\documentclass[english]{article}
\usepackage{verbatim}
\usepackage{tikz}
\newcommand\Stage{One,Two}
\newcommand\SubStageOne{2,3,4,6}
\newcommand\SubStageTwo{6,7,8}
\newcommand{\CurrentSubStage}{} % will be defined in each stage loop
\begin{document}
%
\foreach \stage in \Stage {
%
\renewcommand{\CurrentSubStage}{ \expandafter\csname SubStage\stage \endcsname }
%
The Macro replacement of {\tt CurrentSubStage} looks the same as Macro replacement of {\tt SubStage\stage}:
%
\begin{center}
\CurrentSubStage\ is the same as \expandafter\csname SubStage\stage \endcsname .
\end{center}
%
But really they are different: Consider first the output from looping over {\tt CurrentSubStage}:
\begin{itemize}
\foreach [count=\ii] \substage in \CurrentSubStage {
\item Substage number \ii\ is \substage \\
}
\end{itemize}
%
and then this output from looping over {\tt SubStageOne}:
%
\begin{itemize}
\foreach [count=\ii] \substage in \SubStageOne {
\item Substage number \ii\ is \substage
}
\end{itemize}
}
%
%
In the second \verb|\stage| iteration, i.e. ``Two'', I want to loop over \verb|\SubStageTwo| as in the \verb|\SubStageOne| that creates four rather than one item. But I do not know how to to call \verb|\Substage\stage| (This is why I created \verb|\CurrentSubStage|). My questions:
\begin{enumerate}
\item How can I define macro \verb|\CurrentSubStage| such that it does not treat the set of numbers as a single string so that the corresponding \verb|\substage| loop gives an iteration for each number?
\item Is there a possibility to do something like:\\ \verb|\foreach [count=\ii] \substage in \SubStage\stage { ...|?
\item I need to define an ``output'' macro at the end of each \verb|\stage| iteration: Something like \verb|\newcommand{\SubStageOutputOne}| in iteration One and \verb|\newcommand{\SubStageTwoOutput}| in iteration Two. (In my application, this output is a permutation of the set |\CurrentSubStage|. I want to ``save'' this permutation in a macro and call it later, at the end of the document.) In short, how can I include something like \verb|\newcommand{\SubStageOutput\stage}| at the end of each \verb|\stage| loop?
\end{enumerate}
%
[Final note: For my actual purpose, the set \verb|\Stage| contains 6 elements and each \verb|\SubStage| set contains between 3 and 10 elements each.]
%
\end{document}
答案1
你想要类似的东西
\edef\CurrentSubStage{%
\unexpanded\expandafter\expandafter\expandafter
{\csname SubStage\stage\endcsname}%
}
也就是说,您需要将其扩展为 中的值\csname SubStage\stage\endcsname
。这\edef
是一个 TeX 命令,它会在将其分配给它定义的宏之前完全扩展宏定义中的所有内容。在您的示例中,实际上
\edef\CurrentSubStage{\csname SubStage\stage\endcsname}
就足够了,但第一个版本更安全一些。它是如何工作的?扩展\unexpanded
开始扩展第一个左括号后面的内容。第一个\expandafter
扩展了第三个,\expandafter
后者扩展了\csname
。所以经过一个扩展周期后,我们得到:
\unexpanded\expandafter{\SubStageOne}
现在将余项\expandafter
展开\SubStageOne
,我们得到:
\unexpanded{2,3,4,6}
then\unexpanded
阻止了进一步的扩展,因此\edef
变成\CurrentSubStage
了2,3,4,6
。(类似于循环的第二步。)
评论:
\tt
在 LaTeX 中并不推荐。最好使用\ttfamiy
或在这种情况下\texttt{...}
,请参阅使文本加粗/斜体的“正确”方法是什么?以供参考。- 代码中的
\expandafter
in完全没用:它之前尝试扩展但无法扩展。\expandafter\csname SubStage\stage \endcsname
S
\csname
S
完整代码:
\documentclass[english]{article}
\usepackage{verbatim}
\usepackage{tikz}
\newcommand\Stage{One,Two}
\newcommand\SubStageOne{2,3,4,6}
\newcommand\SubStageTwo{6,7,8}
\newcommand{\CurrentSubStage}{} % will be defined in each stage loop
\begin{document}
\foreach \stage in \Stage {
\edef\CurrentSubStage{%
\unexpanded\expandafter\expandafter\expandafter
{\csname SubStage\stage\endcsname}%
}%
The Macro replacement of \texttt{CurrentSubStage} looks the same as Macro
replacement of \texttt{SubStage\stage}:
\begin{center}
\CurrentSubStage\ is the same as \csname SubStage\stage \endcsname .
\end{center}
But really they are different: Consider first the output from looping over
\texttt{CurrentSubStage}:
\begin{itemize}
\foreach [count=\ii] \substage in \CurrentSubStage {
\item Substage number \ii\ is \substage
}
\end{itemize}
and then this output from looping over \texttt{SubStageOne}:
\begin{itemize}
\foreach [count=\ii] \substage in \SubStageOne {
\item Substage number \ii\ is \substage
}
\end{itemize}
}
In the second \verb|\stage| iteration, i.e. ``Two'', I want to loop over
\verb|\SubStageTwo| as in the \verb|\SubStageOne| that creates four rather
than one item. But I do not know how to to call \verb|\Substage\stage| (This
is why I created \verb|\CurrentSubStage|). My questions:
\begin{enumerate}
\item How can I define macro \verb|\CurrentSubStage| such that it does not
treat the set of numbers as a single string so that the corresponding
\verb|\substage| loop gives an iteration for each number?
\item Is there a possibility to do something like:\\
\verb|\foreach [count=\ii] \substage in \SubStage\stage { ...|?
\item I need to define an ``output'' macro at the end of each \verb|\stage|
iteration: Something like \verb|\newcommand{\SubStageOutputOne}| in
iteration One and \verb|\newcommand{\SubStageTwoOutput}| in iteration
Two. (In my application, this output is a permutation of the set
|\CurrentSubStage|. I want to ``save'' this permutation in a macro and call
it later, at the end of the document.) In short, how can I include
something like \verb|\newcommand{\SubStageOutput\stage}| at the end of each
\verb|\stage| loop?
\end{enumerate}
[Final note: For my actual purpose, the set \verb|\Stage| contains 6 elements
and each \verb|\SubStage| set contains between 3 and 10 elements each.]
\end{document}