我编写了\myfunc
将冒号分隔的字符串拆分为两部分的程序。它本身的工作原理与用\foreach
逗号分隔的冒号分隔字符串的工作原理相同。
但如果我尝试\myfunc
从内部调用\foreach
,就会出现runaway argument
错误。
\documentclass[tikz,border=10pt,a4paper]{standalone}
\usepackage[english]{babel}
\begin{document}
\def\myfunc#1{\myfuncdoit#1\relax}
\def\myfuncdoit#1:#2\relax{ First: (#1), Second: (#2) }
\myfunc{foo bar:int * const}
\foreach \p in {foo:int,bar:float,baz:bool}{ (\p) }
\foreach \p in {foo:int,bar:float,baz:bool}{ (\myfunc{\p}) } % <<<----- ERROR
\end{document}
我预计最后\foreach
会产生
( First: (foo), Second: (int) )
( First: (bar), Second: (float) )
( First: (baz), Second: (bool) )
答案1
你必须在行动\p
之前进行扩展\myfunc
。
\documentclass[tikz,border=10pt,a4paper]{standalone}
\usepackage[english]{babel}
\begin{document}
\def\myfunc#1{\myfuncdoit#1\relax}
\def\myfuncdoit#1:#2\relax{ First: (#1), Second: (#2) }
\myfunc{foo bar:int * const}
\foreach \p in {foo:int,bar:float,baz:bool}{ (\p) }
\foreach \p in {foo:int,bar:float,baz:bool}{ (\expandafter\myfunc\expandafter{\p}) }
\end{document}
否则,使用更强大的方法。
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\myfunc}{>{\SplitArgument{1}{:}}m}{%
\myfuncsplit#1%
}
\NewDocumentCommand{\myfuncsplit}{mm}{%
First: (#1), Second: (#2)%
}
\ExplSyntaxOn
\NewDocumentCommand{\cycle}{ m +m }
{
\clist_map_inline:nn { #1 } { #2 }
}
\ExplSyntaxOff
\begin{document}
\cycle{foo:int, bar:float, baz:bool}{\myfunc{#1}\par}
\end{document}
请注意,列表中逗号周围的空格会被剪掉。在 的第二个参数中\cycle
,您使用#1
来表示逗号分隔列表中的当前项。