有什么原因导致我无法更改命令内的 catcodes 吗?

有什么原因导致我无法更改命令内的 catcodes 吗?

我有一个非常简单的问题。当我这样做时:

\catcode`\@=0
\catcode`\\=11
@mycommand{a}
@catcode`@\=0
\catcode`\@=11

它运行完美,调用\mycommand正确。然而,当我尝试\mycommand用类似的技巧定义时:

\newcommand\mycommand[1]{
  \catcode`\@=0
  \catcode`\\=11
  @textbf{Hello #1}
  @catcode`@\=0
  \catcode`\@=11
}

编译停止并给出*提示。如果我输入Ctrl+ D,它会终止而不产生任何输出。事实上,更改命令中的 catcode 似乎没有任何效果,因为下面的代码运行正常(而据我所知,它不应该这样):

\newcommand\mycommand[1]{
  \catcode`\@=0
  \catcode`\\=11
  \textbf{Hello #1}
}

谁能向我解释一下发生了什么事?

答案1

当你说

\newcommand\mycommand[1]{
  \catcode`\@=0
  \catcode`\\=11
  @textbf{Hello #1}
  @catcode`@\=0
  \catcode`\@=11
}

TeX 将以下标记存储为替换文本\mycommand(• 项目符号分隔标记并使用空格以提高可读性,<sp>表示空格标记):

<sp> • \catcode • ` • \@ • = • 0 • <sp> •
\catcode • ` • \\ • = • 1 • 1 • <sp> •
@ • * t • e • x • t • b • f • { • H • e • l • l • o • <sp> • #1 • } • 
@ • c • a • t • c • o • d • e • ` • @ • \= • 0 • <sp> •
\catcode • ` • \@ • = • 1 • 1 • <sp>

在哪里

  • @,,,`并且类别代码为12 01=
  • {}分别具有类别代码 1 和 2,
  • <sp>类别代码为 10,
  • 这些字母的类别代码为 11。

类别代码为冻结一旦它们进入 TeX 的嘴里。当宏\mycommand{Worlds}展开时,TeX 将更改@从那时起它将吸收的所有内容的类别代码(尊重组),但这不能以任何方式改变已经标记的内容,例如标记序列

@ • * t • e • x • t • b • f

已存储。

将会打印出精确的内容

@textbfHello World @catcode'@0

(0 上会有一个横线)并且 TeX 不会有任何类别代码为 0 的字符,这意味着它无法识别命令。

我将用 Plain TeX 来做一个例子,它更容易打印,但本质上是等效的。我只会\csname bye\endcsname在游戏结束时添加以下内容:

\def\mycommand#1{
  \catcode`\@=0
  \catcode`\\=11
  @textbf{Hello #1}
  @catcode`@\=0
  \catcode`\@=11
  \csname bye\endcsname
}

\mycommand{World}

在此处输入图片描述

请记住,当 TeX 执行 时\def,它会完全禁用宏扩展和它吸收的宏名称、参数文本和替换文本的标记的命令执行。它只会扩展替换文本中的标记,但在执行 时不会再次执行它们\edef

相关内容