宏和控制序列有什么区别?

宏和控制序列有什么区别?

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没有宏)和没有定义的活动字符既不是宏也不是控制序列。

看一下定义:

如果我们看一下这两个条件的定义,我们会发现:

  1. \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,这使得它们彼此相等,并且与所有字符标记不相等。

  2. \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}

enter image description here

相关内容