我们有\hskip
、\vskip
和\mskip
,但只有\kern
和\mkern
。为什么 TeX 不像跳过那样区分水平和垂直字距?
答案1
errorlog.tex
关于的介绍没有注释\kern
,但1978-03-27的注释说
S227. Represent italic corrections as boxes, not glue, so that they won't be broken.
[The |\kern| command doesn't exist yet.] @1113
所以这可能是这个想法\kern
开始出现的地方,它也可以解释为什么垂直和水平字距没有区别:它们具有相同的框属性(因此它们在水平和垂直模式下的行为不同)加上在行/页中断处消失的能力。
虽然用户想要知道或指定将哪种粘连(跳过)附加到哪个列表,但程序员应该知道他们为什么要添加字距,而且\vkern
在某些时候说垂直字距是作为最后的润色添加的东西是没有意义的。另一方面,说\vskip 1pc
(或无论如何)意味着“留下一个垂直空间”并且必须结束一个段落。
还要注意,两个原语而不是一个原语会增加程序的大小,并且至少还有另一个具有双重功能的原语的示例,即\span
。
就实现而言,\kern
将一个 kern 项附加到当前列表中,因此了解这一点并不重要什么正在构建的列表类型。
答案2
\kern
在任何模式下插入字距:在垂直模式下,它是垂直字距;在水平或数学模式下,它是水平字距。这是最简单的实现。
另一方面,\vskip
仅在垂直模式下插入其胶水。如果它在水平模式下使用,则将令牌\vskip
发送\par
到输入队列并等待由此 给出的处理\par
。这是 TeX 在大多数其他情况下使用的“再次读取”原则。我们可以除外:在\par
处理之后,TeX 进入垂直模式,因此\vskip
现在插入胶水。
您可以看到,这比的实现稍微复杂一些\kern
。
\hskip
工作原理类似:如果处于水平或数学模式,它会插入粘连,如果处于垂直模式,它会开始段落。
您可以通过以下方式\hkern
实现\vkern
:
\def\hkern{\leavevmode\kern}
\def\vkern{\par\kern}
更有趣的问题是:为什么没有通用的\insertskip
根据 TeX 模式插入垂直或水平跳过的方法(如\kern
)。但这个问题只针对 TeX 的作者。当然,您可以定义:
\def\insertskip{\relax\ifvmode\vskip\else\hskip\fi}