在 xparse 中测试空值

在 xparse 中测试空值

按照以下答案的建议这个问题,我使用以下代码

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\IfNoValueOrEmptyTF}{mmm}
{
 \IfNoValueTF{#1}
  {#2} % true
  {\tl_if_empty:nTF {#1} {#2} {#3}} % false
}
\ExplSyntaxOff

测试是否存在或者是否为空值。

一个相应的宏是

\NewDocumentCommand \sidenotemark { o } {%
\IfNoValueOrEmptyTF{#1}%
{%...

但是,我把代码改成了

\NewDocumentCommand \sidenotemark { O{} } {%
\IfEmptyTF{#1}%
{%...

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\IfEmptyTF}{mmm}
{ \tl_if_empty:nTF {#1} {#2} {#3}
}
\ExplSyntaxOff

因为我觉得它更具可读性。

但是,中没有\IfEmptyTF和,这似乎很奇怪。\IfNoValueOrEmptyTFxparse

有没有更好的方法来实现所描述的行为(同时保留可选参数而不是键值对?)。

- - 更新 - -

很难让一个示例变得有用且简洁。我希望这能让你更清楚。在下一个示例中,我希望 和 具有相同的empty行为no value

\documentclass{book}

\usepackage{xparse}
\usepackage{lipsum}
\usepackage{marginnote}

\ExplSyntaxOn
    \DeclareExpandableDocumentCommand{\IfNoValueOrEmptyTF}{mmm}
    {
     \IfNoValueTF{#1}
      {#2} % true
      {\tl_if_empty:nTF {#1} {#2} {#3}} % false
    }
\ExplSyntaxOff


\NewDocumentCommand \placemarginal {o m}
{
\IfNoValueOrEmptyTF{#1}
{\marginpar{#2}} % is empty, use marginpar
{\marginnote{#2}[#1]} % is not empty, use marginnote
}

\begin{document}
float\placemarginal{\lipsum[1]}

float\placemarginal[]{test2}

fix\placemarginal[0pt]{test}

\end{document}

答案1

从概念上讲,未给出的可选参数与空的可选参数不同。根据接口定义的语义,给出没有内容的可选参数可能是错误的。一个简单的例子是\makebox

\documentclass{article}
\begin{document}
\makebox[]{foo}
\end{document}

这导致

! Missing number, treated as zero.
<to be read again> 
                   \relax 

因为可选参数(如果给出)必须是维度(数字 + 单位:只添加整数也会失败!)。因此,测试是否给出了参数与测试参数的内容完全不同。

在所描述的例子中,我们想要的是路径的变化,这取决于参数是否为空,而不是参数是否给出。(事实上,我们实际上似乎想要的是一个测试来检查参数是否是一个维度,但这要复杂得多。)因此

\NewDocumentCommand \placemarginal {o m}
  {
    \IfNoValueOrEmptyTF{#1}
      {\marginpar{#2}} % is empty, use marginpar
      {\marginnote{#2}[#1]} % is not empty, use marginnote
  }

似乎不太正确:o只有当存在/不存在测试有用时才有意义。在这里,“类似 LaTeX2e”的可选项更有意义

\ExplSyntaxOn % As I'm using \tl_if_blank:nTF
\NewDocumentCommand \placemarginal {O{} m}
  {
    \tl_if_blank:nTF {#1}
      {\marginpar{#2}} % is empty, use marginpar
      {\marginnote{#2}[#1]} % is not empty, use marginnote
  }

如果你想在调用之前强制出现错误,\marginnote那么你可以尝试类似

\ExplSyntaxOn % As I'm using \tl_if_blank:nTF
\NewDocumentCommand \placemarginal {O{} m}
  {
    \dim_compare:nNnTF { #1  + 0pt } = \c_zero_dim
      {\marginpar{#2}} % is empty, use marginpar
      {\marginnote{#2}[#1]} % is not empty, use marginnote
  }

其作用与空白测试相同,但如果#1不是维度,也会发出警告。

相关内容