1

I'm trying to add some contextual alternatives to Linux Libertine using fonts.handlers.otf.addfeature. I can add these characters correctly using an ordinary substitution, but they are not recognized when using a chain substitution.

The two alternative characters I'm after are the R and K from +ss02 (I do not want the J that comes with them). These characters both sit in the font's private use section. With a simple substitution, they can be accessed as R.alt and K.alt. They can also be invoked with \Uchar. But I'd like the alternate R to appear only ahead of a vowel and the alternate K only ahead of an n.

The code below illustrates the issue.

My question is: how can the feature called crkalt be fixed so that the alternative R is recognized and used in the intended context?

(I am aware of this excellent thread on the general topic.)

\documentclass[12pt]{article}
\usepackage{luacode,luatexbase,xcolor}
    
% stylistic alternates for R and K
\directlua{
  fonts.handlers.otf.addfeature {
    name = "rkalt", 
    type = "substitution",
    data =
    {
      ["K"] = "K.alt",  %% works fine
      ["R"] = "R.alt",  %% works fine
    },
  }
  fonts.handlers.otf.addfeature{
    name = "crkalt",
    type = "chainsubstitution",
    lookups = {
      {
          type = "multiple",
          data = {
              ["R"] = "R.alt",   %% does not recognize "R.alt"
          },
      },
      {
          type = "multiple",
          data = {
              ["K"] =  "Khook" , %% "K.alt" not recognized; using Khook to show other code works
          },
      },
      {
          type = "multiple",
          data = {
             ["R"] = "r", %% just to show that the R substitutions are working contextually
          },
      },      
    },
    data = {
      rules = {
        {
          after  = { { "a" , "e", "i", "o", "u" }},
          current = { { "R" } },
          lookups = { 1 },
        },
        {
          after  = { { "n" } },
          current = { { "K" } },
          lookups = { 2 },
        },
        {
          before  = { { "d" }},
          current = { { "R" } },
          lookups = { 3 },
        },
      },
    },
    }
}

% Can call these characters individually
\def\Rswash{\Uchar"E0EC}
\def\Kswash{\Uchar"E0EB}
\def\Khook{\Uchar"0198}


\usepackage{fontspec}
\setmainfont{Linux Libertine O}[%
    Numbers=OldStyle,%
    BoldFont={Linux Libertine O Semibold},%
    BoldFeatures = {Color=violet},
]

%% test string
\def\TestString{Rather Knotty! JR? Re, Ri, Ro, Ru, Rz, dRd}
\newcommand\TryIt[1]{\textsc{\textbf{#1:}} {\addfontfeatures{RawFeature={#1}} \TestString}\par}


\begin{document}
\TestString\par
\TryIt{+ss02}\TryIt{+rkalt}\TryIt{+crkalt}
\Rswash\Kswash\Khook

\end{document}

enter image description here

0

1 Answer 1

1

I resolved this issue by loading fontspec before the directlua block.

Some of the glyph names in Linux Libertine O differ from those used by the default font. (This thread provided the tools I used to check the glyph names of the font.) Perhaps that's why the loading order matters.

\documentclass[12pt]{article}
\usepackage{luacode,luatexbase,xcolor}

\usepackage{fontspec}
\setmainfont{Linux Libertine O}[%
    Numbers=OldStyle,%
    BoldFont={Linux Libertine O Semibold},%
    BoldFeatures = {Color=violet},
]
    
% stylistic alternates for R and K
\directlua{
  fonts.handlers.otf.addfeature {
    name = "rkalt", 
    type = "substitution",
    data =
    {
      ["K"] = "K.alt",  
      ["R"] = "R.alt",  
    },
  }
  fonts.handlers.otf.addfeature{
    name = "crkalt",
    type = "chainsubstitution",
    lookups = {
      {
          type = "multiple",
          data = {
              ["R"] = "R.alt", 
          },
      },
      {
          type = "multiple",
          data = {
              ["K"] =  "K.alt" , 
          },
      },
      {
          type = "multiple",
          data = {
             ["R"] = "r", %% just to try a different context for R substitution
          },
      },      
    },
    data = {
      rules = {
        {
          after  = { { "a" , "e", "i", "o", "u" }},
          current = { { "R" } },
          lookups = { 1 },
        },
        {
          after  = { { "n" } },
          current = { { "K" } },
          lookups = { 2 },
        },
        {
          before  = { { "d" }},
          current = { { "R" } },
          lookups = { 3 },
        },
      },
    },
    }
}

% Can call these characters individually, as well
\def\Rswash{\Uchar"E0EC}
\def\Kswash{\Uchar"E0EB}
\def\Khook{\Uchar"0198}

%% test string
\def\TestString{Rather Knotty! JR? Re, Ri, Ro, Ru, Rz, dRd}
\newcommand\TryIt[1]{\textsc{\textbf{#1:}} {\addfontfeatures{RawFeature={#1}} \TestString}\par}

\begin{document}
\TestString\par
\TryIt{+ss02}\TryIt{+rkalt}\TryIt{+crkalt}
\Rswash\Kswash\Khook

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .