我发现许多软件包和示例中的代码%
在(许多)行末尾都包含百分号。它们是用来做什么的?它们会影响这些行的解析吗?
答案1
简短的回答就像其他人所说的那样,%
开始注释,直到行尾。正常效果是它不会\par
从换行符插入空格(或)。
更长的答案是当 TeX 解析其输入时,它会逐行读取输入文件。它会删除尾部空格(包括任何回车符和换行符),然后附加一个与寄存器中的数字相对应的字符\endlinechar
(前提是它不是 -1 或大于 255)。默认情况下,该值为 13,对应于 ASCII 回车符。(TeX 用 . 表示^^M
)。您可以将此寄存器更改为任何值。
除非类别代码已更改(例如,通过宏\obeylines
),^^M
否则类别代码为 5 或行尾。当 TeX 到达行尾字符时,它会丢弃该行的其余部分并执行以下三项操作之一:不执行任何操作、插入空格标记或插入标记\par
,具体取决于 TeX 所处的状态(分别为 S、M 或 N)。
那么这与 有什么关系呢%
?因为注释字符会导致 TeX 忽略输入行的其余部分,所以附加的行尾字符也会被忽略。
当使用类别代码^^M
(再次使用\obeylines
或类似)时,这通常很重要。
详细答案载于第 8 章TeXbook。
最后一种没有人提到的用法是,有时需要以空格字符而不是行尾字符结尾。一个例子是反斜杠后跟空格与反斜杠后跟换行符不同:
\show\
\show\ %
在第一行中, 后面有一个空格\
,但是它会按照描述被剥离,所以正如\^^M
您在 TeX 打印出的内容中看到的那样,您会得到什么。
> \^^M=macro:
->\ .
也就是说,\^^M
是一个扩展到控制空间的宏:\
。在第二种情况下,注释可防止删除空格,并且行尾字符将被忽略。TeX 打印出以下内容。
> \ =\ .
也就是说,\
是 TeX 基元(参见控制空间TeXbook或者TeX 按主题分类)。
通常的原因是%
抑制宏定义中的空格。考虑\nopercents
下面的宏\percents
。
\documentclass{minimal}
\newcommand*\bracket[1]{[#1]}%
\newcommand*\nopercents[1]{
\bracket{#1}
}
\newcommand*\percents[1]{%
\bracket{#1}%
}
\begin{document}
X\nopercents{blah}X
X\percents{blah}X
\end{document}
从表面上看,它们似乎在做同样的事情:将输入传递给\bracket
。 不同之处在于,换行符在 中变为空格标记,\nopercents
但在 中被忽略,\percents
因为%
。 因此X\nopercents{blah}X
扩展为X [blah] X
而X\percents{blah}X
扩展为X[blah]X
。
关于行首空格的附录。
A%
只吞掉一行中跟在它后面的内容。它不是对下一行开头的空格没有任何影响。在大多数情况下,TeX 本身会忽略行首的空格。但有几个例外:
当该行完全是空白时,它将被解释为段落分隔符。
当
\obeyspaces
生效时,每个空格都会被带入输出;这在verbatim
模式下是正确的,也可以明确请求。
如果\obeyspaces
在定义命令或环境时 有效,并且定义占用多行,则定义中将保留续行开头的任何空格。缩进通常用于定义命令或环境,以使代码更易于理解(通常是一件好事),但当 有效时\obeyspaces
,这会产生不受欢迎的结果,应避免使用。 通常应仅在分隔范围(或)\obeyspaces
内使用,以避免不必要的结果。{ }
\begingroup ... \endgroup
答案2
你已经有很多答案了。你也可以自己尝试一下:
\documentclass{article}
\begin{document}
Hello%
world!
\end{document}
尝试使用和不使用 来编译它%
。然后你会发现 使%
换行符产生的空格消失了。(请注意,如果你Hello %
在 之前写了一个空格,你仍然会得到空格%
——试试看!)所有细节都在 TH 的精彩回答中给出。
答案3
百分号 %,允许结束一行而不生成空格字符——在编写宏时非常有用。
答案4
%
什么时候不是答案
处于控制序列的中间。
\ta%
你
不会重新组合成\tau
。控制序列必须作为不间断的单元输入。
- 在赋值中使用的数字或 <dimen> 之后。TeX 将继续读取,直到下一个标记绝对不是数字,或者在 <dimen> 不是
plus
或 的情况下minus
。改用\relax
。
这些例外情况已被涵盖,但被“埋没”,因此有必要进行更突出的提醒。
另一种可能性不太容易识别,并且通常不会在用户文档中提及,即通过包插入“填充”,如本例所示。
\documentclass{article}
\usepackage{tcolorbox}
\newcommand{\pink}[1]{\colorbox{red!20}{#1}}
\newcommand{\Pink}[1]{{\fboxsep=0pt\colorbox{red!20}{#1}}}
\begin{document}
compress \par
com\pink{p}ress \par
com\Pink{p}ress
\end{document}
这并不常见,但是当更可能的方法无法解决问题时,应该考虑采取一揽子行动。