2

for a document, I am forced to use an otf font that has no math companion. For consistency reasons, I thus need to use my text font for operators and digits. So far I have:

\setmainfont{Source Serif Pro}
\setsansfont{Source Sans Pro}[Scale=MatchLowercase]
\setmonofont{Source Code Pro}[Scale=MatchLowercase]
\setmathfont{Erewhon Math}[Scale=1.1]
\setmathfont[range=up]{Source Serif Pro}
\setmathfont[range=it]{Source Serif Pro Italic}

which is not bad (at least for what I need to do). I am getting lots of complaints from fontspec about missing Math script in the fonts and lack of font features (e.g. Style=MathScript) but the typesetting seems more or less OK. My sole issue is with math accents that get badly misplaced.

For instance, consider this MWE:

\documentclass{article}
\usepackage{unicode-math}
\setmainfont{Source Serif Pro}
\setsansfont{Source Sans Pro}[Scale=MatchLowercase]
\setmonofont{Source Code Pro}[Scale=MatchLowercase]
\setmathfont{Erewhon Math}[Scale=1.1]
\setmathfont[range=up]{Source Serif Pro}
\setmathfont[range=it]{Source Serif Pro Italic}

\begin{document}
$\hat V$
\end{document}

When compiled via LuaLaTeX, the accent on top of the V is way to much on the right.

Is it possible to somehow manually 'inject' info about the accent positioning? Even going down to a lua script if needed...

5
  • Using a text accent inside a box might work for you. There’s also plain TeX \skew.
    – Davislor
    Commented Oct 25, 2020 at 21:14
  • You might also change the \skewchar, which LuaTeX still uses by default when an accentee lacks a top_accent value.
    – Davislor
    Commented Oct 25, 2020 at 21:16
  • @Callegar When I create a minmal document with such settings the accents look fine. Could you add a MWE? Commented Oct 26, 2020 at 11:28
  • Edited to add MWE
    – callegar
    Commented Oct 30, 2020 at 11:32
  • @Davislor How do you set the \skewchar. From my understanding and a TeX reference I need to pass a font name as in \skewchar\myfont="30. However, the font name gets defined implicitly when I use \setmathfont. What is my font name? Furthermore, is there a way to add the top_accent attribute to a char using Lua?
    – callegar
    Commented Oct 30, 2020 at 11:35

1 Answer 1

3

You can set custom top_accent values by adding a font feature and patching the font table, but by default this will be ignored because you aren't loading a math font. So additionally, you'll have to declare your font a mathfont. Then, it still won't work because LuaTeX considers the font a legacy mathfont and therefore doesn't apply the OpenType mathfont based top_accent value. So you have to emulate being an OpenType mathfont. This requires you to set at least one math parameter. That's a bit problematic becuase this will overwrite the corresponding parameters from your primary mathfont, so you'll have to reload you primary mathfont later to fix up the parameters again.

A possible approach would be (comments inline)

\documentclass{article}
\usepackage{unicode-math}

% First some catcode setup, not really important
\begingroup
  \long\def\x#1{\directlua{\unexpanded{#1}}}
  \catcode`\#=12 \catcode`\%=12
  \expandafter\endgroup\x{
  --[[Declare a helper \DeclareTopAccent to invoke the package later]]
  local id = luatexbase.new_luafunction'DeclareTopAccent'
  local mappings = {}
  token.set_lua('DeclareTopAccent', id)
  lua.get_functions_table()[id] = function()
    --[[This is executed when the command is called. We have to parse the input. Take a peek at the usage of \DeclareTopAccent below before trying to read the code, then it should be relativly easy to follow]]
    local t = {}
    repeat
      local cp = assert(token.scan_int(), 'No codepoint found')
      token.scan_keyword'='
      t[cp] = assert(token.scan_int(), 'No offset found')
    until not token.scan_keyword';'
    assert(token.scan_token().cmdname == 'relax', 'Final delimiter missing')
    --[[Save the parsed mapping in a global table and then send the index back to TeX]]
    mappings[#mappings+1] = t
    tex.sprint(string.format("top_accents_id=%i", #mappings))
  end

  --[[Now implement the feature. Nothing particularly interesting here, it's 
    the same as almost any use of otf.register: Take the feature value, do some lookups, apply to characters]]
  fonts.constructors.features.otf.register {
    name = 'top_accents_id',
    description = 'Change selected top_accent values',
    initializers = {
      base = function(tfmdata, value, features)
        local mapping = assert(mappings[value], "I'm going to strike")
        local characters = tfmdata.characters
        for cp, top_accent in next, mapping do
          --[[For some reason some properties have different names here than the native LuaTeX name. E.g. top_accent is just accent]]
          assert(characters[cp], 'Why are you doing this to me?').accent = top_accent
        end
        --[[For top_accent to have any effect, LuaTeX must consider this a modern Math font.
          To fake that, we'll provide a dummy parameter if necessary. MinConnectorOverlap = 0 should be relativly safe.
          Remember to reset your math parameters after loading this font]]
        if not tfmdata.mathparameters or not next(tfmdata.mathparameters) then
          tfmdata.mathparameters = { MinConnectorOverlap = 0 }
        end
      end,
    },
  }
}

\setmainfont{Source Serif Pro}
\setmathfont{Erewhon Math}[Scale=1.1]
% Example of usage: \DeclareTopAccent expects pairs of codepoint and top_accent value,
% separated by ; and terminated with \relax.
% The unit of top_accent is milli-em, so in most cases values around 500 are a good starting point.
\setmathfont[range=it, RawFeature={\DeclareTopAccent `\W=550;`\V=450\relax}]{Source Serif Pro Italic}
% Reset Math parameters messed up by the other fonts
\setmathfont{Erewhon Math}[Scale=1.1, range={}]

\begin{document}
$\hat V$
$\hat W$
\end{document}

enter image description here

But while this is possible, it is a lot of work to adapt these for all characters and you still don't get a font as good as a proper math font. You should really try to switch to an OpenType math font as soon as possible.

7
  • 1
    I believe the OP is in fact using an OpenType math font, but is taking the math alphabets from a different OpenType font.
    – Davislor
    Commented Oct 30, 2020 at 21:09
  • @Davislor I think so too but I tried to say that taking a Math font with it's own alphabet (or the alphabet of another math font) is strongly preferable over trying to integrate a text font. Commented Oct 30, 2020 at 21:56
  • @Davislor Why? I do have the impression that it answers the question. Commented Oct 30, 2020 at 22:17
  • @Davislor After all the OP asked how they can inject information for accent positioning which is exactly what is done here. Or am I missing something? Commented Oct 30, 2020 at 22:18
  • Okay, I see what you’re doing now. The wording about not loading a math font confused me at first.
    – Davislor
    Commented Oct 30, 2020 at 22:42

You must log in to answer this question.

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