# Kerning and ligatures in TeX without TeX

I am trying to get the same output as in this answer by topskip (an extended version with comments is presented in the TeX without TeX article). I am getting a paragraph consisting of 6 lines with hyphenation, but kerning and ligatures are lost (turned off?) as it can be seen around the character V in VLTAVA and in the letters ffi in office.

I use WinXP + TeX Live 2014 and Lubuntu 13.10 + TeX Live 2013. I've got the same output, the font is LinLibertine_R.otf.

First tip by topskip is to skip loading of the fontspec package which could handle things differently than the luaotfload package. Therefore, instead of libertine and luatextra (they both load the fontspec package), I tried to load luacode and luaotfload packages directly, no success, no errors and no warnings. Where the problem might be?

We run lualatex testfonts.tex.

% lualatex testfonts.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
%\usepackage{luatextra}
%\usepackage{libertine}
\usepackage{luacode}

\begin{document}
\font\main={file:LinLibertine_R.otf}
\main

\begin{luacode*}
local linecount = 0
if head.id == 0 then linecount = linecount + 1 end
end
return linecount
end

function mknodes( text )
local current_font = font.current()
local font_parameters = font.getfont(current_font).parameters
-- we should insert the paragraph indentation at the beginning

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
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 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))
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}


For opentype fonts, luaotfload provide function nodes.simple_font_handler which will take care of all font manipulations like ligaturing and kerning and all other features supported by luaotfload. This function isn't advertised in the manual, I've found it in luaotfload source code. It is called as node callback on normal text, but as you create nodes directly from Lua, it doesn't take effect on your text and you have to call it explicitly:

local head = mknodes(txt)

you don't have to call node.ligaturing and node.kerning any more, they were called from simple_font_handler already
• A small question from a person with no experience in the lua part of luaTeX. Isn't better to call first simple_font_handler and latter hyphenate? I wil guess that kerning and ligature adjustment will change the width of words; and, therefore, potentially the best hyphenation. – TeXtnik Mar 25 '15 at 14:41
• @zunbeltz hyphenate just insert marks on potential hyphenation points, actual breaking into lines happens later, after all node manipulations – michal.h21 Mar 25 '15 at 17:47
• Thanks for the correction. Does the insertion of a potential hyphenation point prevent ligatures? For example the insertion of hyphenations points dif•fi•cult does not block the use of ff ligature if the word is not hyphenated, does it? – TeXtnik Mar 26 '15 at 8:41