我正在用xparse
的布尔标记处理实现一个命令
\NewDocumentCommand{\op}{s o t' t. t^ g}{
% Here I need to check for
% (#3 || #4 || #5) && !(#3 && #4 && #5)
}
我想避免所有\IfBooleanTF
组合,而是通过 进行检查\bool_if:nTF
。也就是说,传递给函数的布尔标记不应该同时全部为真或假。使用\IfBooleanTF
for进行测试
(p∨q∨r)∧¬(p∧q∧r)
非常繁琐(高阶异或,XOR),尤其是在给出更多这样的参数时。
我可以根据 xparse 的测试在 expl3 中分配布尔“变量”,例如,
\IfBooleanTF{#1}
{\bool_set_true:N \l_first_arg_bool}
{\bool_set_false:N \l_first_arg_bool}
没关系。但是有没有办法xparse
直接访问为参数设置的布尔标志?
答案1
依赖实现细节可能不是一个好主意,但是xparse
定义
\cs_new_eq:NN \BooleanFalse \c_false_bool
\cs_new_eq:NN \BooleanTrue \c_true_bool
这意味着您的参数所表示的布尔值只是expl3
可以直接进入的常规布尔值\bool_if:nTF
。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \op { s o t' t. t^ g }
{
\bool_if:nTF { (#3 || #4 || #5) && !(#3 && #4 && #5) }
{ True }
{ False }
}
\ExplSyntaxOff
\begin{document}
\op*[foo]'.^{bar} % False
\end{document}
答案2
实现这个 XOR 相当容易:
\int_new:Nn \l_foo_bad_check_int
\NewDocumentCommand{\bad}{t' t. t^}
{
\int_zero:N \l_foo_bad_check_int
\IfBooleanTF { #1 } { \int_incr:N \l_foo_bad_check_int }
\IfBooleanTF { #2 } { \int_incr:N \l_foo_bad_check_int }
\IfBooleanTF { #3 } { \int_incr:N \l_foo_bad_check_int }
\int_compare:nTF { 0 < \l_foo_bad_check_int < 3 }
{ Good }
{ Bad }
}
另一方面,这样的语法甚至对宏创建者来说也会造成混淆,尤其是带有如下参数说明符的情况
s o t' t. t^ g
和六選配零件。