我创建了一个宏,它只是将一个项目放入序列中。现在我想检查该项目是否在序列中。我尝试使用该\prg_new_conditional:Npnn
函数创建一个谓词,但遇到了Missing number
错误。
编辑:
\if_predicate:w
我改为使用属性列表,以便拥有可扩展的宏。对于和,错误仍然出现\docvar_key_defined:nTF
。
版本 2:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g_docvar_defined_prop
\DeclareDocumentCommand \definedocvar {o m} {
\prop_gput_if_new:Nnn \g_docvar_defined_prop {#2} {}
}
\prg_new_conditional:Npnn \docvar_key_defined:n #1 {p, T, F, TF}
{
\prop_if_in:NnTF \g_docvar_defined_prop #1 {\prg_return_true:} {\prg_return_false:}
}
\ExplSyntaxOff
\begin{document}
\definedocvar{title}
\ExplSyntaxOn
\if_predicate:w \docvar_key_defined_p:n { title }
Title exists
\else:
Title doesn't exist.
\fi:
%\docvar_key_defined:nTF {title} {Title exist} {Title doesn't exist}
\ExplSyntaxOff
\end{document}
有人可以稍微解释一下 expl3 中的布尔逻辑是如何工作的吗?
答案1
由于谓词可以在之后使用\if_predicate:w
,因此谓词必须是可扩展的。这意味着它们不能使用任何改变任何变量值的代码。
在内部,\seq_if_in:NnTF
需要执行赋值,因为这是测试项目(所寻找的)是否与序列中的内容精确匹配的唯一方法(比较标记,而不仅仅是字符串表示中的字符)。因此\seq_if_in:NnTF
不能用于定义谓词。
属性列表在将键转换为字符串(忽略类别代码)后存储它们。事实证明,这允许可扩展地比较键,因此\prop_if_in:NnTF
是可扩展的。这就是为什么我们在评论中建议将“文档变量”存储在属性列表中。
然后缺少一对括号:在编写\prop_if_in:NnTF \l_my_prop {#1}
定义时,括号#1
是必需的,否则只有第一个标记#1
才会被当作在属性列表中搜索的键。