\smash 起什么作用?它的文档记录在哪里?

\smash 起什么作用?它的文档记录在哪里?

我看到论坛里有几个用户在谈论\smash。它显然是在基础 TeX 中定义的。

做什么\smash

为了将来参考,是否有我可以找到的在线文档?

答案1

顾名思义,\smash获取其内容并将其打印出来,就好像它的高度和深度为零一样。

LaTeX 中的定义沿用了纯 TeX 中的定义,但略有不同;为了方便参考,我将使用 LaTeX 中的定义。以下内容指的是 LaTeX 2018-12-01。

% latex.ltx, line 4494:
\def\smash{%
  \relax % \relax, in case this comes first in \halign
  \ifmmode
    \expandafter\mathpalette\expandafter\mathsm@sh
  \else
    \expandafter\makesm@sh
  \fi}

该宏区分它是否在数学模式下调用。请注意,为了提高效率,它不会在开始时读取其参数。我假设调用是\smash{abq}。在数学模式下,我们得到

\mathpalette\mathsm@sh{abq}

现在我们需要看看\mathsm@sh

% latex.ltx, line 4503:
\def\mathsm@sh#1#2{%
  \setbox\z@\hbox{$\m@th#1{#2}$}\finsm@sh}

根据工作\mathpalette,我们得到相当于

\setbox\z@\hbox{$\m@th<current style>{abq}$}\fin@smash

如果呼叫处于文本模式,则我们有\makesm@sh{abq}。现在

% latex.ltx, line 4501:
\def\makesm@sh#1{%
  \setbox\z@\hbox{\color@begingroup#1\color@endgroup}\finsm@sh}

所以我们得到

\setbox\z@\hbox{\color@begingroup abq\color@endgroup}\finsm@sh

在这两种情况下,TeX 都设置了框 0 的内容;现在\finsm@sh开始执行它的工作

% latex.ltx, line 4505:
\def\finsm@sh{\ht\z@\z@ \dp\z@\z@ \leavevmode@ifvmode\box\z@}

这会将框 0 的高度和深度设置为 0pt,并在启动水平模式后对框进行排版。

加载时amsmath定义基本相同,不同之处在于允许使用可选参数,可以是tbt最后一个操作变为仅

\ht\z@\z@ \box\z@

因此深度得以保留;相反,使用bLaTeX 只会

\dp\z@\z@ \box\z@

并且高度保持不变。这是通过重新定义实现的(参考amsmath.sty2018-12-01 版本)

% amsmath.sty, line 903:
\ifx\leavevmode@ifvmode\@undefined
\renewcommand{\smash}[1][tb]{%
  \def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}%
  \edef\finsm@sh{\csname mb@#1\endcsname\z@\z@\box\z@}%
  \ifmmode \@xp\mathpalette\@xp\mathsm@sh
  \else \@xp\makesm@sh
  \fi
}
\else
\renewcommand{\smash}[1][tb]{%
  \def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}%
  \edef\finsm@sh{\csname mb@#1\endcsname\z@\z@ \leavevmode@ifvmode\box\z@}%
  \ifmmode \@xp\mathpalette\@xp\mathsm@sh
  \else \@xp\makesm@sh
  \fi
}
\fi

您会看到,\finsm@sh每次都会重新定义为由必要的位组成。

\smash中的条件定义amsmath.sty是由于\leavevmode@ifvmode从 2018-12-01 版开始,LaTeX 添加了 ,用于在垂直模式下启动水平模式。在之前的 LaTeX 版本中,这种情况不会发生,反映了与普通 TeX 相同的行为,其中 的定义与 LaTeX 内核中的相同,但没有\leavevmode@ifvmode,它在 LaTeX 内核中定义为

% latex.ltx, line 1633:
\protected\def\leavevmode@ifvmode{\ifvmode\expandafter\indent\fi}

答案2

\smash是一个定义为的宏

\relax \ifmmode \def \next {\mathpalette \mathsm@sh }\else \let \next \makesm@sh \fi \next 

定义\mathsm@sh为:

\setbox \z@ \hbox {$\m@th #1{#2}$}\finsm@sh 

定义finsm@sh

ht \z@ \z@ \dp \z@ \z@ \box \z@ 

这个命令的简单版本让它的功能更加明显,它来自TeX 按主题分类

\def\smash#1{{\setbox0=\hbox{#1}\dp0=0pt \ht0=0pt \box0\relax}}

它基本上是取一些内容并将其放入高度和深度均为 0 的盒子中。

它记录在 TeXbook 中,也在 TeX by Topic 中,其中包含了 TeX Live 文档的一部分(texdoc texbytopic应该会提到它。)

LaTeX 内核中的实际宏可以在文档中找到source2e.pdf(也可以通过 获得texdoc)。

一些软件包,例如amsmath重新定义它。另请参阅

答案3

这个答案试图满足@BenCrowell对 smash 如何影响输出的示例的渴望。正如评论所指出的那样,受影响的是高度和深度,而不是宽度\smash。因此,这会影响分配给文本的垂直空间,这可能会影响前行和后行的垂直位置、上标和下标的位置(与粉碎的材料相关),以及与\smash编辑文本一起堆叠的材料。

\documentclass{article}
\usepackage{stackengine}
\begin{document}

\noindent Affects placement of pre-\\
$\displaystyle\frac{Q}{Z}$ (vertical space widened to account)\\
and suc-ceeding material\\
$\displaystyle\smash{\frac{Q}{Z}}$ (vertical space not widened)\\
See what I mean?

\bigskip
Now let's look at super/subscript placement.
\[\left(\frac{a}{b}\right)^a_b\]  
Compare if fraction is smashed:
\[\smash{\left(\frac{a}{b}\right)}^a_b\]  

Now for certain types of stacks:
\Shortstack{a b fg d e} versus \Shortstack{a b \smash{fg} d e}.

\end{document}

在此处输入图片描述

答案4

无论如何,从amsmath 软件包用户指南

命令 \smash 用于排版有效高度和深度为零的子公式,这有时有助于调整子公式相对于相邻符号的位置。

使用 amsmath 包 \smash 具有可选参数 [t] 和 [b],因为有时能够“粉碎”某些物体的顶部或底部,同时保留自然的深度或高度是有利的。

例如,当相邻部首符号因其内容的高度和深度不同而大小或位置不均匀时,可以使用 \smash 使它们更加一致。

他们提供了一个使用\smash[b]平方根符号的例子:

如果没有此选项:

在此处输入图片描述

用它:

\sqrt{x} + \sqrt{\smash[b]{y}} + \sqrt{z}

在此处输入图片描述

第二个被开方数已减小了其边界框的垂直限制。

相关内容