我有一个大\foreach
循环,需要对参数进行宏评估。(这些是字符串比较宏,但这可能没关系。)以下是示例:
\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}
\newcommand\process[1]{\ifstrequal{#1}{Fridge}{EQUAL}{UNEQUAL}}
\begin{document}
\foreach \a in {Fridge,Badger} {\process{\a} }
\end{document}
这将产生输出UNEQUAL UNEQUAL
。我想要的输出是EQUAL UNEQUAL
。
在我的真实例子中,我正在对多个变量进行同时迭代(\foreach \a/\b in ...
),并且我的宏采用多个参数,而不仅仅是一个。
我不是完全地一无所知;我知道为什么会发生这种情况,并且我尝试了数百种\expandafter
、\edef
等组合,但没有任何成功。我发现 LaTeX 的这个方面极难理解。
答案1
答案2
says手册etoolbox
(第 3.6.3 节)
\ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}
⟨true⟩
比较两个字符串,如果相等则执行, 否则执行⟨false⟩
。测试中不会扩展字符串,并且比较与类别代码无关。任何参数中的控制序列标记⟨string⟩
都将被去标记化并视为字符串。
换句话说,你正在比较
\a
(两个字符的字符串)和Fridge
,它们根本不相等。expl3
您可以使用扩展字符串比较函数:
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\xifstrequal}{mmmm}
{
\str_if_eq_x:nnTF { #1 } { #2 } { #3 } { #4 }
}
\ExplSyntaxOff
\newcommand\process[1]{\xifstrequal{#1}{Fridge}{EQUAL}{UNEQUAL}}
\begin{document}
\foreach \a in {Fridge,Badger} {\process{\a} }
\end{document}
完整expl3
版本:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\xifstrequal}{mmmm}
{
\str_if_eq_x:nnTF { #1 } { #2 } { #3 } { #4 }
}
\NewDocumentCommand{\listforeach}{mm}
{
\clist_map_inline:nn { #1 } { #2 }
}
\ExplSyntaxOff
\newcommand\process[1]{\xifstrequal{#1}{Fridge}{EQUAL}{UNEQUAL}}
\begin{document}
\listforeach{Fridge,Badger}{\process{#1} }
\end{document}
当前项不使用某些虚拟控制序列,而是用 来表示#1
。
两种代码都产生相同的输出。