# How to make contextual substitutions work with luatex 1.0x?

Recently I started some experiments with German fraktur fonts, which contain several contextual substitutions to control the correct setting of longs and ligatures. Normally, there is one general rule for the setting of the longs or the ligature and the exceptions are defined as a list of back-substitutions.

In the following an example for the substitution of s by longs (calt1) and back for 2 special phrases (calt2) is given (for lualatex). Additionally, the back-substitution of the t_z ligature for 3 cases is implemented (calt 3) (I used the font Linux Biolinum for demonstration, but any other font containing longs and t_z ligature would work in the same manner). The features are added as lua code, but the direct implementation into the font with fontforge leads to the same or a similar result.

\documentclass[12pt]{article}
%\usepackage[english]{babel}
\usepackage{polyglossia}
\setdefaultlanguage{german}
\usepackage{fontspec}
\directlua
{
name    = "calt1",
type    = "chainsubstitution",
lookups = {{
type = "single",
data = { ["s"] = { "longs" } }}},
data = { rules = {
{
after = {{"o"}},
current = {{"s"}},
lookups = { 1 },
},
{
after = {{"p"}},
current = {{"s"}},
lookups = { 1 },
},
{
after = {{"s"}},
current = {{"s"}},
lookups = { 1 },
},
{
after = {{"t"}},
current = {{"s"}},
lookups = { 1 },
}}}}
name    = "calt2",
type    = "chainsubstitution",
lookups = {{
type = "single",
data = { ["longs"] = { "s" } }}},
data = { rules = {
{
before = {{"h"}, {"o"}},
after = {{"p"}, {"h"}},
current = {{"longs"}},
lookups = { 1 },
},
{
before = {{"B"}, {"u"}, {"n"}, {"d"}, {"e"}},
current = {{"longs"}},
lookups = { 1 },
}}}}
name    = "calt3",
type    = "chainsubstitution",
lookups = {{
type = "multiple",
data = { ["t_z"] = { "t" , "z" } }}},
data = { rules = {
{
before = {{"Z"}, {"e"}, {"i"}},
current = {{"t_z"}},
lookups = { 1 },
},
{
after = {{"u"}, {"longs"}, {"t"}, {"a"}, {"n"}, {"d"}},
current = {{"t_z"}},
lookups = { 1 },
},
{
after = {{"u"}, {"s"}, {"t"}, {"a"}, {"n"}, {"d"}},
current = {{"t_z"}},
lookups = { 1 },
}}}}
}
\setmainfont[RawFeature={+dlig,+calt1,+calt2,+calt3}]{Linux Biolinum}

\begin{document}
\noindent
calt1: (substitution of s by longs if it is before the letters o, p, s or t)\\
calt2: (back-substitution of longs by s in the phrases 'ho\/sph' and 'Bunde\/ſ')\\
Phosphor, Phosphfi, Phosph, Phosphor \\
Phosphor Phosphor Phosphat Phosphz, Phosph, Phosphfi\\
Bundes Bundestag Bundesstaat Bundesorden Bundespolizei Bundes\\
\\
calt3: (back-substitution of the ligatur tz which was activated by +dlig to t and z in the the phrases 'Zei\/tz' and 'tz\/ustand')\\
Erhitzen, sitzen, Latzhose\\
Aggregatzustand, tzustand, Istzustand\\
Zeitzone Zeitz Zeitzone Zeitzustand\\
Zeitzung Zeitz; Zeitzung Zeitzan Zeitzling\\
\end{document}


Everything works fine with luatex 0.95 but using luatex 1.04, 1.06.2 or 1.07 (all tested within the current TeXLive 2017 environment) there are cases, were the back-substitution doesn’t work as desired. For some words the back substitution simply does not occur. Depending on the language setting (babel/ polyglossia for lualatex or \mainlanguage for context) different words are affected. The correct output should look like this:

In case of a current standalone Context distribution, I was only able to test the calt3 feature, which shows the same problems as already described (luatex 1.0x in the TeXLive environment). The compilation of the document fails, if the features calt1 and calt2 are switched on.

Anybody who has ideas how to make contextual substitutions work also with a current luatex version?

• It would be easier to test, if it were clearer how the correct output should look like. Regarding the failure in context: It will probably work if you use multiple instead of single also for calt1 and calt2, at least then it compiles for me with a newer fontloader. And calt3 seems to depend the place of the word on the line, if it is at the start it works. – Ulrike Fischer Feb 2 '18 at 14:23
• Thank you for your helpful comment, Ulrike. With the "multiple" setting for the lookups the compilation works now in context. The result is, that the s/ longs substitutions (calt1 and calt2) seem to work as desired. Only calt3 substitutions are not correct. I also observed, that the position of a word in a line plays a role (at the beginning or not), but afaics only in lualatex, not in context. – orchidee2 Feb 5 '18 at 9:16