我正在寻找 TeX 中的方法来检查宏是否已定义。
目前我使用了一种相当复杂的方法。我利用了通过 比较两个宏时产生的一种副作用\ifx
;此命令返回:
- true,如果两个宏都未定义,
- 如果仅定义了一个宏,则为 false。
因此,给定一个肯定未定义的宏和可能定义或未定义的\undefined
宏,我可以使用:\CheckMe
\ifx \CheckMe \undefined
CheckMe is NOT defined
\else
CheckMe is defined!
\fi
这是正确的吗?我们可以定义一个宏ifdef
吗?它的工作原理如下:
\ifdef CheckMe %or \ifdef \CheckMe
CheckMe is defined!
\else
CheckMe is NOT defined
\fi
我尝试过类似的东西:
\def\ifnotdef#1{\ifx \csname#1\endcsname \undefined}
但它不起作用。
答案1
\ifdef
由于 TeX 跟踪\else
和 的方式,您无法定义可以与嵌套条件一起使用的宏\fi
。使用如下简单的定义
\def\ifdef#1{\ifx#1\undefined}
可以肯定地说
\ifdef\CheckMe
\string\CheckMe\space is not defined
\else
\string\CheckMe\space is defined
\fi
但诸如此类的结构
\ifnum\Acount=\Bcount
something else
\else
\ifdef\CheckMe
\string\CheckMe\space is not defined
\fi
\fi
如果\Acount
等于\Bcount
,则会中断,留下一个游离的\fi
: 将\else
与第一个 匹配\fi
,而不是第二个,因为 TeX 不会扩展在条件的真或假分支中跳过的标记;由于\ifdef
是一个宏而不是一个条件,所以不匹配会困扰你。
一种解决方法(追溯到 Knuth 本人)是以下列方式定义宏:
\def\isundefined#1{TT\fi\ifx#1\undefined}
并将其称为
\if\isundefined\CheckMe
\string\CheckMe\space is not defined
\else
\string\CheckMe\space is defined
\fi
这也适用于嵌套条件,因为 TeX 会看并将其\if
与正确的\else
或进行匹配\fi
。展开后,\if TT\fi
将不执行任何操作,将控制权留给以下\ifx
。
如果允许使用 e-TeX,则有一个\ifdefined
条件可以避免选择宏名称并相信它将保持未定义:
\ifdefined\CheckMe
\string\CheckMe\space is defined
\else
\string\CheckMe\space is not defined
\fi
(注意条件的逆转)。
答案2
稍微改变你的定义,你会得到 Knuth 的\ifundefined
:
\def\ifundefined#1{\expandafter\ifx\csname#1\endcsname\relax}
它有一些限制,但似乎是你需要的。
这里http://www.gust.org.pl/projects/pearls/2006p/index_html(检查是否已定义,Bernd Raichle 没有副作用)您可以找到更深层次的方法,并附有评论。