不需要 \makeatletter 吗?

不需要 \makeatletter 吗?

在输入一些可能在 LaTeX 中产生错误的小例子时(例如具有典型 LaTeX 错误的文档),我尝试了以下方法:

\documentclass{article}
\def\my@macro#1{-#1-}% This is magic
\begin{document}
\my@macro{hi}% Print -hi-
\end{document}

由于我几乎虔诚地用和@来概括-symbol 的定义和/或用法\makeatletter\makeatother参见做什么\makeatletter\makeatother做什么?),并且latex.ltx问题\makeatother实际上出现在倒数第四行,我认为这会闪现错误。

但事实并非如此。

我不仅能够定义宏,而且定义后还可以毫无问题地使用它。为什么会这样?

这里有一个线索,虽然我不知道为什么,但我使用的是 TeX\def语法,而\newcommand不是產生錯誤。

答案1

您的定义定义了一个宏\my,该宏后面必须跟@macro一个参数(可以是单个标记或括号组)。这样就可以得到结果。

之所以这样工作,是因为通常@不是字母(而是符号\catcode12),所以它会结束“宏名称”,但它随后会成为参数文本的一部分,参数文本是名称之后直到{替换文本开始的所有内容。您可以按如下方式测试它:

\show\my
\my @macro {hi}  % should work too
\my {hi}         % error

LaTeX 会\newcommand抱怨,因为它以不同的方式构建宏定义并且不允许分隔参数。

答案2

您正在定义由以下标记组成的\my奇怪控制序列<parameter text>

@ 1211 a 11 c 11 r 11 o 11 #1

(我已将类别代码作为下标)。

这意味着\my 必须紧接着@macro,然后是争论。

你可以尝试写作,之后\begin{document}

\my @macro{hi}
\def\my@differentmacro#1{#1!}
\my@differentmacro{Uh}
\my@macro{ERROR}

第一行将被接受并打印

-你好-

因为控制序列名称后的空格总是被忽略。

第二行将被接受并执行请求的定义;第三行将打印

呃!

而第四个会出现错误:

! Use of \my doesn't match its definition.

确实\my现在需要@differentmacro它。

怎么回事?如果的类别代码@是 12 ( \makeatother),则扫描器在发现非字母(字母的类别代码为 11)\def\my@macro#1{-#1-}时将立即停止控制序列名称,因此它将把第一个括号之前的所有内容视为。@<parameter text>

\makeatletter生效时,@ 一封信,所以

\def\my@macro#1{-#1-}

宏的名称将是\my@macro,参数文本将简单地为#1

相关内容