“条件”是包的名称吗?

“条件”是包的名称吗?

在一些包中我看到过类似这样的构造:

\if\blank{\myMacro}%
  %do something
\else
  %do something else
\fi

我喜欢它,我想用它来测试对宏的调用是否产生空结果。我在我的代码中尝试过它,发现宏\blank只有在我添加到序言中时才起作用\usepackage{conditionals}

现在问题来了:我尝试查找打包“条件”的文档,但我的 MiKTeX 发行版上似乎没有安装(或可用)这样的包。我尝试在 MiKTeX 包管理器中进行搜索,但没有找到。这是为什么?我在哪里可以找到该包的文档?

边注:我正在寻找文档,因为我想找到相反的宏,例如\notblank

答案1

包中的宏conditionals由 Donald Arsenau 编写,根据包中的注释,它们属于公共领域。

因此它们在这里:

{\catcode`\!=8 % funny catcode so ! will be a delimiter
 \catcode`\Q=3 % funny catcode so Q will be a delimiter
\long\gdef\given#1{88\fi\Ifbl@nk#1QQQ\empty!}
\long\gdef\blank#1{88\fi\Ifbl@nk#1QQ..!}% if null or spaces
\long\gdef\nil#1{\IfN@Ught#1* {#1}!}% if null
\long\gdef\IfN@Ught#1 #2!{\blank{#2}}
\long\gdef\Ifbl@nk#1#2Q#3!{\ifx#3}% same as above
}

如果要在文档中使用代码,请用 和 括起来\makeatletter\makeatother

让我们看看当\if\blank{<tokens>}<TRUE>\else<FALSE>\fi扩展时会发生什么,重点关注部分\if\blank{<tokens>}。通常<tokens>会成为宏的参数。

必须知道,它\if会继续扩展,直到找到后面两个不可扩展的标记,然后比较它们的字符代码。因此,第一次扩展是

\if88\fi\Ifbl@nk<tokens>QQ..!

并与\if进行比较;关闭条件,它什么都不做!它只是允许构造与其他条件嵌套。现在 TeX 发现88\fi

\Ifbl@nk<tokens>QQ..!

如果<tokens>仅由(零个或多个)空格组成,则搜索第一个(未分隔的)参数\Ifbl@nk将绕过它们。在这种情况下,参数#1将为Q3(下标表示有趣的类别代码),参数#2将为空,参数#3将为..,因此最终我们将得到

\ifx..<TRUE>\else<FALSE>\fi

这将选择真正的分支。现在假设 中<tokens>有一个非空格标记。第一个这样的标记(或括号组)将成为 的第一个参数\Ifbl@nk,而其余的将成为 参数#2。因此,最多!8 个都将成为 参数#3,因此Q..TeX 会认为

\ifx Q..<TRUE>\else<FALSE>\fi

而比较的是Q3.12,它们是不同的,所以尾随的周期会随着忽略真分支而消失,并遵循假分支。

请注意,没有<tokens>发生任何扩展;这个标记列表完全消失了。

使用\if\given{<tokens>},在\if88\fi消失之后,TeX 会发现

\Ifbl@nk<tokens>QQQ\empty!

同样,如果<tokens>由(零个或多个)空格组成,这些空格将被绕过,参数#1将为Q,参数#2将为空,参数#3将为Q\empty;因此 TeX 将看到

\ifx Q\empty<TRUE>\else<FALSE>\fi

因此遵循错误分支。如果<tokens>第一个(或第一个括号组)中出现一些非空白标记,则为#1,其余的将是#2,并且#3将是QQ\empty。在这种情况下,TeX 将看到

\ifx QQ\empty<TRUE>\else<FALSE>\fi

因此\empty开始了真正的分支,但是它的扩展是空的并且(几乎)无关紧要。

最后,\if\nil{<tokens>}。在\if88\fi我们得到

\IfN@Ught<tokens>* {<tokens>}!

<tokens>现在将引导空白标记不是被绕过,因为 的第一个参数\IfN@Ught由空格分隔。前导空格后的所有内容都将成为,#2并且至少*在那里,因此\blank{#2}将返回 false。如果 中的第一个标记<tokens>不是空格,至少{<tokens>}将成为 的一部分#2,因此\blank{#2}也将返回 false。

因此唯一\if\nil{<tokens>}能返回 true 的方法是它<tokens>确实是空的(根本没有标记)。

确实是非常聪明的宏!

方案 1

使用etoolbox提供的

\ifstrempty{<tokens>}{<true>}{<false>}
\ifblank{<tokens>}{<true>}{<false>}
\notblank{<tokens>}{<true>}{<false>}

相当于

\if\nil{<tokens>}
\if\blank{<tokens>}
\if\given{<tokens>}

分别,但语法不同(没有\else\fi)。文档的脚注etoolbox说宏基于 Donald Arsenau 的代码,这很可能与中的相同conditionals.sty

方案 2

在 LaTeX3 中也有类似的结构:

\tl_if_empty:nTF {<tokens>}{<TRUE>}{<FALSE>}

等同于\if\nil{<tokens>},而

\tl_if_blank:nTF {<tokens>}{<TRUE>}{<FALSE>}

与 相同\if\blank{<tokens>}。当然语法与 中的语法类似etoolbox。实际上不需要 的类似物\if\given{<tokens>}

答案2

条件包实际上提供了与空白相反的内容:

 \if\blank{ } --- checks if parameter is blank (Spaces count as blank)
 \if\given{ } --- checks if parameter is not blank: like \if\blank{}...\else
 \if\nil{ }   --- checks if parameter is null (spaces are NOT null)

如果您使用查看文档的日志文件,\usepackage{conditionals}您将看到文件的完整路径。每次 TeX 打开文件时,它都会将 写入(日志文件,后跟打开的文件的路径,)一旦读取完文件,它就会将 写入日志文件。

相关内容