标点在左右边界处的伸出

LiYanrui posted @ Jun 30, 2009 04:56:35 PM in Dream of TeX with tags luatex tex , 3991 阅读

先把要解决的问题交代一下。所谓“标点在左右边界处的伸出 (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)的伸出处理。

\pdfprotrudechars=2

\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 () 函数改写如下:

    function initializers.common.microtype(tfmdata)
        for i in pairs(left_protlist) do
            tfmdata.characters[i].left_protruding  = left_protlist[i] / 1000
        end
        tfmdata.auto_expand   = true
    end

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter