# Properly breaking up ligatures using selnolig / LuaLaTeX

Currently I use the selnolig package together with LuaLaTeX to automatically break up ligatures. This works quite well regarding the fact that ligatures get broken up at the right places. Note however, that apparently -- at least according to German typography rules -- two letters which don't form a ligature must not have any contact.1

Sadly the package selnolig only breaks the ligatures up without inserting additional kerning and it doesn't provide any interface where one could specify additional kerning for deactivated ligatures.

Did someone try to adapt the selnolig package in order to account for correct kerning? (I don't know any Lua, and when I skimmed the source I did not spot the place where the ligature gets broken up...)

UPDATE: I tried to adapt the kerning between the f and l glyphs by the means of Feature Files, but this doesn't seem to have any effect (the support for Feature Files has been dropped in luaotfload >= 2.7 -- I am aware of this and use an older version.)

For an illustration see the following MWE:

\documentclass[ngerman,parskip=full]{scrartcl}
\usepackage{fontspec}
\usepackage[ngerman]{babel}
\usepackage{filecontents}
\begin{filecontents*}{mykern.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
feature kern {
pos \f \l +300;
} kern;
\end{filecontents*}
\setmainfont[FeatureFile=mykern.fea,Ligatures=TeX]{Linux Libertine O}
\usepackage{selnolig}
\begin{document}

\selnoligoff
Auflage (incorrect; fl ligature is used)

\selnoligon
% manual kerning in feature file does not have any effect
Auflage (good; automatic suppression of ligature, but bad kerning)

Auf\kern+0.8pt lage (perfect)

\end{document}


UPDATE 2: What follows is another version of the MWE where I try to adapt the kerning between the f and l glyphs -- this "should work" with luaotfload >= 2.7, e.g. TeXLive 2016. It doesn't have any effect either, the result is the same as above.

\documentclass[ngerman,parskip=full]{article}
\usepackage{fontspec}
\usepackage[ngerman]{babel}
\usepackage{filecontents}
\directlua{
name = "ktest",
{
type = "kern",
data = {
["f"] = { ["l"] =  200 },
}
},
"extra kerns"
}
}
\setmainfont[RawFeature=+ktest,Ligatures=TeX]{Linux Libertine O}
\usepackage{selnolig}
\begin{document}

\selnoligoff

Auflage (incorrect; fl ligature is used)

\selnoligon
% manual kerning in lua code does not have any effect
Auflage (good; automatic suppression of ligature, but bad kerning)

Auf\kern+0.8pt lage (perfect)

\end{document}


1 Fossman and de Jong (2008). Detailtypografie. 4th ed. Mainz: Hermann Schmidt, pp. 98, 194.

• Interesting question. I think I discussed this issue at some point with Mico, who wrote selnolig, and it turned out that it’s at least not trivial to not only break up the ligature, but instead insert something or change something about the kerning. Also, I disagree about the third example looking perfect: The bigger space/kerning looks weird – what would be closer to perfect imho would be to use a variant of f with a shorter tail at the top. There is some font that has it, perhaps Junicode or Libertine. – doncherry Jun 17 '16 at 9:27
• @FredFisch - In my view, the optimal amount of kerning to be inserted depends critically on both the character pair whose ligature is being suppressed ("f|f" generally requires no extra kerning at all for most fonts, whereas "f|l" may indeed look better with some extra kerning) and the font being used. Most Garamond look-alikes and Linux Libertine have an "f" with a fairly long "arm", whereas the "f" of Palatino and Times Roman features a fairly short arm; for the latter two fonts, then, no extra kerning is usually needed for "f|l" and "f|i" combinations. (Continued below) – Mico Jun 17 '16 at 11:05
• (cont'd from above) Worse still, the length of the arms of the f and ff glyphs can vary substantially between the upright, bold, italic, and bold-italic members of one and the same font family. Hence, what may be an optimal amount of kerning for the basic upright font may be rather suboptimal for the bold and italic members of the family. Note that the babel approach (0.06em of kern) -- is a one-size-fits-all method that happens to be acceptable for some fonts and glyph combinations (e.g., Computer Modern upright and the "f|l" pair) but fails to do a good job elsewhere. – Mico Jun 17 '16 at 11:17
• (cont'd) For the reasons explained above, and as @doncherry has noted in a comment, I believe that the real solution to the vexing issue of the unligated "f" and "l" glyphs being too close is not is to insert a kern. Instead, I believe, the best solution is to use "short-armed" "f" and "ff" glyphs whenever available. Encouragingly, EB Garamond has excellently-shaped short-armed variants of the "f" and "ff" glyphs. Unfortunately, whereas Linux Libertine also provides short-armed variants of the "f" and "ff" glyphs, their arms are actually not that much shorter than the "regular" variants. – Mico Jun 17 '16 at 11:19
• Unfortunately, LuaTeX 0.95 -- which is disributed with TeXLive2016 -- no longer provides easy support for the Adobe feature file approach. (The issue is with LuaTeX, by the way, not fontspec or luaotfload.) I'm back to square one, so to say, with my efforts to program the use of short-armed f and ff glyph variants if they are followed by i or l. :-( My recommendation to you, for now, is to use a font, such as Palatino and Dante, whosef and ff glyphs feature short "arms" by default. – Mico Jun 17 '16 at 11:25

As I have recently explained in a different answer the usage of selnolig interferes with the manual kerning in LuaTeX. That is because selnolig's approach to breaking ligatures is by inserting a user-defined whatsit in the node list. The ligaturing routine of TeX does not look ahead over whatsits when building ligatures (actually you could also break ligatures by using an empty \special instead of an explicit \kern).

Unfortunately this means that you cannot use selnolig to remove the ligature if you want to adjust the kerning. You would have to remove the ligature from the font instead which is luckily possible with LuaTeX.

You might think that now you could use selnolig again but the problem is that selnolig intercepts ligatures in the ligaturing callback whereas the user-defined font features are only applied later (I think before pre_linebreak_filter). That means no selnolig :(

\documentclass[ngerman,parskip=full]{article}
\usepackage{fontspec}
\usepackage[ngerman]{babel}
\directlua{

fonts.handlers.otf.addfeature({
name = "removefl",
type = "multiple",
data = {
["f_l"] = { "f", "l" },
}
})
%
name = "kernfl",
type = "kern",
data = {
["f"] = { ["l"] =  80 },
}
})

}
\setmainfont[RawFeature=+removefl;+kernfl,Ligatures=TeX]{Linux Libertine O}
\begin{document}

Auflage

Auf\kern.8pt lage

\end{document}