XeLaTeX 中特定字母的下标字距调整

XeLaTeX 中特定字母的下标字距调整

我使用了以下代码,这是对@egreg 提供的代码的微小修改在数学模式下使 f 处于活动状态,更改特定字母的下标字距(例如此示例中的 f)。

然而,有两个问题值得担忧:

a) 上标的字距也会受到影响,例如$f_{a}^{b}$

b) 如果上标位于下标之前,例如$f^{b}_{a}$,则不受影响。

我(至少在原则上)了解代码的作用以及这些问题出现的原因。但是,我还没能解决这些问题。

\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}

任何帮助都将受到赞赏。

答案1

您可以使用e的功能xparse。但实际上,mathspec是一组临时解决方案,我们正在将临时解决方案添加到临时解决方案中。

\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}

在此处输入图片描述

答案2

我已经从你提到的代码这个答案可以在宏之后捕捉下标和上标。我们的想法是让活动字符的宏捕获以下下标和上标,以便我们可以分别调整它们的字距。

\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

请注意,相对于您的实现,参数符号是反转的。与非活动字符相比,诸如$f_\text{x}$不再起作用,因为该函数仅收集\text标记,而不收集其参数。

相关内容