我正在尝试写这个 if 语句
\def\x{y}
if x==y
yes
else
no
end
我怎样才能在 latex 中编写这样的代码
答案1
实现此目的的基本方法是使用\ifx
比较。\ifx
比较以下两个宏的定义(如果参数是宏,则它还可以比较其他标记)。重要的是\ifx
不扩展以下标记。
我们如何使用这个来比较两个文本?好吧,我们使用两个临时宏来存储文本,然后比较这些临时宏。为了使临时宏保持临时性,我们在 内部定义它们,\begingroup...\endgroup
并在组结束之前进行比较,恢复它们之前的定义(或取消定义它们)我们使用\expandafter
(这会评估\ifx
,然后关闭组,然后才执行 的真或假分支\ifx
)。
在这两个分支中我们使用\expandafter\@firstoftwo
or \expandafter\@secondoftwo
,其效果是\else
or\fi
被扩展,并且只有在此之后,才会读取并重新插入接下来的两个参数(从用户的角度来看,这两个参数是真分支和假分支)。这样,\ifx...\fi
在插入任何用户代码之前,会处理完整的块(这通常会提供更好的稳定性)。
\newcommand\iftexteqTF[2]
{%
\begingroup
\def\tmpa{#1}%
\def\tmpb{#2}%
\expandafter
\endgroup
\ifx\tmpa\tmpb
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
这种比较的缺点是它不可扩展(因此,如果我们做的一切都正确,我们就不会\newcommand
在那里使用,但希望的定义\iftexteqTF
是\protected
,所以更好的是\@ifdefinable\iftexteqTF{\protected\long\def\iftexteqTF#1#2{<definition>}}
)。此外,这样前两个参数中的文本就不能包含#
(下面 MWE 中的实现通过使用\edef\tmpa{\unexpanded{#1}}
而不是来解决这个问题\def\tmpa{#1}
)。
我们还可以使用可扩展测试。多个引擎中都内置了这种可扩展测试(对于 LuaLaTeX,则在 Lua 中实现)。为了独立使用这个引擎,我们只需使用 LaTeX3 提供的实现即可:
\ExplSyntaxOn
\cs_new_eq:NN \ifstreqTF \str_if_eq:nnTF
\ExplSyntaxOff
名称略有不同表明了一个重要的区别:这会比较其参数的字符串表示,因此不考虑类别代码。这种差异通常并不重要(有时甚至是有利的)。
使用两种变体的完整文档:
\documentclass[]{article}
\makeatletter
\@ifdefinable\iftexteqTF
{%
\protected\long\def\iftexteqTF#1#2%
{%
\begingroup
\edef\tmpa{\unexpanded{#1}}%
\edef\tmpb{\unexpanded{#2}}%
\expandafter
\endgroup
\ifx\tmpa\tmpb
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}%
}
\ExplSyntaxOn
\cs_new_eq:NN \ifstreqTF \str_if_eq:nnTF
\ExplSyntaxOff
\makeatother
\begin{document}
\iftexteqTF{abc}{abc}{True}{False} \par
\iftexteqTF{abc}{ABC}{True}{False} \par
\bigskip
\ifstreqTF{abc}{abc}{True}{False} \par
\ifstreqTF{abc}{ABC}{True}{False}
\end{document}
如果你想知道,第一个变体也由 LaTeX3 以 的形式提供,\tl_if_eq:nnTF
因此我们也可以使用以下形式:
\ExplSyntaxOn
\cs_new_eq:NN \iftexteqTF \tl_if_eq:nnTF
\ExplSyntaxOff