一些符号下标/上标组合的水平间距很丑陋

一些符号下标/上标组合的水平间距很丑陋

有时我发现我最喜欢的字体的间距lmodern很丑。下面是一个例子,其中 nabla 的下标必须调整才能不突出。大多数情况下,这些情况是数学模式下的下标和上标。

下面的特定示例在cm、和euler字体中看起来也很糟糕。

是字体的问题吗?如果是,我该如何在字体中纠正这个问题?除了手动添加字距调整之外,最好的中间解决方案是什么?

\documentclass{standalone}
\usepackage{lmodern}

\begin{document}
\(A_x \quad \nabla_x \quad \nabla_{\kern -0.2em x}\)
\end{document}

左侧,大写 A 带有下标 x,中间 nabla 带有下标 x,右侧 nabla 带有下标 x,且间距已更正。

答案1

你问,

是字体的问题吗?

您认为令人反感的水平间距不是字体的结果。相反,这是 TeX 处理下标和上标排版方式的结果:TeX 通过移动包含字符(可能还有整个子公式)的“框”或“边界框”(Postscript 术语)来组装公式。有趣的是,TeX 确实执行一些字距调整使下标与其关联的“主”字符“紧密贴合”。例如,查看$f_2^3$和的结果$C_2^3$:在这两种情况下,下标都位于上标的左侧。

重要的是,在最终的公式组装阶段,TeX 实际上并不“知道”给定框内的内容。因此,如果符号如\nabla\Gamma)不包含任何材料,右下在其各自边界框的角落后面跟着下标,就会产生“视觉空洞”。如果字母FPTV、和后面跟着下标,也会出现同样的问题,但程度要小一些。同样,如果字母、、、WY后面跟着下标,也会出现同样的问题。AL\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以获得您所展示的结果。

参考:

代码:

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

相关内容