通过 latex3 expl3 访问 xparse 的 \BooleanTrue

通过 latex3 expl3 访问 xparse 的 \BooleanTrue

我正在用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。也就是说,传递给函数的布尔标记不应该同时全部为真或假。使用\IfBooleanTFfor进行测试

(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

選配零件。

相关内容