[Tex/LaTex] Improved kerning in fractions

fractionskerningtypography

Question

How can I apply selective kerning within the numerator and denominator of an inline fraction? Specifically, I'd like to:

  • Tighten kerning after the numerator if it ends in 7
  • Loosen kerning after the numerator if it ends in 4
  • Tighten kerning before the denominator if it begins with 4
  • Loosen kerning before the denominator if it begins with 5 or 7

Background

I'm not quite satisfied with \sfrac or \nicefrac for typesetting fractions in passages of text, so I've been working on a macro called \textfrac. I'm pleased with the results so far, except the kerning, as mentioned above.

Features of \textfrac:

  • Uses 5-point type for numerator and denominator, rather than 7-point type.
  • In Computer Modern and Latin Modern, aligns perfectly with height and depth of standard numerals.
  • Works great inside of \textit and \textbf. (Except for small issue noted later.)
  • Takes an integer as an optional argument. If present, it adds micro-kerning between the integer and the fraction—for example 2½ becomes 2 ½. Also adds italic correction between the integer and the fraction.
  • Looks ahead using \futurelet to add additional a hair space after the fraction if it is not already followed by white space (for example a period or comma). The implementation of this isn't quite right yet, however, as it fails to detect the space token if the next token is } and then space.
  • A star version typesets the fraction using a horizontal bar instead of a diagonal solidus.

Here is a comparison with three popular fraction styles:


table

And the same comparison in paragraph form:


paragraphs

Additional question

How can I fix \textfrac* so that the denominator and horizontal bar are shifted to the left when used inside of \textsl and \textit?


rm sl it bf

Closer view:


want

Minimal working example

\documentclass{article}
\usepackage{ifthen}    % for use in \textfrac

\makeatletter

% Add a hair space if the fraction is followed by a non-space token.
\newcommand{\textfrac@kern}{%
  \ifx\textfrac@nexttoken\@sptoken%
    %
  \else%
    \kern.08333em%
  \fi%
}

% The non-star version of \textfrac uses a diagonal solidus.
\newcommand{\textfrac@nostar}[3][]{%
  \mbox{%
    \ifthenelse{\not\equal{#1}{}}%  Test for integer portion [optional #1]
      {#1\/\kern.05em}%                 Present? Emit integer and hair space
      {}%                             Not present? Emit nothing
    \raisebox{.775ex}{\tiny #2}%    Emit numerator [#2]
    \raisebox{.365ex}{\kern-.15em{\scriptsize /}\kern-.15em}%  Emit solidus
    \raisebox{0ex}{\tiny #3}%       Emit denominator [#3]
  }%
  \futurelet\textfrac@nexttoken\textfrac@kern%
}

% The star version of \textfrac uses a horizontal rule.
\newlength\textfrac@width@num%
\newlength\textfrac@width@denom%
\newlength\textfrac@width@%
\newcommand{\textfrac@star}[3][]{%
  \settowidth{\textfrac@width@num}{\tiny #2\/}%
  \settowidth{\textfrac@width@denom}{\tiny #3\/}%
  \ifthenelse{\lengthtest{\textfrac@width@num<\textfrac@width@denom}}%
    {\let\textfrac@width@\textfrac@width@denom}%
    {\let\textfrac@width@\textfrac@width@num}%
  \mbox{%
    \ifthenelse{\not\equal{#1}{}}%  Test for integer portion [optional #1]
      {#1\/\kern.08333em}%              Present? Emit integer and hair space
      {}%                             Not present? Emit nothing
    \ooalign{%
      \relax\cr%
      \noalign{\vskip-1.1ex}%
      {\hss\tiny #2\/\hss}\cr%        Emit numerator [#2]
      \noalign{\vskip1.1ex}%
      \rule[.6666ex]{\textfrac@width@}{.4pt}\cr%   Emit horizontal rule
      \noalign{\vskip.4ex}%
      {\hss\tiny #3\/\hss}\cr%        Emit denominator [#3]
      \noalign{\vskip-.4ex}%
    }%
  }%
  \let\textfrac@width\undefined%
  \futurelet\textfrac@nexttoken\textfrac@kern%
}

% Select between \textfrac and \textfrac*.
\def\textfrac{\@ifstar\textfrac@star\textfrac@nostar}

\makeatother

\begin{document}

\noindent\textrm{\textfrac[2]{1}{2} cups\quad \textfrac*[2]{1}{2} cups\\}
\noindent\textit{\textfrac[2]{1}{2} cups\quad \textfrac*[2]{1}{2} cups\\}

\end{document}

Best Answer

One way to shift your numerators in an italic context would be

 {\hss\tiny\kern\fontdimen\@ne\font#2\/\kern-\fontdimen\@ne\font\hss}\cr%        Emit numerator [#2]

as for safe ways of looking ahead and adding space or not, you might want to look at latex's definition of \DeclareTextFontCommand which defines \textit and friends to add italic correction at the start or end, depending.

Related Question