这与之前的问题类似(\IfValueT 的布尔参数周围的空格给出 -NoValue-),但该问题的答案涉及数学模式字符及其 catcode,而这个问题没有这样的问题。
考虑一下这个MWE:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\testing}{ o }
{%
\IfValueTF{ #1 }
{#1}
{false}
}%
\ExplSyntaxOff
\begin{document}
\testing
\end{document}
如果没有\ExplSyntaxOn...\ExplSyntaxOff
并且 周围没有任何空格,我会得到预期的结果( )。但是,如果我#1
在参数周围加上空格,我会得到,除非我还打开。这不可能像以前一样是数学模式问题或 catcode 问题,至少如果是的话我不明白。此外,如果我将参数设为强制而不是可选,则不会发生这种情况,但我仍然没有得到我期望的结果。在这种情况下发生了什么?我知道不需要,但我是否应该将其包括在内并将我的所有定义放在 里面?\IfValueTF{#1}
false
\IfValueTF{ #1 }
-NoValue-
\ExplSyntaxOn...\ExplSyntaxOff
\testing
false
\NewDocumentCommand
xparse
\ExplSyntaxOn...\ExplSyntaxOff
答案1
因为{ #1 }
和{#1}
是不同的,除非在标记阶段忽略空格。
使用标准类别代码,{ #1 }
有六个标记
{
1 <空格> 10 #
6 1
12 <空格> 10 }
2
具体来说,空格将位于宏的替换文本中,并且测试\IfValueTF{ #1 }
将始终返回 true,因为如果缺少可选参数,则传递的参数是<space>-NoValue-<space>
,这与-NoValue-
另一方面,在\ExplSyntaxOn
将空格的类别代码设置为 9 之后,此类字符将在标记化阶段被丢弃,除非它位于类别代码为 0 的字符(反斜杠)之后,因此在expl3
编程环境中,输入{ #1 }
只是四个标记
{
1 #
6 1
12 }
2
具体来说,在 之后\ExplSyntaxOn
,可以使用“反斜杠空格”并获取通常的标记(即输出中的空格)。行尾的“反斜杠空格”问题通过设置\endlinechar=32
(空格)解决:TeX 在开始标记化之前会从行中删除任何尾随空格,但在这种情况下,空格会重新插入为行尾字符。
答案2
正如大卫·卡莱尔 (David Carlisle) 指出的那样,问题在于 catcode 以及它们如何受到\ExplSyntaxOn
和 的影响\ExplSyntaxOff
。