通过 \let 获取分配给控制序列的字符的 catcode

通过 \let 获取分配给控制序列的字符的 catcode

\z给定一个像这样定义的控制序列\let\z=z,如何获取定义z时角色的catcode?\z

显而易见的解决方案

{\catcode`z=12 \global\let\z=z}
\the\catcode`\z

乍一看似乎有效,但它给出了错误的结果,11因为'\z它不是被解释为先前定义的控制序列,而只是字母字符代码的另一种表示z

使用不同的控制序列名称可以使其显而易见

{\catcode`z=12 \global\let\thez=z}
\the\catcode`\thez

当它失败时

! Improper alphabetic constant.

这个问题处理类似的问题,得到特点这种控制序列的代码,但我看不出有什么办法可以用它来解决这个问题,因为\meaning它只返回类别 12 和 10 的字符。

答案1

隐式字符不能处于活动状态,也不能具有 catcode 0、5、9、14 或 15。检查每种可能性:

\def\catcodeofimplicitchar#1{%
  \ifcat\noexpand#1\bgroup 1\else
  \ifcat\noexpand#1\egroup 2\else
  \ifcat\noexpand#1$3\else
  \ifcat\noexpand#1&4\else
  \ifcat\noexpand#1##6\else
  \ifcat\noexpand#1^7\else
  \ifcat\noexpand#1_8\else
  \ifcat\noexpand#1 10\else
  \ifcat\noexpand#1a11\else
  \ifcat\noexpand#1112\else
  -1\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}

\let\one={ \let\two=} \let\three=$
\let\four=& \let\six=# \let\seven=^
\let\eight=_ \let\eleven=z \let\twelve=0
\begingroup\def\\#1:{\global\let\ten= #1}\\ :\endgroup
\let\thirteen=~

{\tt\meaning\one}:
\catcodeofimplicitchar\one

{\tt\meaning\two}:
\catcodeofimplicitchar\two

{\tt\meaning\three}:
\catcodeofimplicitchar\three

{\tt\meaning\four}:
\catcodeofimplicitchar\four

{\tt\meaning\six}:
\catcodeofimplicitchar\six

{\tt\meaning\seven}:
\catcodeofimplicitchar\seven

{\tt\meaning\eight}:
\catcodeofimplicitchar\eight

{\tt\meaning\ten}:
\catcodeofimplicitchar\ten

{\tt\meaning\eleven}:
\catcodeofimplicitchar\eleven

{\tt\meaning\twelve}:
\catcodeofimplicitchar\twelve

{\tt\meaning\empty}:
\catcodeofimplicitchar\empty

\ifnum\catcodeofimplicitchar\one=1 GOOD\else BAD\fi

\bye

在此处输入图片描述

答案2

你确实想要和如何获取用 \let 定义的字符代码(!不正确的字母常量),但您需要使用文本\meaning。该示例涵盖三种情况(空格、字母、其他),并且可自然扩展到其他情况:

\long\def\getcatcode#1{%
  \expandafter\getcatcodeaux\meaning#1\stop
}
\edef\getcatcodeaux#1\stop{%
  \noexpand\getcatcodespace#1{}{}\detokenize{blank space}\noexpand\stop
  \noexpand\getcatcodeletter#1{}{}\detokenize{the letter}\noexpand\stop
  \noexpand\getcatcodeother#1{}{}\detokenize{the character}\noexpand\stop
}
\edef\temp{%
  \def\noexpand\getcatcodespace##1\detokenize{blank space}##2\noexpand\stop{%
    \noexpand\ifx\relax##1\relax
      10%
    \noexpand\fi
  }%
  \def\noexpand\getcatcodeletter##1\detokenize{the letter}##2\noexpand\stop{%
    \noexpand\ifx\relax##1\relax
      11%
    \noexpand\fi
  }%
  \def\noexpand\getcatcodeother##1\detokenize{the character}##2\noexpand\stop{%
    \noexpand\ifx\relax##1\relax
      12%
    \noexpand\fi
  }%
}
\temp

这些都是可扩展的,因此可以放入\catcode或类似的参数中。我没有添加任何防御性代码,以防\z这里有一个可能包含测试字符串、chardef 的宏,ETC。,但我们可以扩展这个想法。

相关内容