1

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
    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
    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? Oct 26, 2020 at 11:28
  • Edited to add MWE
    – callegar
    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
    Oct 30, 2020 at 11:35

1 Answer 1

2

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
    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. Oct 30, 2020 at 21:56
  • @Davislor Why? I do have the impression that it answers the question. 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? 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
    Oct 30, 2020 at 22:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.