答案1
你问,
是字体的问题吗?
您认为令人反感的水平间距不是字体的结果。相反,这是 TeX 处理下标和上标排版方式的结果:TeX 通过移动包含字符(可能还有整个子公式)的“框”或“边界框”(Postscript 术语)来组装公式。有趣的是,TeX 确实执行一些字距调整使下标与其关联的“主”字符“紧密贴合”。例如,查看$f_2^3$
和的结果$C_2^3$
:在这两种情况下,下标都位于上标的左侧。
重要的是,在最终的公式组装阶段,TeX 实际上并不“知道”给定框内的内容。因此,如果符号如\nabla
和\Gamma
)不包含任何材料,右下在其各自边界框的角落后面跟着下标,就会产生“视觉空洞”。如果字母F
、P
、T
、V
、和后面跟着下标,也会出现同样的问题,但程度要小一些。同样,如果字母、、、W
和Y
后面跟着下标,也会出现同样的问题。A
L
\lambda
\Lambda
\Delta
后面跟着上标,也会出现视觉空洞,因为这些字符在文本中几乎没有或根本没有内容。右上方各自边界框的角落。
如果是的话,我该如何纠正字体呢?
由于这不是字体本身的问题(而是符号形状的问题),因此在字体级别上无法采取任何措施。
除了手动添加字距调整之外,最好的中间解决方案是什么?
我不会声称以下是最佳解决方案,但如果您愿意并且能够使用 LuaLaTeX 而不是 pdfLaTeX 或 XeLaTeX 来编译文档,则可以使用它。该解决方案设置了一个名为的 Lua 函数,suppl_math_kerning
该函数可对各种符号和字符组合执行自动字距调整。按照通常的 TeX 语法规则,下标和上标假定由以下任一字符组成:单身的字母数字字符(AZ,az,0-9——在下面的 Lua 代码中表示为%w
)或用一对花括号括起来的内容(在下面的 Lua 代码中表示为)。通过执行 LaTeX 宏 激活 Lua 函数,通过执行 LaTeX 宏 停用%b{}
Lua 函数。\SupplKernOn
\SupplKernoff
以下代码中使用的字距调整值 -- -4mu
、-3mu
和-1.5mu
,其中“ mu
”等于 -- 的三分之一,\thinspace
似乎对于该Latin Modern Math
字体来说“大致正确”。对于其他数学字体,字距调整可能更大或更小都是合适的。
% !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}
答案2
您可以定义一个宏来为您完成此操作。以下是原始输出和使用该宏:
笔记:
- 我使用了负薄空间,
\!
因为我觉得它看起来更好,但您可以用它来替换\kern -0.2em
以获得您所展示的结果。
参考:
- 该
e_
参数没有太多文档,因此您可以使用 egreg 的解决方案Xparse 的新 e-type 参数(k-type 参数的替代)作为指导。
代码:
\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}