19

Sometimes I find the spacing of my favourite font lmodern ugly. Below is an example, where the subscript of the nabla has to be adjusted to not stick out. Most of the time, these cases are the sub- and superscripts in math mode.

The particular example below looks bad in cm, and euler fonts, too.

Is the font to blame? If so, how can I get it corrected in the font? What would be the best intermediate solution, instead of manually adding kernings?

\documentclass{standalone}
\usepackage{lmodern}

\begin{document}
\(A_x \quad \nabla_x \quad \nabla_{\kern -0.2em x}\)
\end{document}

Left, Capital A with subscript x, middle nabla with subscript x, right nabla with subscriptx with corrected spacing.

2 Answers 2

11

You asked,

Is the font to blame?

The horizontal spacing you find objectionable is not a consequence of the font. Instead, it's a consequence of the way TeX handles the typesetting of subscripts and superscripts: TeX assembles a formula by moving around "boxes", or "bounding boxes" (in postscript jargon) which contain characters (and possibly entire subformulas). Interestingly, TeX does perform some kerning to "snug up" the subscripts to their associated "main" characters. E.g., check out the results of $f_2^3$ and $C_2^3$: in both cases, the subscripts are placed slightly to the left of the superscripts.

Importantly, during the final formula assembly stage, TeX doesn't actually "know" what's inside a given box. Thus, if symbols such as \nabla and \Gamma, which contain no material in the lower-right corner of their respective bounding boxes, are followed by a subscript, a "visual hole" is created. To a somewhat lesser extent, the same issue occurs if the letters F, P, T, V, W, and Y are followed by a subscript. Likewise, if the letters A, L, \lambda, \Lambda and \Delta are followed by a superscript, a visual hole can appear since these characters have little or no material in the upper-right corner of their respective bounding boxes.

If so, how can I get it corrected in the font?

Since it's not an issue of the font itself (but of the shapes of the symbols), there's nothing that can be done at the font level.

What would be the best intermediate solution, instead of manually adding kernings?

I won't claim that the following is the best possible solution, but it's available to you if you're willing and able to use LuaLaTeX instead of either pdfLaTeX or XeLaTeX to compile your document. The solution sets up a Lua function called suppl_math_kerning which performs automatic kerning adjustments for various symbol and character combinations. As per the usual TeX syntax rules, subscripts and superscripts are assumed to consist either of a single alphanumeric character (A-Z,a-z,0-9 -- represented by %w in the Lua code below) or of material that's enclosed in a pair of curly braces (represented as %b{} in the Lua code below). The Lua function is activated by executing the LaTeX macro \SupplKernOn, and it is deactivated by executing the LaTeX macro \SupplKernoff.

The kerning values used in the code below -- -4mu, -3mu, and -1.5mu, where "mu" equals a third of \thinspace -- appear to be "about right" for the Latin Modern Math font. For other math fonts, either more or less kerning may be appropriate.

enter image description here

% !TEX TS-program = lualatex
\documentclass{article} 
%\usepackage{amsmath}       % optional
\usepackage{unicode-math}  % optional

\usepackage{luacode}
\begin{luacode}
function suppl_math_kerning ( s )
  -- Subscript combinations
  -- \nabla
  s = s:gsub ("(\\nabla)%s-_%s-(%b{})", "%1_{\\mkern-4mu   %2}" )
  s = s:gsub ("(\\nabla)%s-_%s-(%w)"  , "%1_{\\mkern-4mu   %2}" )
  -- \Gamma
  s = s:gsub ("(\\Gamma)%s-_%s-(%b{})", "%1_{\\mkern-4mu   %2}" )
  s = s:gsub ("(\\Gamma)%s-_%s-(%w)"  , "%1_{\\mkern-4mu   %2}" )
  -- \Psi
  s = s:gsub ("(\\Psi)%s-_%s-(%b{})"  , "%1_{\\mkern-3mu   %2}" )
  s = s:gsub ("(\\Psi)%s-_%s-(%w)"    , "%1_{\\mkern-3mu   %2}" )
  -- \Upsilon
  s = s:gsub ("(\\Upsilon)%s-_%s-(%b{})","%1_{\\mkern-3mu  %2}" )
  s = s:gsub ("(\\Upsilon)%s-_%s-(%w)"  ,"%1_{\\mkern-3mu  %2}" )
  -- letters T, V, W, Y
  s = s:gsub ("([VWY])%s-_%s-(%b{})"  , "%1_{\\mkern-3mu   %2}" )
  s = s:gsub ("([VWY])%s-_%s-(%w)"    , "%1_{\\mkern-3mu   %2}" )
  -- letters F, P, T
  s = s:gsub ("([FPT])%s-_%s-(%b{})"  , "%1_{\\mkern-1.5mu %2}" )
  s = s:gsub ("([FPT])%s-_%s-(%w)"    , "%1_{\\mkern-1.5mu %2}" )

  -- Superscript combinations
  -- \Delta
  s = s:gsub ("(\\Delta)%s-%^%s-(%b{})", "%1^{\\mkern-3mu  %2}" )
  s = s:gsub ("(\\Delta)%s-%^%s-(%w)"  , "%1^{\\mkern-3mu  %2}" )
  -- \Lambda
  s = s:gsub ("(\\Lambda)%s-%^%s-(%b{})","%1^{\\mkern-3mu  %2}" )
  s = s:gsub ("(\\Lambda)%s-%^%s-(%w)"  ,"%1^{\\mkern-3mu  %2}" )
  -- \lambda
  s = s:gsub ("(\\lambda)%s-%^%s-(%b{})","%1^{\\mkern-2mu  %2}" )
  s = s:gsub ("(\\lambda)%s-%^%s-(%w)"  ,"%1^{\\mkern-2mu  %2}" )
  -- letters A, L
  s = s:gsub ("([AL])%s-%^%s-(%b{})"  , "%1^{\\mkern-1.5mu %2}" )
  s = s:gsub ("([AL])%s-%^%s-(%w)"    , "%1^{\\mkern-1.5mu %2}" )  
  return s
end
\end{luacode}

\newcommand\SupplKernOn{\directlua{luatexbase.add_to_callback ( 
  "process_input_buffer" , suppl_math_kerning , "suppl_math_kerning" ) }}
\newcommand\SupplKernOff{\directlua{luatexbase.remove_from_callback ( 
  "process_input_buffer" , "suppl_math_kerning" ) }}

\begin{document}

%% subscript cases
$\nabla_x \ \Gamma_y \ \Upsilon_0 \ \Psi_1\ F_2 \ P_3 \ T_n \ V_4 \ W_5 \ Y_6$ --- unadjusted

\SupplKernOn
$\nabla_{x} \ \Gamma_{y} \ \Upsilon_{0} \ \Psi_{1}\ F_{2} \ P_{3} \ T_{n} \ V_{4} \ W_{5} \ Y_{6}$ --- adjusted

\medskip
%% superscript cases
\SupplKernOff
$\displaystyle A^2 \ L^x\ \Delta^2 \  \lambda^2 \ \Lambda^2$ --- unadjusted

\SupplKernOn
$\displaystyle A^2 \ L^x\ \Delta^2 \  \lambda^2 \ \Lambda^2$ --- adjusted
\end{document}
3
  • 1
    I assume the "1. List item" is not an elaborate ploy to create suspense for the reader.
    – moewe
    Commented May 18, 2018 at 18:35
  • 1
    What about MathItalicsCorrectionInfo? I thought TeX had a similar mechanism, see slide 32 (Super- and Subscript Positioning) on Johannes Küster's slides. Could you please comment on them in your great answer!
    – Mankka
    Commented May 21, 2018 at 17:31
  • 1
    @Mankka - Thanks for these suggestions and for pointing out Johannes Küster's slides. I've updated my answer to incorporate additional Greek letters -- \Psi, \Upsilon, \Delta, \lambda, \Lambda -- and so say a bit more about TeX's kerning process for subscripts. TeX actually does perform some kerning by default for subscripts; it's just that it's not enough if the "main" character has no material in either the bottom-right or the top-right corner of the bounding box.
    – Mico
    Commented May 21, 2018 at 18:52
11

You could define a macro that does that for you. Following is original output and using the macro:

enter image description here

Note:

  • I used a negative thin space, \!, as that looks better to me, but you can replace that with \kern -0.2em to get the results you showed.

References:

Code:

\documentclass{article}
\usepackage{lmodern}
\usepackage{xparse}

\makeatother
\let\OldNabla\nabla
\RenewDocumentCommand{\nabla}{e_}{%
    \OldNabla
    \IfValueT{#1}{%
        _{\!#1}
    }%
}
\makeatletter

\begin{document}
\(A_x \quad \OldNabla_x \quad \OldNabla_{\kern -0.2em x}\)
\par
\(A_x \quad \nabla_x \)

\end{document}
1
  • This answer does not address the first two questions.
    – Mankka
    Commented May 18, 2018 at 11:34

You must log in to answer this question.

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