![XeLaTeX 中特定字母的下标字距调整](https://linux22.com/image/330930/XeLaTeX%20%E4%B8%AD%E7%89%B9%E5%AE%9A%E5%AD%97%E6%AF%8D%E7%9A%84%E4%B8%8B%E6%A0%87%E5%AD%97%E8%B7%9D%E8%B0%83%E6%95%B4.png)
我使用了以下代码,这是对@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
标记,而不收集其参数。