Basic Problem Statement
I would like to enable some (but not all) stylistic alternate ".end" characters from an OpenType font, on condition that they replace terminal characters in a word.
Unfortunately, using the +salt feature enables them globally throughout text, which I do not want.
So far, I have tried using \directlua to build a chainsubstitution, then add it via RawFeature, but this is producing very odd results.
I expect this is likely an error in usage of \directlua on my part---one for which I would greatly appreciate correction.
Indeed, to me, my approach seems a bit of a hack, particularly when it comes to listing all the conditions to trigger substitution. If there is an altogether different method for making this substitution smartly, I am happy to hear about it.
MWE
This is a simple example of the problem. I am using Adobe Garamond Premier Pro. Regrettably, I am unaware of a free choice at hand which features the same ".end" characters for this situation.
For ease, (I think) I am setting "a.end" to replace "a" whenever "a" occurs just before a period.
With this snippet, the output is as expected only with the normal Roman and boldface fonts. All italic shapes somehow produce the "d.end" character instead.
\documentclass{minimal}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature{
name = "asub",
type = "chainsubstitution",
lookups = {
{
type = "substitution",
data = {
["a"] = "a.end",
},
},
},
data = {
rules = {
{
after = { { "." } },
current = { { "a" } },
lookups = { 1 },
},
},
},
}
}
\setmainfont[{RawFeature=+asub}]{Garamond Premier Pro}
\begin{document}
a.
{\itshape a. }
{\bfseries a. }
{\bfseries\itshape a. }
\end{document}
MWE Output
Notes
- Using
+saltdoes produce the correct "a.end" glyph, no matter what choice of bold and/or italic. On checking the different OTF files with FontForge, I see the "a.end" glyph is not in the same slot for each font, but the name is always the same. - This is just one example of such a broken substitution. The "h.end" character behaves similarly.

Contxtuals=Final? – Davislor Nov 03 '21 at 04:05otfinfofor each of the fonts, andfinais unlisted, confirmed byfontspecwarning in console output on trying to add the feature. But that is a good point; it would surely make this a simpler matter were it available. – jasonhathcock Nov 03 '21 at 04:23article, say) for an MWE;minimalclass is "regrettably" named and was intended to test for package-loading dependencies - it defines normalsize font and that's about it: https://tex.stackexchange.com/questions/42114/why-should-the-minimal-class-be-avoided/42115 – Cicada Nov 03 '21 at 07:14a.endandd.endin both roman and italic, I get the expected results in the regular and bold roman, but the final form ofàin the regular and bold italic. But with Le Monde Livre Classic, the output of the MWE is perfect. – Thérèse Nov 03 '21 at 15:51a.endcorresponds to 983046 andd.endto 983047, whereas in the italica.endis 983045 andd.endis 983046. So the problem becomes making different features for the upright and the italic, referencing these numbers. Not sure I can do it — certainly not before this busy semester is done, but maybe someone else with the fonts can pursue this sooner. – Thérèse Nov 03 '21 at 16:51+saltfeature gets it correct every time. – jasonhathcock Nov 03 '21 at 17:34tex\latex-dev. You can then test it by compiling withlualatex-dev– Ulrike Fischer Nov 05 '21 at 08:17minimaltoarticlefor safety) is the same. – Thérèse Nov 05 '21 at 11:31luaotfload 2021-05-21 3.19-dev. I can't test it, but you could open an issue at the luaotfload tracker. – Ulrike Fischer Nov 05 '21 at 11:54git clone https://github.com/latex3/luaotfload.git, changed to the directory created, typedl3build install, and thenlualatex-dev example.tex. Any missing steps? – Thérèse Nov 05 '21 at 12:23l3build install, rungit checkout devto switch to the development branch. Otherwise you just reinstall the last released version. – Marcel Krüger Nov 05 '21 at 12:25luaotfloadwith variable fonts. With the last released version, some variable fonts look as if their outlines have been chewed by rats, but with the dev version, almost all of those defects are gone. Excellent work! – Thérèse Nov 11 '21 at 03:12harfmode, but that requires engine changes and therefore has to wait till TeX Live 2022.) – Marcel Krüger Nov 11 '21 at 08:06