我试图获得与这个答案由 topskip 撰写(带有注释的扩展版本在TeX 没有 TeX 的文章)。我得到了一个包含 6 行带连字符的段落,但字距调整和连字符丢失了(关闭了?),因为它可以在字符周围看到五在伏尔塔瓦河和信件中菲在办公室。
我使用 WinXP + TeX Live 2014 和 Lubuntu 13.10 + TeX Live 2013。我得到了相同的输出,字体是LinLibertine_R.otf
。
topskip 给出的第一个建议是跳过fontspec
包的加载,因为包的处理方式可能与包不同。因此,我尝试直接加载和包,luaotfload
而不是libertine
和luatextra
(它们都加载包) ,但没有成功,没有错误,也没有警告。问题可能出在哪里?fontspec
luacode
luaotfload
我们跑lualatex testfonts.tex
。
% lualatex testfonts.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
%\usepackage{luatextra}
%\usepackage{libertine}
\usepackage{luaotfload}
\usepackage{luacode}
\begin{document}
\font\main={file:LinLibertine_R.otf}
\main
\begin{luacode*}
function count_lines (head)
local linecount = 0
while head do
if head.id == 0 then linecount = linecount + 1 end
head = head.next
end
return linecount
end
function mknodes( text )
local current_font = font.current()
local font_parameters = font.getfont(current_font).parameters
local n, head, last
-- we should insert the paragraph indentation at the beginning
head = node.new("glue")
head.spec = node.new("glue_spec")
head.spec.width = 20 * 2^16
last = head
for s in string.utfvalues( text ) do
local char = unicode.utf8.char(s)
if unicode.utf8.match(char,"%s") then
-- its a space
n = node.new("glue")
n.spec = node.new("glue_spec")
n.spec.width = font_parameters.space
n.spec.shrink = font_parameters.space_shrink
n.spec.stretch = font_parameters.space_stretch
else -- a glyph
n = node.new("glyph")
n.font = current_font
n.subtype = 1
n.char = s
n.lang = tex.language
n.uchyph = 1
n.left = tex.lefthyphenmin
n.right = tex.righthyphenmin
end
last.next = n
last = n
end
-- now add the final parts: a penalty and the parfillskip glue
local penalty = node.new("penalty")
penalty.penalty = 10000
local parfillskip = node.new("glue")
parfillskip.spec = node.new("glue_spec")
parfillskip.spec.stretch = 2^16
parfillskip.spec.stretch_order = 2
last.next = penalty
penalty.next = parfillskip
-- just to create the prev pointers for tex.linebreak
node.slide(head)
return head
end
local txt = "VLTAVA office A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart. I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine."
tex.baselineskip = node.new("glue_spec")
tex.baselineskip.width = 14 * 2^16
local head = mknodes(txt)
lang.hyphenate(head)
head = node.kerning(head)
head = node.ligaturing(head)
local vbox
local size = 90
lines = 0
lines_goal = 6
while lines < lines_goal do
texio.write_nl(string.format("Formatting text to %d mm",size))
local copy_of_head = node.copy_list(head)
vbox = tex.linebreak(copy_of_head,{ hsize = tex.sp(string.format("%dmm",size))})
size = size - 10
lines = count_lines(vbox)
texio.write_nl(string.format("lines=%d",lines))
end
node.write(vbox)
\end{luacode*}
VLTAVA office
\end{document}
答案1
对于 opentype 字体,luaotfload
提供nodes.simple_font_handler
处理所有字体操作(如连字和字距调整)以及 支持的所有其他功能的函数luaotfload
。手册中没有宣传此功能,我在luaotfload
源代码中找到了它。它在普通文本上被称为节点回调,但由于您直接从 Lua 创建节点,因此它不会对您的文本生效,您必须明确调用它:
local head = mknodes(txt)
lang.hyphenate(head)
head = nodes.simple_font_handler(head)
你不必再打电话node.ligaturing
了,他们已经node.kerning
打过电话了simple_font_handler