2

I have used the following code, which is a minor modification of @egreg's code provided in Making f active in math mode, to change the subscript kerning for specific letters (e.g. f in this example).

However, there are two concerns:

a) the kerning of superscripts is also affected e.g. in $f_{a}^{b}$

b) if a superscript precedes the subscript, as e.g. in $f^{b}_{a}$, nothing is affected.

I understand (at least in principle) what the code does and why these issues come up. However, I haven't been able to resolve them.

\documentclass{article}
\usepackage{fontspec}
\usepackage{xunicode}

\makeatletter
\DeclareRobustCommand{\fixsubkerning}[3]{
\AtBeginDocument{%
  \edef\SAVEfCODE{\the\Umathcodenum`#1 } % just for the test
  \Umathcharnumdef#3\Umathcodenum`#1
  \mathcode`#1=\string"8000 }
\begingroup\lccode`~=`#1
\lowercase{\endgroup
  \def~{%
    #3
    \ifnum\mathgroup=\m@ne
      \expandafter\@firstofone
    \else
      \expandafter\@gobble
    \fi
    {\@ifnextchar_{\mkern-#2mu}{\relax}}%
  }
}
}
\makeatother

\fixsubkerning{f}{5}{\mathf}

\begin{document}
\[
f_{a}
\]
\end{document}

Any help is appreciated.

niels
  • 3,295

2 Answers2

2

You can use the e feature of xparse. But, really, mathspec is a set of kludges and we're adding kludges to kludges.

\documentclass{article}
\usepackage{mathspec}
\setmainfont{Hoefler Text}
\setmathfont(Digits,Latin)[Numbers=Lining]{Hoefler Text}
\setmathrm[Numbers=Lining]{Hoefler Text}

\AtBeginDocument{%
  \Umathcharnumdef\mathematicalf\Umathcodenum`f 
  \mathcode`f=\string"8000
}

\NewDocumentCommand{\usemathematicalf}{e{_^}}
 {
  \usemathematicalfaux#1
 }
\ExplSyntaxOn
\NewDocumentCommand{\usemathematicalfaux}{mm}
 {
  \mathematicalf
  \IfValueTF{#1}{\sb{#1}}{ \int_compare:nT { \mathgroup=-1}{\,} }
  \IfValueT{#2}{\sp{\mkern4mu\scan_stop: #2}}
 }
\char_set_active_eq:NN f \usemathematicalf
\ExplSyntaxOff

\begin{document}

$f(x)f_1(x)\mathbf{f}(x)\mathbf{f}_1(x)\mathbf{f_1}(x)$

$f(x)f_1(x)f_1^2(x)f^2_1(x)\mathbf{f}_1^{\,2}(x)$

\end{document}

enter image description here

egreg
  • 1,121,712
  • How can I get kerned f in pdflatex? I mean, I would like to get the f letter with negative space in subscript as f_{\!2}^2 in an automatic manner. – mert Sep 03 '22 at 19:50
  • @mert It's generally already kerned. – egreg Sep 03 '22 at 20:08
  • You are right. But I would like to learn this for a specific purpose. Would you like to do that, if possible? – mert Sep 03 '22 at 20:15
  • @mert Please ask a specific question with all the details. – egreg Sep 03 '22 at 20:57
0

I've pieced together a solution from the code you mentioned and this answer to catch sub- and superscripts after a macro. The idea is to have the active character's macro catch following sub- and superscripts so that we can kern them separately.

\makeatletter
\DeclareRobustCommand{\fixkerning}[4]{
\AtBeginDocument{%
  \Umathcharnumdef#4\Umathcodenum`#1
  \mathcode`#1=\string"8000 }
\begingroup\lccode`~=`#1
\lowercase{\endgroup
  \def~{%
    #4
    \ifnum\mathgroup=\m@ne
      \expandafter\@firstofone
    \else
      \expandafter\@gobble
    \fi
    {%
      \let\fix@sub\@empty%
      \let\fix@sup\@empty%
      \def\fix@kernsub{#2mu}%
      \def\fix@kernsup{#3mu}%
      \fix@test%
    }%
  }
}
}

\def\fix@test{%
  \@ifnextchar_{\fix@catch@sub}{%
    \@ifnextchar^{\fix@catch@sup}{\fix@fini}}}
\def\fix@catch@sub_#1{%
  \expandafter\def\expandafter\fix@sub\expandafter{\fix@sub#1}\fix@test}
\def\fix@catch@sup^#1{%
  \expandafter\def\expandafter\fix@sup\expandafter{\fix@sup#1}\fix@test}
\def\fix@fini{%
  \ifx\fix@sub\@empty\else_{\mkern\fix@kernsub\fix@sub}\fi%
  \ifx\fix@sup\@empty\else^{\mkern\fix@kernsup\fix@sup}\fi}

\fixkerning{f}{-2}{0}{\math@f}
\makeatother

Notice the reversal of the argument sign with respect to your implementation. Compared to nonactive characters, things like $f_\text{x}$ do not work anymore because the function collects only the \text token but not its argument.

Roland W
  • 483