# fontspec/luaotfload: defining custom features without OTF feature file support

Since 2016, fontspec no longer supports standard OTF feature files. These files made it possible to define sophisticated custom changes to the way an OpenType font is processed. That feature file format, developed by Adobe some 20 years ago, is well-established, well-documented, and independent of operating systems and typesetting applications.

The fontspec manual provides a very small example of the new procedure that's supposed to be used in place of the previous one -- and, in case of any further questions, refers us to the manual of luaotfload, which apparently is the cause of these changes.

However, that manual doesn't seem to address the question that's crucial here (leaving aside the question of what's so bad about Adobe's format that it had to be abandoned): How do we transform the things that we used to do, very easily, in that feature file format into the format that luaotfload now seems to require?

If we go back to the fontspec manual (which, in contrast to luaotfload's, at least give us one example), we see that the new syntax is a lot different from Adobe's one.

Whereas, previously, we would say, e.g., for a simple substitution:

substitute k by k.alt;


...we're now supposed to say

["k"] = "k.alt",


...as in this example, based on the one from the manual:

\documentclass{article}
\usepackage{fontspec}
\directlua{
name = "kalt",
type = "substitution",
data = {
["k"] = "k.alt",
}
}
}
\setmainfont{Minion Pro}[RawFeature=+kalt]
\begin{document}
okay
\end{document}


But that's about all we can gather from there. How do we do all the other things that we used to do? What, for example, would be the syntax expected by luaotfload for a contextual substitution that I used to use with Matthew Carter's ›Miller‹ typeface which offers two slightly diffent capital Rs:

substitute R' [a c d e g o q s u adieresis odieresis udieresis C G O Q S U Odieresis Udieresis] by R.salt;

• – Ulrike Fischer Mar 16 '18 at 13:58
• the change wasn't caused by fontspec or luaotfload, it was a change to the underlying luatex engine (dropping some libraries inherited from fontforge as I recall) – David Carlisle Mar 16 '18 at 14:09
• Thanks, Ulrike, that's the post I had hope would exist. Might solve my problem, let's see... – Nils L Mar 16 '18 at 14:48

Thanks to Ulrike's hint, my question is now answered. Here's an example of a simple context sub using the two Rs present in Miller Text.

\documentclass{article}
\usepackage{fontspec}
\directlua{
name = "ralt",
type = "chainsubstitution",
lookups = {
{
type = "substitution",
data = {
["R"] = "R.salt",
},
},
},
data = {
rules = {
{
after  = { { "a", "c", "e", "o", "u", "adieresis", "odieresis", "udieresis", "C", "G", "O", "Q", "S", "U", "Odieresis", "Udieresis" } },
current = { { "R" } },
lookups = { 1 },
},
},
},
}
name = "ralt-it",
type = "chainsubstitution",
lookups = {
{
type = "substitution",
data = {
["R"] = "R.salt",
},
},
},
data = {
rules = {
{
after  = { { "a", "c", "e", "i", "o", "u", "adieresis", "odieresis", "udieresis", "C", "G", "O", "Q", "S", "U", "Odieresis", "Udieresis" } },
current = { { "R" } },
lookups = { 1 },
},
},
},
}
}

\setmainfont[%
UprightFeatures={RawFeature=+ralt},
ItalicFeatures={RawFeature=+ralt-it}]{Miller Text}

\begin{document}
Roll Right \emph{Roll Right}
\end{document}