我正在尝试在 \foreach 循环中定义多个宏。每个宏的名称包含不同的整数。为此,我使用 \csname ... \endcsname。
问题是我希望能够在循环外调用这些宏。具体来说,我正在逐行构建文本,并且希望将每一行存储在一个编号宏中,以便在完成后能够调用所有这些宏。
以下是我尝试过的:
\documentclass[12pt, a4paper]{article}
\usepackage{pgf,tikz}
\begin{document}
\large
\foreach \k in {1,...,3}{
\expandafter\newcommand\csname step\k\endcsname{line n° \k}
\csname step\k\endcsname
%\global\let\csname step\k\endcsname = \csname step\k\endcsname
}
%\csname step1\endcsname
\end{document}
我尝试使用 \global\let 使每个宏全局化,但它引发多个错误:
Extra \endcsname
LaTeX Error: Command \csname already defined
显然我做错了什么,但我不知道是什么,可能是因为我不明白 \csname、\global 和 \let 如何工作。
答案1
如果你这样做\global\let\csname step\k\endcsname
,你就重新定义了\csname
。
你需要
\global\expandafter\let\csname step\k\endcsname
(因为\global
想要看到\let
,\def
或者它之后的变体,所以它将令牌扩展为这个目的)。
另一方面,您无法\k
在定义主体中扩展,因此,除非您使用,否则您注定会失败\xdef
。
\foreach \k in {1,...,3}{
\expandafter\xdef\csname step\k\endcsname{\unexpanded{line n° }\k}
}
现在\csname step3\endcsname
将产生“第 3 行”。
我保护了\unexpanded
所有不属于的东西\k
,以避免遭遇令人不快的意外。
采用不同的方法expl3
。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\nforeach}{mO{1}mm}
{
\cs_set_protected:Nn \__funkiephil_nforeach:n { #4 }
\int_step_function:nnnN { #1 } { #2 } { #3 } \__funkiephil_nforeach:n
}
\ExplSyntaxOff
\nforeach{1}{3}{\ExpandArgs{c}\newcommand{step#1}{line n° #1}}
\begin{document}
\csname step1\endcsname
\csname step2\endcsname
\csname step3\endcsname
\end{document}
请注意,这\ExpandArgs{c}\newcommand{...}
是更简单的术语
\expandafter\newcommand\csname...\endcsname
但需要较新(2021 年 10 月)发布的 LaTeX。
语法\nforeach
是
\nforeach{<start>}[<step>]{<end>}{<what to do>}
<what to do>
您可以在循环中使用当前#1
整数。步骤是可选的(默认为 1)。