在一些包中我看到过类似这样的构造:
\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 发现8
8
\fi
\Ifbl@nk<tokens>QQ..!
如果<tokens>
仅由(零个或多个)空格组成,则搜索第一个(未分隔的)参数\Ifbl@nk
将绕过它们。在这种情况下,参数#1
将为Q
3(下标表示有趣的类别代码),参数#2
将为空,参数#3
将为..
,因此最终我们将得到
\ifx..<TRUE>\else<FALSE>\fi
这将选择真正的分支。现在假设 中<tokens>
有一个非空格标记。第一个这样的标记(或括号组)将成为 的第一个参数\Ifbl@nk
,而其余的将成为 参数#2
。因此,最多!
8 个都将成为 参数#3
,因此Q..
TeX 会认为
\ifx Q..<TRUE>\else<FALSE>\fi
而比较的是Q
3和.
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 打开文件时,它都会将 写入(
日志文件,后跟打开的文件的路径,)
一旦读取完文件,它就会将 写入日志文件。