在LaTeX3 接口我们发现:
\token_if_macro:NTF <token> {<true code>} {<false code>}
测试是否
<token>
是 TeX 宏。\token_if_cs:NTF <token> {<true code>} {<false code>}
测试是否是
<token>
控制序列。
所以我问自己:有什么区别?
答案1
简而言之:
控制序列是所有以 escapechar 开头的标记(通常是\
)。有一个例外:已分配给非活动字符标记(如\bgroup
)的控制序列标记是不是意义上的控制序列\token_if_cs:N(TF)
。
宏\def
都是用和 朋友定义的所有控制序列或活动字符。
例子(根据问题的条件):
\newcommand
或者\documentclass
同时是控制序列和宏,\def
、\relax
或\dimen@
是控制序列但不是宏,并且~
是宏但不是控制序列\bgroup
既不是宏也不是控制序列。
(假设标准定义)。未定义的控制序列(例如,\@undefined
没有宏)和没有定义的活动字符既不是宏也不是控制序列。
看一下定义:
如果我们看一下这两个条件的定义,我们会发现:
\token_if_cs:N(TF)
:\prg_new_conditional:Npnn \token_if_cs:N #1 { p , T , F , TF } { \if_catcode:w \exp_not:N #1 \scan_stop: \prg_return_true: \else: \prg_return_false: \fi: }
\scan_stop:
这意味着每个与(\relax
)具有相同类别代码的标记都会被\if_catcode:w
(\ifcat
) 看到。引用TeX 按主题分类即“特殊类别代码16”。TeX 会扩展后面的内容,
\ifcat
直到找到两个不可扩展的标记;然后根据它们的类别代码进行比较。控制序列标记被认为具有类别代码 16,这使得它们彼此相等,并且与所有字符标记不相等。\token_if_macro:N(TF)
:\use:x { \prg_new_conditional:Npnn \exp_not:N \token_if_macro:N ##1 { p , T , F , TF } { \exp_not:N \exp_after:wN \exp_not:N \__token_if_macro_p:w \exp_not:N \token_to_meaning:N ##1 \tl_to_str:n { ma : } \exp_not:N \q_stop } \cs_new:Npn \exp_not:N \__token_if_macro_p:w ##1 \tl_to_str:n { ma } ##2 \c_colon_str ##3 \exp_not:N \q_stop } { \if_int_compare:w \__str_if_eq_x:nn { #2 } { cro } = \c_zero \prg_return_true: \else: \prg_return_false: \fi: }
检查是否
\meaning<token>
包含字符串macro:
(所有类别代码 12 个字符),如果令牌已用\def
及其朋友定义,则为真。
一个小的测试文件:
备注:下面的测试宏\tokentest
实际上并没有抓取第一个标记,而是用标准的非分隔参数定义的。
\documentclass[twocolumn]{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\newcommand*\cs[1]{\expandafter\texttt\expandafter{\string#1}}
\ExplSyntaxOn
\cs_new_protected:Npn \token_check:N #1
{
\noindent \cs #1 ~ is~
\token_if_macro:NF #1 { \emph {not} ~ }
a~ macro \\
\cs #1 ~ is~
\token_if_cs:NF #1 { \emph {not} ~ }
a~ control~ sequence \par
meaning: ~ \expandafter \texttt \expandafter { \meaning #1 } \par
\medskip
}
\NewDocumentCommand \tokencheck {m}
{ \token_check:N #1 }
\ExplSyntaxOff
\def\a{}
\def\b#1{}
\long\def\c{}
\protected\def\d{}
\def\1{}
\begin{document}
\makeatletter
\subsection*{Defined with \cs\def}
\tokencheck\a
\tokencheck\b
\tokencheck\c
\tokencheck\d
\tokencheck\1
\tokencheck~
\subsection*{Undefined}
\tokencheck\@undefined
\newpage
\subsection*{Primitives}
\tokencheck\def
\tokencheck\relax
\tokencheck\fi
\tokencheck\ \relax
\subsection*{Defined with \cs\newbox, \cs\chardef, \dots}
\tokencheck\&
\tokencheck\strutbox
\tokencheck\dimen@
\tokencheck\skip@
\makeatother
\end{document}