在输入一些可能在 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
一个参数(可以是单个标记或括号组)。这样就可以得到结果。
之所以这样工作,是因为通常@
不是字母(而是符号\catcode
12),所以它会结束“宏名称”,但它随后会成为参数文本的一部分,参数文本是名称之后直到{
替换文本开始的所有内容。您可以按如下方式测试它:
\show\my
\my @macro {hi} % should work too
\my {hi} % error
LaTeX 会\newcommand
抱怨,因为它以不同的方式构建宏定义并且不允许分隔参数。
答案2
您正在定义由以下标记组成的\my
奇怪控制序列<parameter text>
@ 12米11 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
。