是否可以检查一个标记是否是分隔符,即,,,,,,等(
,)
而|
无需在条件中直接检查它们每一个?\vert
\langle
\rangle
定界符的结构在这里有很好的描述:https://tex.stackexchange.com/a/296650/213149. 它似乎使用\delimiter
命令
所以我的问题是如何使用纯 TeX 或 LaTeX3 以某种通用的方式检测这样的分隔符。
例如,我想要自定义宏\isDelimiter{...}
来打印true
或false
在文档中显示它的参数是否是分隔符。
答案1
我不确定这是否能解决你的\veca
问题。无论如何……
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\isDelimiterTF}{mmm}
{
\antshar_isdel:Nnn #1 { #2 } { #3 }
}
% first check whether #1 is a control sequence
\cs_new:Nn \antshar_isdel:Nnn
{
\token_if_cs:NTF #1
{
\__antshar_isdel_cs:Nnn #1 { #2 } { #3 }
}
{
\__antshar_isdel_char:Nnn #1 { #2 } { #3 }
}
}
% it is a control sequence; first check the two exceptional cases \{ and \}
% which return true; otherwise go on: if the token is not expandable return false
\cs_new:Nn \__antshar_isdel_cs:Nnn
{
\str_case:nnF { #1 }
{
{\{}{#2}
{\}}{#2}
}
{
\token_if_expandable:NTF #1
{
\__antshar_isdel_csexp:Nnn #1 { #2 } { #3 }
}
{
#3
}
}
}
% the token is expandable, access its expansion
\cs_new:Nn \__antshar_isdel_csexp:Nnn
{
\__antshar_isdel_exp:onn { #1 } { #2 } { #3 }
}
% if the expansion begins with \delimiter return true, otherwise false
\cs_new:Nn \__antshar_isdel_exp:nnn
{
\__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }
}
\cs_generate_variant:Nn \__antshar_isdel_exp:nnn { o }
\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
{
\token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
}
% when the token is a character, look at its \delcode;
% if positive return true, otherwise false
\cs_new:Nn \__antshar_isdel_char:Nnn
{
\int_compare:nTF { \delcode`#1 > 0 } { #2 } { #3 }
}
\ExplSyntaxOff
\begin{document}
\verb|a|: \isDelimiterTF{a}{T}{F}
\verb|(|: \isDelimiterTF{(}{T}{F}
\verb|]|: \isDelimiterTF{]}{T}{F}
\verb|\langle|: \isDelimiterTF{\langle}{T}{F}
\verb-\|-: \isDelimiterTF{\|}{T}{F}
\verb|\{|: \isDelimiterTF{\{}{T}{F}
\verb|\lbrace|: \isDelimiterTF{\lbrace}{T}{F}
\verb|\mbox|: \isDelimiterTF{\mbox}{T}{F}
\end{document}
我们如何识别控制序列何时是分隔符?其第一级扩展应以 开头,\delimiter
或者,如果是字符,则应\delcode
为正数。
因此,检查字符是显而易见的。对于控制序列,我们首先需要查看它是否可扩展。但我们还需要注意有些特殊的\{
情况\}
,因此这些情况可以自行解决。
如果我们检查的控制序列不可扩展,则它不是分隔符(可能还有其他例外,例如\{
必须\}
使用某些字体包添加和)。如果它是可扩展的,我们通过调用来查看其第一级扩展
\__antshar_isdel_exp:onn { #1 } { #2 } { #3 }
因此o
参数类型将进行所需的一级扩展。这将变成
\__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }
的定义\__antshar_isdel_exp_aux:w
是
\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
{
\token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
}
因此,我们正在检查的控制序列扩展中的第一个标记变为#1
,其余的标记\q_nil
变为#2
。其余的,即#3
和#4
是 的真假文本\isDelimiterTF
。第一个参数是无分隔符的,因此它将以输入流中的第一个标记作为其参数;当 TeX 找到 时,第二个参数结束\q_stop
。
奇怪的\q_nil
是,如果你尝试,\isDelimiter{\empty}{T}{F}
扩展中将没有任何内容;在这种情况下,\q_nil
被视为#1
并且#2
是空的。但是,由于\q_nil
不是\delimiter
,所以一切都会顺利进行。