我发现宏定义的常见风格有两个奇怪之处:
- 宏定义中的行以‘%’结束;
- 不是将宏名括在括号中。
例子:
\newcommand\examplemacro{%
\somecommand%
\othercommand%
}
首先作为一名软件工程师,其次是一名 LaTeX 用户,我期望:
\newcommand{\examplemacro}{
\somecommand{}
\othercommand{}
}
采用前一种方式有什么理由吗,或者仅仅是习惯问题?
答案1
某些行末尾的注释会删除行尾字符插入的空格(通常会变成空格)。宏(控制字)后不需要注释,因为它们会自行删除空格。宏后不需要括号。{}
我认为你在这里将它()
与 C 等编程语言中函数后添加的注释联系起来。宏不是函数,即使它们经常以类似的方式使用。如果你的宏\somecommand
不接受参数,它将{}
不受参数影响,并且它后面的源代码换行符将变成通常不需要的空格。通常,孤立的换行符{}
不会造成伤害,但在某些地方,例如在可扩展上下文中,它们可能会造成麻烦。你绝对不应该裹所有宏都放在括号中,例如{\somecommand}
,因为这会使它们具有本地范围。
因此你应该像这样编写宏:
\newcommand\examplemacro{%
\somecommand
\commandwitharg{somearg}%
}
这里需要两个空格%
来删除行尾空格,但该\somecommand
行不需要空格,因为控制字后的所有空格都被删除了。这样做是因为您可能需要在它后面添加至少一个空格来将其与后面的文本分开,而多个空格总是会减少为一个。
需要注意的是,这些 (La)TeX 规则可以动态更改,例如,可以通过更改必需的\endlinechar
和 catcode 来忽略所有行尾甚至所有空格。这是针对 LaTeX3 语法进行的,从而避免了对此类注释的需求。
答案2
正如 Martin 已经评论过的,%
在行尾添加字符可以防止 TeX 将行尾字符转换为空格。每行末尾都需要这样做除了TeX 已经跳过空格的情况,例如在没有参数的宏名之后:
\newcommand{\examplemacro}{%
\somecommand{}%
\othercommand
}
这里,带有 的行\othercommand
不需要,%
因为 TeX 无论如何都会跳过这里的空格。
\newcommand
由于 TeX 抓取参数的方式,第一个参数的括号使用是“可选的”。我们在 LaTeX 中使用括号组来表示单个参数,但 TeX 会抓取任何一个括号组或单个令牌作为无界参数。在示例中,\examplemacro
是一个标记(控制序列),因此 TeX 会一次性抓取它。
有些地方需要使用括号。例如
\newcommand\test{a}
会起作用,但是
\newcommand{\test}b
不会,因为“替换文本”的论点\newcommand
有用括号括起来。
由于 LaTeX 是基于 TeX 构建的,因此一些 TeX 理念也泄露了出来。正式的 LaTeX 语法总是包含括号,但由于 TeX 并不总是需要括号,因此“知情人士”会采取捷径。
答案3
我不是 100% 确定,但在我的一个宏中,我可以抑制输出中不需要的空格。
关于问题 2 为什么缺少括号,我认为是因为它们是可选的。