标点在左右边界处的伸出
先把要解决的问题交代一下。所谓“标点在左右边界处的伸出 (protruding)”,可以通过下面的示例来理解。
第一个示例是标点在版面左侧文本边界处未有伸出的示例。
第二个示例是标点在版面的左侧文本边界处伸出的示例,伸出的目的是让文字在左边界处垂向对齐,让版面更齐整。
同理,为了排版的美观,对于标点出现在文本右侧边界处也需要伸出处理。本文要讲述的是怎样控制 LuaTeX 来处理这类问题。
比较正路的应该是利用 LuaTeX 提供的 \lpcode 与 \rpcode 功能(是从 pdfTeX 那里来的)。LuaTeX 的 font.characters 表里提供了 left_protruding 和 right_protruding 元素,详见 LuaTeX Reference 第 7 章。只需要对标点字符表中的这两个元素设置合适的值,那么当 LuaTeX 在断行时遇到行首或行尾出现该标点时,就会按照 left_protruding 或者 right_protruding 的值控制标点符号的向外伸出的长度。
孙文昌老师在 CTeX 论坛上给出的一个简单示例,其中包含了设置标点字符伸出长度的代码,但是这个示例中有关标点伸出的代码不工作。后来在 Wang Yue 介绍的韩国 luatexko 项目中找到了可以工作的例子,下面给出这个例子的超级简化版本,因为它只演示了对出现在左侧边界的左引号(0x201C)的伸出处理。
\directlua{
local initializers = fonts.initializers
local left_protlist = {
[0x201C] = 300,
}
function initializers.common.microtype(tfmdata)
for i,v in pairs(tfmdata.characters) do
if left_protlist[i] then
v.left_protruding = left_protlist[i] / 1000
end
end
tfmdata.auto_expand = true
end
table.insert(fonts.manipulators,"microtype")
initializers.base.otf.microtype = initializers.common.microtype
}
\parindent 0pt
\def\defaultfeature{+microtype}
\font\myfont={file:simsun:\defaultfeature} at 14pt
\myfont
“测试”测试测试测试测试测试
测试测试测试测试测试测试
\bye
上述代码中的做法并不难理解,就是在定义字体时,只要设定了 microtype 字体特征,它会触发 initializers.base.otf.microtype () 函数,而这个函数真正的实体是 initializers.common.microtype () 函数,并且在这一函数中,根据标点符号表中定义的 protruding 参数来计算标点符号字符的伸出比例。
不过,上面的做法有问题,不应当对 tfmdata.characters 表进行遍历并且从中选择落入标点符号表的字符结点,这样相当于每加载一个字体,都要运行一个成千上万次的循环代码块。正确的做法应当将 initializers.common.microtype () 函数改写如下:
for i in pairs(left_protlist) do
tfmdata.characters[i].left_protruding = left_protlist[i] / 1000
end
tfmdata.auto_expand = true
end