我创建了两个等式:
$x \notin \mathbb{N}$
; 和$x \in \mathbb{N}$
。
事实证明,两者具有相同的深度值:
深度 = 0.39098pt
高度 = 7.5pt深度 = 0.39098pt
高度 = 6.88889pt
显然,第一个方程的深度应该比第二个方程更大,因为符号\notin
更深。
怎么会这样?
这是用于生成两者的代码:
\documentclass[10pt]{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage[usenames]{color}
\pagestyle{empty}
\newsavebox{\eqbox}
\newlength{\width}
\newlength{\height}
\newlength{\depth}
\begin{lrbox}{\eqbox}
{$ x \notin \mathbb{N} $}
\end{lrbox}
\settowidth {\width} {\usebox{\eqbox}}
\settoheight{\height} {\usebox{\eqbox}}
\settodepth {\depth} {\usebox{\eqbox}}
\newwrite\file
\immediate\openout\file=\jobname.bsl
\immediate\write\file{Depth = \the\depth}
\immediate\write\file{Height = \the\height}
\addtolength{\height} {\depth}
\immediate\write\file{TotalHeight = \the\height}
\immediate\write\file{Width = \the\width}
\closeout\file
\begin{document}
\usebox{\eqbox}
\end{document}
谁能告诉我这是为什么?
答案1
并非总是如此。最好的观察方式是从边界框的角度来看待这个问题:
\documentclass[10pt]{article}
\usepackage{amssymb,xcolor}% http://ctan.org/pkg/{amslatex,xcolor}
\newcommand{\showbb}[1]{{\color{red!50}\leavevmode\rlap{\fbox{\phantom{#1}}}}#1}
\begin{document}
\setlength{\fboxsep}{-\fboxrule}
\showbb{$ x \notin \mathbb{N} $} \quad
\showbb{$ x \in \mathbb{N} $}
\end{document}
如上所述,很明显两者具有相同的深度,但高度不同。为什么?这是由字体设计师在每个符号的字体规范中决定的。在某些情况下,字符/符号的边界框取决于其后的内容(例如,V
后跟A
)。在这种情况下(或最有可能),符号的深度被设置为不会影响基线跳过。
检查这一点的一种方法是,如果要\notin
在两行连续的线条上有两个符号。如果符号的深度更大,线条分离会使输出看起来很尴尬……仅在一个位置。为了避免这种情况,并且知道符号\not
的“ ”部分是一条(细)规则,如果它向下延伸得比预期的要远,它不应该影响读者。
答案2
这是 实施的副作用\notin
。来自fontmath.ltx
(重新格式化):
\DeclareRobustCommand\notin{%
\mathrel{%
\m@th
\mathpalette\c@ncel\in
}%
}
\def\c@ncel#1#2{%
% #1: math style
% #2: the symbol (here: \in)
\m@th
\ooalign{%
$\hfil#1\mkern1mu/\hfil$%
\crcr
$#1#2$%
}%
}
简化版\notin
会制作一个只有一列的特殊表格。第一行包含一个水平居中、向右/
移动的1mu
。第二行包含符号 。但是,您看不到两条线。的诀窍\ooalign
是将 设置\baselineskip
为零。因此,两行共享相同的基线。整体放入一个垂直框(\vtop
)。整个框的高度来自第一个框、第一条线、斜线的高度。现在第二个框、第二条线紧随其后,这意味着第一条线的深度不再计算。第二条线的高度也被忽略,但第二条线中符号的深度成为整个框的深度。
以下示例比较了不同的变体:
- 前两个框包含单个字形,表明字符边界框是正确的。
- 第三个框
\notin
显示了具有如上所述的原始定义的组合符号。 - 第四个框
\NotIn
使用重写的\c@ncel
宏(\NewC@ncel
),同时考虑了高度和深度。 - 为了进行比较,最后一个框使用不同的符号
\not
和方法来表示否定。
\documentclass{article}
\usepackage{xcolor}
\makeatletter
\newcommand*{\NotIn}{%
\mathrel{%
\mathpalette\NewC@ncel\in
}%
}
\newcommand*{\NewC@ncel}[2]{%
% #1: math style
% #2: symbol
\sbox0{$#1#2\m@th$}%
\sbox2{$#1\mkern1mu/\m@th$}%
\ifdim\wd2>\wd0 %
\wd0=\wd2 %
\else
\setbox2=\hbox to \wd0{\hfil\unhcopy2\hfil}%
\fi
\rlap{\copy2}%
\copy0 %
}
\makeatother
\newcommand*{\test}[1]{%
\begingroup
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{.2pt}%
\sbox0{$#1$}%
\typeout{* [\detokenize{#1}: height=\the\ht0, depth=\the\dp0}%
\fcolorbox{blue}{white}{\copy0 } \texttt{\detokenize{#1}}%
\par
\endgroup
}
\begin{document}
\test{\in}
\test{/}
\test{\notin}
\test{\NotIn}
\test{\not\in}
\end{document}
如果要使用(而不是像示例中那样使用\notin
新的宏),那么可以重新定义:\NotIn
\c@ncel
\makeatletter
\newcommand*{\NewC@cncel}{...}% see above
\let\c@ncel\NewC@ncel
\makeatother
修复了以下建议\ooalign
以下测试文件可用于纯 TeX 和 LaTeX,它重新定义了\ooalign
。首先将单元格内容放入一个框中以测量其高度和深度,然后将整个框设置为最大高度和深度。
\ifx\documentclass\undefined
\nopagenumbers
\catcode`\@=11 %
\else
\documentclass{article}
\pagestyle{empty}
\begin{document}
\makeatletter
\fi
\let\plain@ooalign\ooalign
%%% begin: \ooalign %%%
\newdimen\ooalign@height
\newdimen\ooalign@depth
% The implementation merges the original `\ooalign'
% with the modified contents of `\oalign'.
% The heights and depths are measured and the overall box
% is adjusted to get the maximum height and depth.
\def\ooalign#1{%
\leavevmode
\begingroup
\setbox\z@\vtop{%
\baselineskip\z@skip
\lineskip\z@ % might not be needed
\lineskiplimit=-\maxdimen
\global\ooalign@height\z@
\global\ooalign@depth\z@
\ialign{%
% the cell contents is measured and
% the maximum values for height and depth are remembered
\setbox\z@\hbox{##}%
\ifdim\ht\z@>\ooalign@height
\global\ooalign@height\ht\z@
\fi
\ifdim\dp\z@>\ooalign@depth
\global\ooalign@depth\dp\z@
\fi
\unhcopy\z@
\crcr
#1%
\crcr
}%
}%
\vtop{%
% update the height if needed
\ifdim\ooalign@height>\ht\z@
\hrule width\z@ height \ooalign@height depth\z@
\kern-\ht\z@
\fi
\unvcopy\z@
% update the depth if needed
\ifdim\ooalign@depth>\dp\z@
\kern-\dp\z@
\kern\ooalign@depth
\fi
}%
\endgroup
}
%%% end: \ooalign %%%
% for testing
\ifx\fbox\undefined
\newdimen\fboxrule
\newdimen\fboxsep
\newbox\@tempboxa
\newdimen\@tempdima
\long\def\fbox#1{%
\leavevmode
\setbox\@tempboxa\hbox{%
\begingroup
\kern\fboxsep{#1}\kern\fboxsep
\endgroup}%
\@frameb@x\relax
}%
\def\@frameb@x#1{%
\@tempdima\fboxrule
\advance\@tempdima\fboxsep
\advance\@tempdima\dp\@tempboxa
\hbox{%
\lower\@tempdima\hbox{%
\vbox{%
\hrule height\fboxrule
\hbox{%
\vrule width\fboxrule
#1%
\vbox{%
\vskip\fboxsep
\box\@tempboxa
\vskip\fboxsep}%
#1%
\vrule width\fboxrule}%
\hrule height\fboxrule
}%
}%
}%
}%
\fi
\fboxsep=0pt
\fboxrule=.1pt
\def\test{a\fbox{$\notin$}b\fbox{\copyright}c}
% original \ooalign
\begingroup
\let\ooalign\plain@ooalign
\test
\endgroup
% new \ooalign
\test
\ifx\enddocument\undefined
\def\next{\end}%
\else
\def\next{\end{document}}%
\fi
\next
答案3
\notin
定义为纯 tex,并带入乳胶中。它不需要乳胶或amsfonts
证明缺乏深度。
相关元素是在(via )\ooalign
的定义中的使用。 定义如下(texbook,第 356 页):\notin
\c@ancel
\ooalign
\def\ooalign{\lineskiplimit-\maxdimen \oalign} % chars over each other
有效\lineskiplimit
地抵消了组件的任何高度或深度,正如这个小纯 tex 脚本所示:
\setbox0=\hbox{$/$}
\setbox1=\hbox{\ooalign{.\crcr/\crcr}
\showthe\dp0
\showthe\dp1
\bye
输出(到屏幕)是这些值:
> 2.5pt.
l.7 \showthe\dp0
?
> 0.0pt.
l.8 \showthe\dp1
\showthe\ht1
还将报告的值0.0pt
。
这是否给任何人造成了问题仍是一个悬而未决的问题;然而,30 多年来它并没有给任何人带来足够的困扰以致于将其报告为错误。
答案4
\dpnotin
具有斜线深度的更简单的实现:
\documentclass{article}
\makeatletter
\DeclareRobustCommand{\dpnotin}{%
\mathrel{\m@th\mathpalette\c@ncel{{\in}\vphantom{/}}}%
}
\makeatother
\begin{document}
\fboxsep=0pt
\fbox{$x\notin N$}\,\fbox{$x\dpnotin N$}
\fbox{$x\notin N$}\,\fbox{$x\notin N$}
\end{document}
我们传递\c@ncel
参数{\in}\vphantom{/}
,因此幻像将以正确的方式设置构造的深度。示例中的第二行只是检查水平尺寸是否不变;第三行和第四行用于检查下标中的符号。