数学嵌套上标和下标内联显示不正确

数学嵌套上标和下标内联显示不正确

在内联数学中使用嵌套上标和下标时,我遇到了一个奇怪的错误(displaystyle 工作正常)。无论使用哪种字体或编译器,此行为都是相同的(最初使用 with,luaLaTeXunicode-math也使用 plainpdfLaTeX

\documentclass{standalone}
\begin{document}

Some text is \(\omega_{m_{ij}}^r\) and \(\omega_{m_{ij}}^{r_{ij+1}}\)

\end{document}

在此处输入图片描述

任何想法如何解决这一问题?

编辑:与输出进行比较\everymath{\displaystyle}

在此处输入图片描述

答案1

我认为你可以将这种奇怪的行为视为 TeX 的上下标定位算法中的一个错误;这没有道理两个都下标和上标都凸起。请参阅下文中有关如何修复此问题的一些建议。最后,我提供了一种新的定位算法,并将其与旧算法进行了比较。(抱歉这个答案太长了!)

发生了什么?

定位算法在 TeXbook 附录 G 规则 18 中规定。具体情况如下:首先,定义下标和上标的暂定位置(规则 18c 和 18d)。问题出现在规则 18e 中:仅有的如果上标和下标之间的距离太近(根据暂定位置,小于默认规则厚度的四倍),TeX 会确保上标的底部至少高出基线 80% 的 x 高度。在这种情况下,上标可能会被抬高到超出实现默认规则厚度四倍的最小距离所需的高度,然后下标也会被抬高!

为了说明问题,我使用m作为下标,并使用高度为 0 且深度不同的规则作为上标:

比较

在第一种情况下,深度为0.34ex,在第二种情况下为0.35ex:细微的差别导致输出结果大不相同。我认为这种行为并不可取。请注意,这种情况只会因为 的m高度较小而发生,而不会发生在带有上升器的字母上f

\documentclass{article}
\newcommand\test[1]{\omega_m^{\rule[-#1ex]{1pt}{#1ex}}}
\begin{document}
$\test{0.34}$ versus $\test{0.35}$
\end{document}

让我指出,同样的效果可能发生在 中\displaystyle:然后上标默认设置得更高一些,以便效果出现在 的深度与 的深度0.46ex0.47ex因此,这是一个好运气的例子,这对你的情况有帮助(正如 David 的回答中所观察到的)。让我指出,在“拥挤”的风格中(如在和\displaystyle下使用),效果可能非常剧烈:给出\overline\sqrt$\overline{a_n^ia_n^j}$

\overline 的输出

解决问题的可能方法

我发现至少有三种完全不同的方法可以解决这个问题;我不知道该选择哪一种。第一的一个想法(参见 David 对这个答案的第二条评论)是给下标添加一个支柱,使其高度足够,以至于 TeX 不会提高它的高度。以下代码定义了\scriptstrut一个只是足够大;然而,我认为输出仍然不是最优的:第二个上标提升太多了。

输出:上标凸起过多

\documentclass{article}
\makeatletter
\AtBeginDocument{%
  \check@mathfonts               % initialize math fonts
  \dimen@=\fontdimen5\textfont2  % x-height
  \multiply\dimen@ by 4
  \divide  \dimen@ by 5          % 80% of the x-height
  \advance \dimen@ by \fontdimen17\textfont2
  \@tempdima=\fontdimen8\textfont3
  \multiply\@tempdima by 4       % 4x the default rule thickness
  \advance \dimen@ by -\@tempdima
  \edef\scriptstrut{\noexpand\rule{0pt}{\the\dimen@}}%
  }
\makeatother
\begin{document}
$\omega_{m_{ij}}^r$ versus $\omega_{m_{ij}\scriptstrut}^{r_{ij+1}}$
\end{document}

现在,你必须\scriptstrut在所有过高的下标上添加一个。一个可以尝试通过激活下划线来实现自动化_(另请参阅 mafp 的第二条评论),但以安全的方式执行此操作并不容易:请注意,例如$a_\frac12$是有效的(尽管不推荐)TeX 代码。

这是我的第二想法:默认情况下,如果存在上标,TeX 会将下标放在较低位置。您可以通过添加

\makeatletter
\AtBeginDocument{%
  \check@mathfonts %initialize math fonts
  \fontdimen17\textfont2=\fontdimen16\textfont2
  }
\makeatother

您的前言。这并不能完全消除问题,但会使问题变得不那么明显。然而,可能会有其他副作用。

新的定位算法

可能是最好的方法是使用另一种算法来垂直定位子/上标组合。我在下面的代码中提供了这样一种新算法,其中我定义了一个\nss命令(如“自然子和上标”),它有三个参数,第二个是第一个的子标,第三个是第一个的上标。

输出

我使用的规则如下,尽可能接近原始算法:使用 TeX 引擎会使用的临时默认位置。为了使下标和上标之间的距离至少为默认规则厚度的四倍,请升高上标,但前提是其底部最多为基线上方 x 高度的 80%。如果下标和上标之间的距离仍然太小,请降低下标。

\documentclass{article}
\usepackage{mathtools}
\makeatletter
\newcommand*\nss[3]{%
  \begingroup
  \setbox0\hbox{$\m@th\scriptstyle\cramped{#2}$}%
  \setbox2\hbox{$\m@th\scriptstyle#3$}%
  \dimen@=\fontdimen8\textfont3
  \multiply\dimen@ by 4             % 4x the default rule thickness
  \advance \dimen@ by \ht0
  \advance \dimen@ by -\fontdimen17\textfont2
  \@tempdima=\fontdimen5\textfont2  % x-height
  \multiply\@tempdima by 4
  \divide  \@tempdima by 5          % 80% of the x-height
  % Modifications are only necessary if the top of the subscript is not that high:
  \ifdim\dimen@<\@tempdima
    \ht0=0pt                        % don't let the subscript interfere
    \@tempdima=\fontdimen5\textfont2
    \divide\@tempdima by 4          % 25% of the x-height
    \advance \dimen@ by -\@tempdima % if >0, add to depth of superscript!
    \ifdim\dimen@>0pt
      \@tempdima=\dp2
      \advance\@tempdima by \dimen@
      \dp2=\@tempdima
    \fi
  \fi
  #1_{\box0}^{\box2}%
  \endgroup
  }
\makeatother
\begin{document}
\begin{tabbing}
   Original: $\omega_{m_{ij}}^{r_{ij+1}}$,\,
\= improved: $\nss{\omega}{m_{ij}}{r_{ij+1}}$. \\
   Original: $\overline{a_n^i a_n^j}\,$,
\> improved: $\overline{\nss{a}{n}{i} \nss{a}{n}{j}}\,$.
\end{tabbing}
\end{document}

最后,对原始算法和改进算法进行更广泛的比较。我使用宽度为的框2pt作为下标,使用宽度为的框1pt作为上标。下标的高度各不相同(但深度 0pt),上标的深度各不相同(但高度 0pt)你会看到原始算法存在很大的抖动!

原始与改进

\documentclass{article}
\usepackage{mathtools}
\makeatletter
\newcommand*\nss[3]{...} % insert code from above!!!
\makeatother
\newcommand\oss[3]{#1_{#2}^{#3}}
\newcommand\test[3]{#1{\omega}{\rule{2pt}{#3pt}}{\rule[-#2pt]{1pt}{#2pt}}}
\newcommand\compare[2]{\test#1{#2}{1}\test#1{#2}{2}\test#1{#2}{3}\test#1{#2}{4}}
\newcommand\oneline[1]{\compare\oss{#1}\qquad\compare\nss{#1}}
\newcommand\threelines[1]{%
  \leavevmode\rlap{Original:}\hphantom{$\compare\oss1$}\qquad Improved: \par
  $#1{\oneline2}$ \par
  $#1{\oneline3}$ \par
  $#1{\oneline4}$ \par}
\begin{document}
\textbf{Cramped style} \par
\threelines\cramped    \medskip
\textbf{Text style}    \par
\threelines\textstyle  \medskip
\textbf{Display style} \par
\threelines\displaystyle
\end{document}

答案2

由于 TeX 尝试最大限度地保证表达式不干扰段落行距,因此下标和上标的默认位置更接近 textstyle 中的基线。

您的第一个示例是内联数学的标准设置,但是由于下标导致脚本变大,TeX 必须将它们移得更远。

这是标准布局,但是\displaystyle如果不考虑行距的话,即使在内联数学中也可以强制使用不太拥挤的设置。

答案3

使用该subdepth包;我在一个中写了关于该问题的讨论常见问题解答

相关内容