![LaTeX 命令后的空格](https://linux22.com/image/258394/LaTeX%20%E5%91%BD%E4%BB%A4%E5%90%8E%E7%9A%84%E7%A9%BA%E6%A0%BC.png)
我有一个定义:
\newcommand{\arnold}{Arnold Schwarzenegger}
当我这样引用它时:
\arnold is a
它被渲染为:
Arnold Schwarzeneggeris a
为了在“is”前面留一个空格,我需要写
\arnold\ is a
还有其他更短的方法吗?
答案1
如果创建没有参数的宏,则应始终在它后面加上一个空语句来调用它:
\arnold{}
其背后的原因是 LaTeX 会忽略宏后面的空格(它们只是停止扫描宏的名称)。您需要使用受保护的空格(如您已经写过的)或空语句来打破这种局面{}
。我建议使用空语句,因为使用受保护的空格可能会产生令人讨厌的效果 — 例如,如果受保护的空格后面直接跟着换行符。在这种情况下,LaTeX 可能会打印两个空格,这看起来很丑陋,也是不想要的。使用空语句可以避免这种情况。
如何直接在宏中添加空格已经得到解答,但你真的想要这样吗?只要宏后面跟着标点符号(或者宏后面跟着\footnote
,等等),你就会遇到麻烦:
\arnold,
Arnold Schwarzenegger ,
我建议选择空语句选项——人们很快就会习惯它。
答案2
是的,看看xspace
包装。
\usepackage{xspace}
后来……
\newcommand{\arnold}{Arnold Schwarzenegger\xspace}
答案3
*这是一个总结性的答案,重点介绍了用于保留控制字后空格的不同技术的优点和缺点。从概念上讲,这适用于 LaTeX 实现,其中控制字不接受参数,扩展为简单、可能格式化的文本,并且主要用于散文。
背景:
TeX 输入处理器在构建由类别代码 = 11 的字符(控制字)组成的控制序列后,切换到状态 S,该状态会跳过类别代码 = 10 的字符(空格)。因此,为了保留控制字后面的空格,必须在控制字和后面的空格之间使用类别代码 < 10 或类别代码 > 11 的字符。这是下面前五个选项的本质。第六个选项在输入处理器之后起作用,并根据后面的标记添加空格。
评价标准:
问题定义了一个比较的基础:
- 尽量减少基线控制字之外的附加字符的数量(
\arnold
作为示例)。
简洁性不应是唯一考虑的因素。定性特征也很重要。例如,该方法是否:
- 允许错误地删除预期的尾随空格吗?换句话说,是否存在可以删除显式空格的控制字的有效变体?
- 是否有可能在控制字后添加意外的尾随空格?
- 如果控制字已经定义,是否会引发错误?
- 应用于现有的控制字(例如
\LaTeX
)? - 强制在文章中一致使用控制字?与 (2) 一样,控制字是否有有效的变体?对一致使用的渴望源于对控制字作为底层文本的直接替代的合理解释。
- 是否会与 LaTeX 的其他方面产生意想不到的后果/冲突?
由于上述各点的权重都是主观的,没有完美的解决方案,因此最好的方法在很大程度上取决于个人喜好。因素 (1) 列在选项标题中,其余因素则列在好处和缺点。下面的每个选项都有实现(那些“带检查的”)来满足(4),因此被省略。
选项1:\␣
如果需要空格,请在控制字后添加一个控制空格( =反斜杠 + 空格)。影响:0 或 1 个额外字符。
TEXbook 第 8 页给出了“明确”的解决方案。这将产生一个控制序列标记(不同于仅由空格生成的字符标记),因此将被保留。
定义: \newcommand{\arnold}{Arnold Schwarzenegger}
使用示例:
- 后面有空格:
He yelled ``Get to the choppa!'' in his best \arnold\ impression.
- 标点符号之后:
According to \arnold, it is pronounced Kal-e-four-knee-yah.
好处:
- (3)不会添加意外的尾随空格。
- (5)适用于预先存在的控制字。
缺点:
- (2)如果省略,尾随空格将被删除(即,
best \arnold impression
上面的结果为best Arnold Schwarzeneggerimpression
)。 - (6)使用情况不一致(即
\arnold\ ,
产量高于Arnold Schwarzenegger ,
)。
选项 2:{}
当需要空格或每次使用后,请在控制字后添加。
实施 A:影响:0 或 2 个额外字符。
正如建议的那样bluebrother 的回答,{
这种方法中控制字后面的字符会导致输入处理器切换到状态 M 并保留第一个后续空格。
定义: \newcommand{\arnold}{Arnold Schwarzenegger}
用途:
- 后面有空格:
He yelled ``Get to the choppa!'' in his best \arnold{} impression.
- 标点符号之后:
According to \arnold, it is pronounced Kal-e-four-knee-yah.
According to \arnold{}, it is pronounced Kal-e-four-knee-yah.
好处:
- (3)不会添加意外的尾随空格。
- (5)适用于预先存在的控制字。
缺点:
- (2)如果省略,尾随空格将被删除(即,
best \arnold impression
上面的结果为best Arnold Schwarzeneggerimpression
)。 - (6)使用不一致(
{}
只要后面有标点,加、省略都可以)。 (7)意想不到的后果/冲突:
- 如果用作单词/首字母缩略词的一部分,则防止与后续文本进行字距调整和连字(请参阅Ulrich Diez 的回答)。
实施 B:影响:增加 2 个角色。
{}
如果不遵循控制字,则可能会引发错误的替代方法,请参阅csname 方法的缺点是避免命令后出现空格。
定义:各不相同
用途:
- 后面有空格:
He yelled ``Get to the choppa!'' in his best \arnold{} impression.
- 标点符号之后:
According to \arnold{}, it is pronounced Kal-e-four-knee-yah.
好处:
- (2)防止删除预期的尾随空格(如果
{}
省略则会引发错误)。 - (3)不会添加意外的尾随空格。
- (6)使用大多一致(如果
{}
省略则会引发错误;但是{\relax}
可以编译)。
缺点:
- (5)不适用于现有的控制字。
(7)意想不到的后果/冲突:
- 一些如果用作单词/首字母缩略词的一部分,实现可能会阻止字距调整和与后续文本的连字(请参阅Ulrich Diez 的回答)。
选项 3:{
}
如果需要空格或每次使用时,请将控制字括起来。影响:0 或 2 个附加字符。
建议来自特里克斯在评论中bluebrother 的回答。
定义: \newcommand{\arnold}{Arnold Schwarzenegger}
用途:
- 后面有空格:
He yelled ``Get to the choppa!'' using his best {\arnold} impression.
- 标点符号之后:
According to \arnold, it is pronounced Kal-e-four-knee-yah.
According to {\arnold}, it is pronounced Kal-e-four-knee-yah.
好处:
- (3)不会添加意外的尾随空格。
- (5)适用于预先存在的控制字。
缺点:
- (2)如果省略,尾随空格将被删除(即,
best \arnold impression
上面的结果为best Arnold Schwarzeneggerimpression
)。 - (6)使用不一致(
{
}
只要后面有标点,加、省略都可以)。 (7)意想不到的后果/冲突:
- 将命令放入一个组中,从而将该命令的非全局效果限制在该范围内(如格诺特在下面的评论中)。
- 如果用作单词/首字母缩略词的一部分,则防止与后续文本进行字距调整和连字(请参阅Ulrich Diez 的回答)。
选项 4:在控制字的定义中以及每次使用后,在其末尾添加一个非字母字符。影响:1 个附加字符。
变体Przemysław Scherwentke 的回答(也可以看看lockstep 的回答和yo 的回答),这也许是“规范的”解决方案(The TEXbook 第 204 页):
你可以使用这个想法来定义旨在用于句子中的宏,这样用户就不必担心空格可能消失。
通过用 定义控制字,\def
并在参数文本的开头放置一个非字母字符,该字符将被必需的. 与上述一样,可以将定义包装起来\@ifdefinable
以执行相同的检查,\newcommand
如果控制字已经定义,则会引发错误。
定义:
不带支票:\def\arnold/{Arnold Schwarzenegger}
经过检查(请参阅本答案末尾的附录以了解替代实施方案):
\makeatletter
\@ifdefinable{\arnold}{\def\arnold/{Arnold Schwarzenegger}}
\makeatother
用途:
- 后面有空格:
He yelled ``Get to the choppa!'' using his best \arnold/ impression.
- 标点符号之后:
According to \arnold/, it is pronounced Kal-e-four-knee-yah.
好处:
- (2)防止删除预期的尾随空格(如果
/
省略则会引发错误)。 - (3)不会添加意外的尾随空格。
- (6)使用一致(若
/
省略则出错)。
缺点:
- (5)不适用于现有的控制字。添加:本答案末尾的附录提供了重新定义单个现有控制字以遵循此惯例的方法。
选项 5:#
在定义中的参数文本末尾添加要求{
紧跟控制字。影响:2 个或 ? 个附加字符。
通过定义控制字\def
并放置#
在参数文本的末尾,控制字后面必须跟一个左括号(The TEXbook 第 204 页)。右括号也应是必需的关闭群组(见格诺特(见下面的评论),但在撰写本文时,并非所有编辑器都能正确解析由于省略而导致的警告。定义可能会被包装起来\@ifdefinable
以执行与相同的检查,\newcommand
如果控制字已经定义,则会引发错误。
定义:
不带支票:\def\arnold#{Arnold Schwarzenegger}
经过检查(请参阅本答案末尾的附录以了解替代实施方案):
\makeatletter
\@ifdefinable{\arnold}{\def\arnold#{Arnold Schwarzenegger}}
\makeatother
用途:
后面有空格:
He yelled ``Get to the choppa!'' in his best \arnold{} impression.
He yelled ``Get to the choppa!'' in his best \arnold{ }impression.
标点符号之后:
According to \arnold{}, it is pronounced Kal-e-four-knee-yah.
好处:
- (2)防止删除预期的尾随空格(如果省略
{
,{}
则会引发错误/警告)。{<anything>}
- (3)不会添加意外的尾随空格。
缺点:
- (5)不适用于现有的控制字。添加:本答案末尾的附录提供了重新定义单个现有控制字以遵循此惯例的方法。
- (6)使用不一致。控制字后面可能跟有
{}
或{<anything>}
。
选项 6:使用包并在定义末尾xspace
添加。影响:0* 个附加字符\xspace
这是Uri 的回答该xspace
包作用于输入处理器之后,根据控制字后面的标记添加空格。
定义: \newcommand{\arnold}{Arnold Schwarzenegger\xspace}
用途:
- 后面有空格:
He yelled ``Get to the choppa!'' in his best \arnold impression.
He yelled ``Get to the choppa!'' in his best \arnold{} impression.
He yelled ``Get to the choppa!'' in his best \arnold\ impression.
- 标点符号之后:
According to \arnold, it is pronounced Kal-e-four-knee-yah.
According to \arnold{}, it is pronounced Kal-e-four-knee-yah.
好处:
- (2)防止删除预期的尾随空格。
缺点:
- (3)可能会添加意外的尾随空格。
- (6)使用可能不一致。
- (5)不适用于现有的控制字。
*理想情况下,这种方法在使用控制字时不需要任何附加字符。但是,在失败的情况下,a{}
是必需的。
附录
用于向仅生成文本的现有无参数宏添加所需分隔符的接口。
\documentclass{article}
\makeatletter
\newcommand\requiredelimiter[2][########]{%
\ifdefined#2%
\def\@temp{\def#2#1}%
\expandafter\@temp\expandafter{#2}%
\else
\@latex@error{\noexpand#2undefined}\@ehc
\fi
}
\@onlypreamble\requiredelimiter
\makeatother
\requiredelimiter{\LaTeX}
\newcommand\arnold{Arnold Schwarzenegger}
\requiredelimiter[/]{\arnold}
\requiredelimiter{\foo} % <---- ERROR
\begin{document}
\LaTeX{} is nice
\arnold/ is strong
\end{document}
如果没有可选参数,则(重新定义的)宏将需要在后面加上一对括号,如\LaTeX
示例中所示。如果有可选参数,则需要指定的标记,如\arnold
示例中所示。
答案4
除了使用空语句
\hello{} world
您还可以使用波浪号作为明确的空格:
\hello~world
确保不要在波浪号后添加另一个空格,因为这将导致出现两个空格。