Skip to main content
11 of 16
added contextual alternates and made cosmetic fixes
Thérèse
  • 12.8k
  • 3
  • 37
  • 59

Crimson is useful for experimenting with the new approach, because it’s free and defines few of the features it could support. Here are the features defined in its latest version:

       | r | i | b | bi | sb si |
|------+---+---+---+----+-------|
| c2sc | ✓ | ✓ | ✓ |    |       |
| kern | ✓ | ✓ | ✓ | ✓  | ✓     |
| liga |   |   |   | ✓  |       |
| onum | ✓ | ✓ |   | ✓  |       |
| ordn | ✓ |   |   |    |       |
| pnum | ✓ | ✓ |   | ✓  | ✓     |
| smcp | ✓ | ✓ | ✓ |    |       |
| zero | ✓ |   |   |    |       |

Ligatures

It’s most surprising that liga is defined only in the bold italic face, so let’s fix that first.

Here’s Crimson before we add the feature:

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Crimson}
\begin{document}
The five baffled officials flew off.

\textit{The five baffled officials flew off.}
\end{document}

output of example

Now here’s the fix:

\documentclass{article}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature {
    name = "liga",
    {
        type = "ligature",
        data = {
            ['f_f'] = { "f", "f" },
            ['f_i'] = { "f", "i" },
            ['f_f_i'] = { "f", "f", "i" },
            ['f_l'] = { "f", "l" },
            ['f_f_l'] = { "f", "f", "l" },
            ['T_h'] = { "T", "h" },
        }
    },
    "some ligatures"
  }
}
\setmainfont{Crimson}
\begin{document}
The five baffled officials flew off.

\textit{The five baffled officials flew off.}
\end{document}

output of second example

In ['f_i'] = { "f", "i" }, ['f_i'] is the glyph name of the ligature, and { "f", "i" } are the letters to be ligatured. So if your font calls the ligature “fi” rather than “f_i”, you should write ['fi'] = { "f", "i" }. Also note that, in some fonts, ['f_f_b'] = { "f", "f", "b" } doesn’t work, but ['f_f_b'] = { "ff", "b" } does.

As Ulrike Fischer explains in tex.stackexchange.com/a/352864 and in her answer to this question, if you have updated luaotfload recently (4 February 2017), you will need to revise the invocation of \directlua as follows:

\directlua{
  fonts.handlers.otf.addfeature{
    name = "liga",
    type = "ligature",
    data = {
      ['f_f'] = { "f", "f" },
      ['f_i'] = { "f", "i" },
      ['f_f_i'] = { "f", "f", "i" },
      ['f_l'] = { "f", "l" },
      ['f_f_l'] = { "f", "f", "l" },
      ['T_h'] = { "T", "h" },
    },
  }
}

Stylistic and Contextual Alternates

Some alternates are desirable or not depending on what’s nearby. For example, Crimson’s long-tailed ‘Q’ is attractive before ‘u,’ but looks silly or collides with other glyphs if it comes at the end of a word. Compare salt, which replaces a glyph by an alternate everywhere, and calt, which replaces it in some contexts only:

\documentclass{article}
\usepackage{fontspec}
\directlua{
  fonts.handlers.otf.addfeature{
    name = "salt",
    type = "alternate",
    data =
    {
      Q = "Q.alt01",
    },
  }
  fonts.handlers.otf.addfeature{
    name = "calt",
    type = "chainsubstitution",
    lookups = {
      {
        type = "substitution",
        data = {
          ["Q"] = "Q.alt01",
        },
      },
    },
    data = {
      rules = {
        {
          after  = { { "u" } },
          current = { { "Q" } },
          lookups = { 1 },
        },
      },
    },
  }
}
\setmainfont{Crimson}
\begin{document}
(Questions about NASDAQ.) Meh.

{\addfontfeature{RawFeature=+salt}
  (Questions about NASDAQ.) Oops!}

{\addfontfeature{RawFeature=+calt}
  (Questions about NASDAQ.) That’s better.}
\end{document}

output of example

If Crimson had a long-tailed Q in its small caps, you’d get it by adding a line like this: ["q.sc"] = "q.scalt01",.

Superiors

Here I’ve found the principle, or part of it, but it’s probably better not applied to Crimson, because superiors 4–9 and 0 are designed to sit higher than superiors 1–3, as is especially noticeable in note 10 below:

\documentclass{article}
\usepackage{fontspec,realscripts}
% see Ulrike’s answer at tex.stackexchange.com/a/235302/7883
\renewcommand\footnotemarkfont{\addfontfeature{RawFeature={+sups}}}
\renewcommand\fakesuperscript[1]{#1}
\usepackage[paperwidth=180pt,paperheight=150pt,margin=12pt]{geometry}
\directlua{
fonts.handlers.otf.addfeature {
    name = "sups",
    {
        type = "substitution",
        data = {
            one = "¹",
            ["one.onum"] = "¹",
            two = "²",
            ["two.onum"] = "²",
            three = "³",
            ["three.onum"] = "³",
            four = "⁴",
            ["four.onum"] = "⁴",
            five = "⁵",
            ["five.onum"] = "⁵",
            six = "⁶",
            ["six.onum"] = "⁶",
            seven = "⁷",
            ["seven.onum"] = "⁷",
            eight = "⁸",
            ["eight.onum"] = "⁸",
            nine = "⁹",
            ["nine.onum"] = "⁹",
            zero = "⁰",
            ["zero.onum"] = "⁰",
        }
    },
    "footnote figures"
  }
}
\setmainfont{Crimson}
\begin{document}
There\footnote{Note.} are\footnote{Note.} far\footnote{Note.}
too\footnote{Note.} many\footnote{Note.}  footnotes\footnote{Note.}
in\footnote{Note.} this\footnote{Note.}  little\footnote{Note.}
sentence.\footnote{Note.}
\end{document}

sample of sups feature

You’ll have to add more such lines (e.g., ["one.prop"] = "¹", etc.,) if you want to have footnote figures whether you’re using the default figures, old-style figures, proportional figures, the slashed zero, or any other sort of figure provided.

For the luaotfload of February 2017, use \directlua this way:

\directlua{
  fonts.handlers.otf.addfeature{
    name = "sups",
    type = "substitution",
    data = {
      one = "¹",
      ["one.onum"] = "¹",
      two = "²",
      ["two.onum"] = "²",
      three = "³",
      ["three.onum"] = "³",
      four = "⁴",
      ["four.onum"] = "⁴",
      five = "⁵",
      ["five.onum"] = "⁵",
      six = "⁶",
      ["six.onum"] = "⁶",
      seven = "⁷",
      ["seven.onum"] = "⁷",
      eight = "⁸",
      ["eight.onum"] = "⁸",
      nine = "⁹",
      ["nine.onum"] = "⁹",
      zero = "⁰",
      ["zero.onum"] = "⁰",
    },
  }
}

Remove a ligature

Crimson isn’t of much use to illustrate removal of ligatures, so here’s FPL Neu (www.alice-dsl.net/ralfstubner/fplneu-otf.html) without its “fk” ligature:

\documentclass{article}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature {
    name = "nofk",
    {
        type = "multiple",
        data = {
          ["f_k"] = { "f", "k" },
        }
    },
    "get rid of fk ligatures"
  }
}
\setmainfont{FPL Neu}
\begin{document}
Kafka

\addfontfeature{RawFeature=+nofk}
Kafka
\end{document}

output of example

The result is hardly visible in a font like Garamond Premier Pro, with its long-armed f, and I can’t seem to combine this nofk feature with extra kerning.

For the luaotfload of February 2017, use \directlua this way:

\directlua{
  fonts.handlers.otf.addfeature{
    name = "nofk",
    type = "multiple",
    data = {
      ["f_k"] = { "f", "k" },
    },
  }
}

Select among standard ligatures

Some fonts put more in their liga feature than one could wish. For example, LTC Kaatskill Pro, a lovely Goudy design, makes œ a standard rather than a discretionary ligature, with the result that not only words like “œdema” but even “does” and “poem” are affected. Using type = "multiple", as for “fk” above, would fix “does” but interfere with “œdema,” so we need another approach.

To illustrate, let’s examine a freely available Carolingian minuscule. With liga, it produces results one could use to ease students into a paleography course:

\documentclass[12pt,latin]{octavo}
\usepackage{babel,fontspec,microtype}
\setmainfont{0850 Carolina Tours}
\linespread{1.10345}
\begin{document}
Invocat te, Domine, fides mea quam dedisti mihi, quam inspirasti mihi
per humanitatem Filii tui, per ministerium praedicatoris tui.
\end{document}

output

For decorative rather than scholarly purposes, we’d want to remove whatever is defined in liga but unfamiliar to contemporary readers.

Besides the harmless “ff,” “fi,” “fl,” “ft,” and “ll,” liga adds an “oe” ligature and e caudata for “ae”; it also replaces “i” and “j” with their dotless versions, and substitutes “ſ” for “s,” “u” for “v,” and “V” for “U.” We can remove those ligatures and substitutions by turning off liga, and add back the harmless ligatures by defining them as rlig, a feature which is on by default:

\documentclass[12pt,latin]{octavo}
\usepackage{babel,fontspec,microtype}
\directlua{
  fonts.handlers.otf.addfeature{
    name = "rlig",
    type = "ligature",
    data = {
      ['f_f'] = { "f", "f" },
      ['fi'] = { "f", "i" },
      ['fl'] = { "f", "l" },
      ['f_t'] = { "f", "t" },
      ['l_l'] = { "l", "l" },
    },
  }
}
\setmainfont{0850 Carolina Tours}[
  Ligatures=NoCommon]
\linespread{1.10345}
\begin{document}
Invocat te, Domine, fides mea quam dedisti mihi, quam inspirasti mihi
per humanitatem Filii tui, per ministerium praedicatoris tui.
\end{document}

output

CAVEAT

I don’t really understand what I’ve done, and there may be better ways (which I’d be glad to learn about), but at least things are more or less working.

Thérèse
  • 12.8k
  • 3
  • 37
  • 59