我试图理解为什么\mymap
以下代码中的函数在 for 循环中使用变量调用时不产生任何输出(请参阅\myloop
)。当明确将文本传递给它时,它会产生输出。请参阅\myloopb
。抱歉,这个问题很简单,我无法理解stackexchange 和其他地方对\if
和\ifx
语句的解释。如果这很重要,我在 Windows 上使用 MikTex 的 pdflatex。
\documentclass[12pt]{article}
\usepackage{pgffor}
% define variables
\def\vala{aa}
\def\valb{bb}
% this produces different output depending on #1
\newcommand{\mymap}[1]{
\def\temparg{#1}
\ifx\temparg\vala
Condition 1 is true
\fi
\ifx\temparg\valb
Condition 2 is true
\fi
}
\newcommand{\myloop}{
\foreach \myvar in {\vala,\valb}{
% this does not produce any output
\mymap{\myvar}
}
}
\newcommand{\myloopb}{
% this produces output
\mymap{aa}
\mymap{bb}
}
\begin{document}
\section{Using myloop does not produce output}
% no output
\myloop
\section{Using myloopb produces output}
% produces output
\myloopb
\end{document}
答案1
这里的问题是扩展。\ifx
测试以下两个宏(如果传递了宏)是否具有相同的含义。在第一种情况下,\temparg
含义为,macro:->\myvar
而\vala
含义macro:->aa
为。\valb
macro:->bb
您的循环中的\myvar
hasmacro:->\vala
和macro:->\valb
as 含义。如果在\mymap
获取其参数之前将其展开两次,则会得到 的正确含义\temparg
。您可以使用 触发早期的展开\expandafter<tokA><tokB>
,它将在展开<tokB>
之前展开。因此,在您的循环中使用。<tokA>
\expandafter\expandafter\expandafter\mymap\expandafter\expandafter\expandafter{\myvar}
如果您的输入总是可以完全扩展(在您的示例中),您可以使用\edef\temparg{#1}
它,它比\expandafter
上面提出的-chain 更干净。
\documentclass[12pt]{article}
\usepackage{pgffor}
% define variables
\def\vala{aa}
\def\valb{bb}
% this produces different output depending on #1
\newcommand{\mymap}[1]{%
\edef\temparg{#1}%
\ifx\temparg\vala
Condition 1 is true%
\fi
\ifx\temparg\valb
Condition 2 is true%
\fi
}
\newcommand{\myloop}{%
\foreach \myvar in {\vala,\valb}{%
% this does not produce any output
\mymap{\myvar}%
}%
}
\newcommand{\myloopb}{%
% this produces output
\mymap{aa}%
\mymap{bb}%
}
\begin{document}
\section{Using myloop does not produce output}
% no output
\myloop
\section{Using myloopb produces output}
% produces output
\myloopb
\end{document}
答案2
您可以定义一个通用的字符串大小写比较。
\documentclass[12pt]{article}
\usepackage{pgffor}
% a string comparison function
\ExplSyntaxOn
\NewExpandableDocumentCommand{\StringCaseTF}{mm+m+m}
{% #1 = string input, #2 = cases,
% #3 = code to execute after a match
% #4 = code to execute after no match
\str_case_e:nnTF { #1 } { #2 } { #3 } { #4 }
}
\ExplSyntaxOff
% define variables (not with \def)
\newcommand\vala{aa}
\newcommand\valb{bb}
% this produces different output depending on #1
\newcommand{\mymap}[1]{%
\StringCaseTF{#1}{
{\vala}{Condition 1 is true}
{\valb}{Condition 2 is true}
}{\par There was a match!}{\par There was no match!}%
\par
}
\newcommand{\myloop}{%
\foreach \myvar in {\vala,\valb,x}{
% this does not produce any output
\mymap{\myvar}
}
}
\begin{document}
\myloop
\end{document}
xparse
如果您没有最新的 LaTeX 内核,请加载。
当然,第三或第四个参数可以\StringCaseTF
留空。