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


function count_lines (head)
  local linecount = 0
  while head do
    if head.id == 0 then linecount = linecount + 1 end
    head = head.next
  return linecount

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

    last.next = n
    last = n

  -- 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
  return head

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


VLTAVA office

a preview of the result

1 Answer 1


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)
head = nodes.simple_font_handler(head)

you don't have to call node.ligaturing and node.kerning any more, they were called from simple_font_handler already

enter image description here

  • 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, 2015 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, 2015 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, 2015 at 8:41
  • @zunbeltz no, it doesn't prevent ligatures :)
    – michal.h21
    Mar 26, 2015 at 9:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .