为什么人们在 \newcommand 中的控制序列周围使用括号?

为什么人们在 \newcommand 中的控制序列周围使用括号?

我在 LaTeX 的每一篇介绍性材料和许多其他人(事件专家)的代码中都看到,该\newcommand命令是通过将第一个参数括在括号中来使用的,即使在我看来这似乎是不必要的。

括号与传递给 LaTeX 命令的参数的通常方式一致(因为通常即使参数由单个标记组成也会使用括号,以保持一致性和清晰度),但在这种情况下,它们在我看来非常丑陋,在我看来它们降低了可读性。

但这些只是观点,而问题却是技术性的:技术的写这篇文章的原因:

\newcommand{\mycmd}[1]{Hello #1}

而不是这样:

\newcommand\mycmd[1]{Hello #1}

答案1

正如 LaTeX 书中所述,官方的 Latex 语法只使用括号形式,并且同样总是使用x^{2}而不是x^2

但是,对于必须是单个标记的参数(例如 的第一个参数),无括号形式可以正常工作\newcommand。这实际上也是受支持的语法,您会发现 LaTeX 项目团队使用这种样式的许多示例。

当然,从技术上讲,即使参数不一定是单个标记,删除括号也是可行的,人们会\frac12选择而不是\frac{1}{2},甚至,x^\frac12而不是,x^{\frac{1}{2}}但实际上,他们不应该......

答案2

这两个命令之间没有区别。我想这只是个人喜好问题。我更喜欢带括号的版本。它对我来说看起来更一致,它是由我的 IDE 的自动完成功能提供给我的,而\newcommand*{\mycmd}[1]{Hello #1}我在本例中使用的带星号的版本对我来说似乎更容易阅读。我在最后一句中使用了三次“对我来说”...这清楚地表明您可以选择任何您喜欢的版本。

我对这两个命令进行了一些测试,没有发现任何差异。由于命令命名规则非常严格,因此将括号分开不会造成任何问题。

答案3

当 TeX “抓取”未定界参数时,前导空格标记会被丢弃,最外层的括号(由类别 1(开始组)的显式字符标记和类别 2(结束组)的匹配显式字符标记组成的一对)会删除(如果存在)。如果未定界参数由多个标记组成,则必须将这些标记嵌套到另一层括号中,而这层括号又被视为被删除的最外层括号。

例如,以下代码序列产生相同的结果(\processtwo定义的方式是控制序列由点分隔而参数不受分隔 - 这样,第一个参数前面的空格不会被 TeX 的读取装置跳过,而是被标记为空格标记):

\def\processtwo.#1#2{%
  \def\tempa{FirstArg:|#1| SecondArg:|#2|}%
  \par{\tt\meaning\tempa}%
}
\processtwo.AB
\processtwo. AB
\processtwo.A B
\processtwo. A B
\processtwo.{A}B
\processtwo. {A}B
\processtwo.{A} B
\processtwo. {A} B
\processtwo.A{B}
\processtwo. A{B}
\processtwo.A {B}
\processtwo. A {B}
\processtwo.{A}{B}
\processtwo. {A}{B}
\processtwo.{A} {B}
\processtwo. {A} {B}
\bye

当 TeX “抓取”一个分隔参数时,不会删除前导空格标记。如果整个参数被括在括号中 — — 即,括在由类别 1(开始组)的显式字符标记和类别 2(结束组)的匹配显式字符标记组成的括号中,则最外层的括号会被删除。

例如,以下代码序列并非都导致相同的结果(\processtwo以控制序列和参数由点分隔的方式定义。通过分隔控制序列,还可以确保 TeX 的读取装置不会跳过第一个参数前面的空格,而是将其标记为空格标记):

\def\processtwo.#1.#2.{%
  \def\tempa{FirstArg:|#1| SecondArg:|#2|}%
  \par{\tt\meaning\tempa}%
}
\processtwo.A.B.
\processtwo.{A}.{B}.
\processtwo.{A}.B.
\processtwo.A.{B}.
\medskip
\processtwo.A. B.
\processtwo.{A}. B.
\medskip
\processtwo. A.B.
\processtwo. A.{B}.
\medskip
\processtwo. {A}.B.
\processtwo. {A}.{B}.
\medskip
\processtwo.{A}. {B}.
\processtwo.A. {B}.
\medskip
\processtwo. A. B.
\medskip
\processtwo. {A}. B.
\medskip
\processtwo. A. {B}.
\medskip
\processtwo. {A}. {B}.
\bye

\newcommand本身就是一个宏。第一个参数(在可选的 之后*)表示要定义的控制序列标记。LaTeX 将该参数视为由单个标记(单个控制序列标记)组成的无界参数。因此,该参数/标记是否嵌套在括号中没有区别。

但在处理括号分隔的参数(→ 带#{- 符号的参数文本)时,括号很重要。通常从用户手册中描述的语法来看,用户级宏的参数是作为未分隔的参数处理还是作为括号分隔的参数处理并不明显。例如,color-package 通过括号分隔的参数进行了大量处理。为了了解这种微妙之处,您需要查看 .sty 文件或注释的源代码。

相关内容