考虑以下命令定义:
\NewDocumentCommand{\reportexpansion}{ m }{
\bgroup
\tl_set:Nn \l_tmpa_tl { #1 }
{ \ttfamily \tl_to_str:V \l_tmpa_tl } \space is \space
\exp_args:No \cs_if_exist:NTF { \tl_head:w #1 {} \q_stop } {
\tl_set:Nx \l_tmpb_tl { \l_tmpa_tl }
{ \ttfamily \tl_to_str:V \l_tmpb_tl } .
} {
undefined.
}
\egroup
}
这可以按原样工作,但假设我想在 的参数中使用\l_tmpa_tl
而不是。 (在提示此问题的原始代码中,条件位于循环体内,因此标记列表是#1
\cs_if_exist:NTF
\ior_map_variable:NNn
仅有的可作为 tl 变量的值。)
\exp_args:No \cs_if_exist:NTF { \tl_head:V \l_tmpa_tl }
不起作用,因为的内容\l_tmpa_tl
被扩展了;如果第一个标记是未定义的宏,我们会在\cs_if_exist:NTF
有机会采取行动之前收到“未定义的控制序列”错误。interface3 文档确实特别警告\tl_head:n
及其变体会扩展标记列表的内容,并且\tl_head:w
应该在 o 类型参数中使用,但是...
\exp_args:No \cs_if_exist:NTF { \tl_head:w \l_tmpa_tl {} \q_stop }
... 也不起作用,因为现在\tl_head:w
和之间的材料\q_stop
根本没有扩展,并且\cs_if_exist:NTF
应用于标记\l_tmpa_tl
,这是一个定义的控制序列,无论其内容是什么。显然要尝试修复的是
\exp_args:No \cs_if_exist:NTF
{ \exp_args:NV \tl_head:w \l_tmpa_tl {} \q_stop }
但这并没有完全执行\exp_args:NV
,最终导致 的\cs_if_exist:NTF
第一个参数为\exp_after:wN \tl_head:w \exp_after:wN {\l_tmpa_tl }{}\q_stop
,这显然不起作用。这是我目前为止得到的。
就我今天想要的这个内容而言,是保证标记列表的头部将是一个控制序列,但为了稳健性,我会理想情况下喜欢有是\tl_if_head_is_cs
和\tl_if_head_is_cs_that_exists
,以及:V
所有\tl_if_head_*
谓词的变体,保证不会扩展令牌列表的内容。