按照以下答案的建议这个问题,我使用以下代码
\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
和,这似乎很奇怪。\IfNoValueOrEmptyTF
xparse
有没有更好的方法来实现所描述的行为(同时保留可选参数而不是键值对?)。
- - 更新 - -
很难让一个示例变得有用且简洁。我希望这能让你更清楚。在下一个示例中,我希望 和 具有相同的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
不是维度,也会发出警告。