我正在制作一个新包,并想使用 \foreach 简化 .sty 文件中的以下几行
\DeclareOption{aaa}{ \def\x{1} }
\DeclareOption{bbb}{ \def\x{2} }
\DeclareOption{ccc}{ \def\x{3} }
我尝试了以下
\usepackage{pgffor}
\foreach \i/\j in {aaa/1, bbb/2, ccc/3}{
\DeclareOption{\i}{ \def\x{\j}}
}
\ProcessOptions\relax
但是,它没有定义 \x。
相反,以下作品
\def\i{aaa}
\def\j{1}
\DeclareOption{\i}{ \def\x{\j}}
也许该问题与 \foreach 循环的实现有关,但我无法弄清楚。
答案1
pgf\foreach
将每次迭代放在本地组中,因此它通常是一种不适合编程任务的循环结构。
还有许多其他不引入组的循环宏,例如expl3
clist 映射,或\loop
格式中的宏,或者您可以直接执行列表而无需任何显式循环宏。
例如,这将遍历一个空格分隔的对列表,直到到达一个空白行
测试.sty
\long\def\zz #1/#2 #3{%
\ifx\par#3%
\else
\DeclareOption{#1}{\def\x{#2}}%
\expandafter\zz\expandafter#3\fi
}
\zz aaa/1 bbb/2 ccc/3
\ProcessOptions\relax
因此设置\x
为 2
\documentclass{article}
\usepackage[bbb]{test}
\typeout{x=\x}
\end{document}
答案2
\foreach
按组执行循环中的每个项目,因此对于此应用程序而言毫无用处。
下面是一个具有不同循环的示例:
%%% file declareoptions.sty
\ExplSyntaxOn
\cs_new_protected:Npn \DeclareOptionsWithFormat #1 #2
{% #1 is a list of items of the form {<optionname>}{<text>}
% #2 is code that will become \DeclareOption{<optionname>}{<code>}
% The <code> here should depend on #1, which will be replaced
% with the current <text> in the loop
\cs_set_protected:Nn \__declareoptionswithformat_aux:n { #2 }
\clist_map_inline:nn { #1 } { \__declareoptionswithformat:nn ##1 }
}
\cs_new_protected:Nn \__declareoptionswithformat:nn
{
\DeclareOption{#1}{\__declareoptionswithformat_aux:n {#2}}
}
\ExplSyntaxOff
\DeclareOptionsWithFormat{
{aaa}{1},
{bbb}{2},
{ccc}{3}
}{\def\x{#1}}
\ProcessOptions\relax
如果我们运行测试文件
\documentclass{article}
\usepackage[bbb]{declareoptions}
\show\x
我们得到
> \x=macro:
->2.
如果你在 2020-10-01 之前拥有 LaTeX,你需要
\RequirePackage{expl3}
在declareoptions.sty
。