如何检查文档中加载的数学字体? 就像\fontname\font
用于检查加载的字体一样,打印当前数学字体的命令是什么?
答案1
数学模式下的字体选择与文本模式下的字体选择不同。在文本模式下,您有一个“当前字体”,但在数学模式下,您不一定有。在数学模式下,TeX 使用最多 16 种字体系列中的一种,其中每个系列都有三种变体\textfont
,\scriptfont
并且\scriptscriptfont
,用于字符在数学公式中可能出现的各种位置。
当 TeX 将字符设置为数学模式时,它首先会检查与该字符关联的数学代码。例如,您可以检查字母的数学代码a
。\showthe\mathcode`a
然后 TeX 将打印
*\showthe\mathcode`a
> 29025.
十六进制形式为7161
。第一位数字代表与数学字符关联的数学类,第二位数字代表字体系列,第三位和第四位数字代表字符在字体表中的位置。因此,在这种情况下,字母a
具有默认字体系列 1。
但是,这比仅仅使用这个字体系列要复杂得多,因为该字符还有类别 7。类别 7 意味着 TeX 首先检查字体系列寄存器的值是否\fam
在 0-15 范围内。如果是,TeX 会假设类别为 0(普通的数学字符/符号),并使用字体系列\fam
来排版此字符。如果\fam
不在上述范围内(启动数学模式时默认情况下如此),TeX 会使用与字母相关的字体系列,在本例中为 1。
现在我们知道要查看哪个字体系列,我们终于可以在数学模式下检查三个系列变体的字体名称了。如果我们输入
$\fontname\textfont1, \fontname\scriptfont1, \fontname\scriptscriptfont1$
在一个简单的 LaTeX 文档中,输出将如下所示
cmmi10, cmmi7, cmmi5
它们是标准的计算机现代斜体数学字体变体。
字体系列仅在数学模式下设置,因此如果您需要文本模式下的值,请使用类似
$\xdef\famone{\fontname\textfont1}$
\ttfamily\famone
对于 script 和 scriptscript 变体也类似。
编辑:这是一个小宏\printmathfont
,它打印给定数学字体变体的字体名称(#1
)和(可能是隐式的)数学字符(#2
):
\documentclass{article}
\def\printmathfont#1#2{%
\ifcat\relax#2\relax
\count0=#2%
\else
\count0=\mathcode`#2%
\fi
\divide\count0 256%
\count1=\numexpr\count0/16\relax % class
\count0=\numexpr\count0 - 16*(\count0/16)\relax % family
\def\tempinfo##1{\xdef\temp{\fontname#1##1}}%
$%
\ifnum\count1=7\relax
\ifnum\fam>0\relax
\ifnum\fam<16\relax
\tempinfo{\fam}%
\else
\tempinfo{\count0}%
\fi
\else
\tempinfo{\count0}%
\fi
\else
\tempinfo{\count0}%
\fi
$%
\string#1 \string#2 ($#2$): \temp
}
\begin{document}
\ttfamily
\printmathfont\textfont a \par
\printmathfont\scriptfont a \par
\printmathfont\textfont\alpha \par
\printmathfont\textfont\cap \par
\printmathfont\textfont= \par
\string\bf\everymath{\bf}\printmathfont\textfont a \par
\string\sf\everymath{\sf}\printmathfont\textfont a \par
\end{document}
答案2
没有“当前数学字体”。基本上,数学公式中的每个符号都附带一种字体选择。
每个字符都有一个“数学码”,例如的数学码b
是0x7162
“排版时,作为普通符号,字符0x62
位于当前值指向的字体位置,\mathgroup
或者,如果\mathgroup
是-1,则使用1定义的字体\mathgroup
”。的数学码;
是0x603B
“排版时,作为标点符号,字符位于00x3B
指向的字体位置\mathgroup
”。
TeX 维护最多 16 个数学组(普通 TeX 术语中的系列,但这里我指的是 LaTeX),但在 XeTeX 和 LuaTeX 中限制提高到 256。
每个数学组最多可以分配三种字体;如果系列编号为n,我们可以这样引用它们:“\textfont
n”,“\scriptfont
n“ 和 ”\scriptscriptfont
n”;顾名思义,下标/上标级别为零、一级和以上的符号分别使用不同的字体。因此,公式$b^{b}$
将使用两种不同的字体,即\textfont1
和\scriptfont1
,分别表示底数和指数。
另一方面,$\mathrm{b}^{b}
将再次使用两种不同的字体,但现在它们将分别\textfont0
用于底数和\scriptfont1
指数,因为\mathrm{b}
这是一条基本上
\begingroup\mathgroup=0 b\endgroup
因此暂时设置\mathgroup
为 0;公式启动时参数的值为 −1。一般来说,出于显而易见的原因,分配给数学组的三个变体的字体仅在大小上有所不同。
还有其他一些微妙之处。将字体分配给数学组有两种基本方法:
\DeclareSymbolFont{<name>}{<encoding>}{<family>}{<series>}{<shape>}
\DeclareMathAlphabet{<control sequence>}{<encoding>}{<family>}{<series>}{<shape>}
声明
\SetSymbolFont{<name>}{<version>}{<encoding>}{<family>}{<series>}{<shape>}
\SetMathAlphabet{<control sequence>}{<version>}{<encoding>}{<family>}{<series>}{<shape>}
是数学版本的配套产品;我不会提供有关数学版本的任何详细信息,我将坚持使用“正常”数学版本(但不难理解发生了什么)。
数学组 0、1、2 和 3 是保留的,因为它们被 TeX 用于设置重要的数学参数;组 0 应引用“数学罗马”字体,组 1 应引用“数学字母”字体,组 2 应引用“数学符号”字体,组 3 应引用“数学扩展”字体。事实上,fontmath.ltx
我们发现
\DeclareSymbolFont{operators} {OT1}{cmr} {m}{n}
\DeclareSymbolFont{letters} {OML}{cmm} {m}{it}
\DeclareSymbolFont{symbols} {OMS}{cmsy}{m}{n}
\DeclareSymbolFont{largesymbols}{OMX}{cmex}{m}{n}
作为前四个声明。每个数学字体包都应遵守此约定(但分配这四种字体属性是自由的,只要分配给数学组 1、2 和 3 的字体是为相应角色设计的,因为它们需要适当的参数)。
随后的每个\DeclareSymbolFont
声明都会分配另一个数学组。相反,对应的数学组\DeclareMathAlphabet
仅在需要时才分配。
例如,文档
\documentclass{article}
\begin{document}
$\mathbf{a}$ \fontname\textfont4
\end{document}
将打印
Acmbx10
但是,更改$\mathbf{a}$
为$a$
将打印
A空字体
对应的数学组\mathbf
是不可预测的,因为它取决于分配的符号字体(例如,amssymb
将分配超过标准的四个)以及数学字母的使用顺序。继续我们的例子,
\documentclass{article}
\begin{document}
$\mathbf{a\xdef\whatfont{\fontname\textfont\mathgroup\space(math group \the\mathgroup)}}$
\whatfont
\end{document}
将打印
Acmbx10(数学组 4)
但如果我们还加载amssymb
,我们会得到
Acmbx10(数学组 6)
如果我们
\documentclass{article}
\usepackage{kpfonts}
\begin{document}
$\mathbf{a\xdef\whatfont{\fontname\textfont\mathgroup\space(math group \the\mathgroup)}}$
\whatfont
\end{document}
我们得到
Ajkpbn7t(数学组 9)
正是因为kpfonts
配备较多的符号字体。
另一个重要的微妙之处是,在排版数学公式之前,不会为任何数学组声明数学字体,甚至连四个基本数学组也没有。这样做有一个很好的理由,如下例所示:
\documentclass{article}
\begin{document}
\footnotesize $a$ \fontname\textfont1
\end{document}
这将打印
Acmmi8
进入数学模式会触发执行,\check@mathfonts
负责检查已分配的数学组列表并提供正确的字体分配。示例
\documentclass{article}
\begin{document}
$a$ \footnotesize \fontname\textfont1
\end{document}
将打印
Acmmi10
因为还没有在 中排版任何数学公式\footnotesize
。在文档开始时,还没有分配字体,这解释了上面的“nullfont”。
最后请注意,在如下公式中
$a\oplus\mathrm{a}\bigg|$
使用了四种字体;依次为\textfont1
、、\textfont2
和\textfont0
。\textfont3
答案3
当使用 Unicode 数学字体时,可以(并且通常)为数学公式中使用的所有字符使用单一数学字体。这与旧概念(使用 7 位字体)不同,旧概念将所有数学字符集划分为按数学系列编号注册的更多字体。此旧概念已在此处的另一个答案中进行了解释。
例如,OpTeX 将数学系列编号 1 保留为主 Unicode 数学字体。因此,您可以通过以下方式获取其名称
\fontfam[lm]
\fontname\textfont1
\bye
其他数学系列数字可用于附加字体。当主 Unicode 数学字体未包含数学公式所需的所有字符时,它可用。
答案4
该答案涵盖了用户使用 LaTeX 的情况。
说“目前没有数学字体”是半准确的,因为
- 在 TeX 的低级别中,
\textfont
这些等没有预先设置,但是 - (La)TeX 的用户通常不会太关心低级部分。
实际上,LaTeX 维护着一个内部表,
- 当前数学版本
\math@version
(normal
或bold
)拍摄于此处, - 对于每个数学版本(例如
bold
,normal
或者如果您使用unicode-math并加载适当的字体,您可能会获得像times
或xitsmath
等数学版本),- 从数学字母表(例如)到文本字体名称的映射
\mathbf
排除大小 - 即⟨encoding、family、series、shape⟩例如\mathbf → (OT1, cmr, bx, n⟩
- 从每个 ⟨sym-font⟩ 到文本字体名称的映射如上所述。例如
symbols → ⟨OMS, cmsy, m, n⟩
- 从数学字母表(例如)到文本字体名称的映射
- 此外,尺寸信息被保存(设置者
\DeclareMathSizes
)
为了访问这些信息,您可以访问 LaTeX 的一些内部宏——通过阅读文档可以找到其名称:
- 映射“(数学版本,数学字母表)→字体”被
\DeclareMathAlphabet
(设置所有数学版本的数学字母表字体)、\SetMathAlphabet
(设置特定数学版本的数学字母表字体)、、\DeclareSymbolFont
修改\SetSymbolFont
。 - 定义符号属于哪个 ⟨sym-font⟩ 的命令是
\DeclareMathSymbol
(还有等等\DeclareMathDelimiter
)
当然,访问这些以编程方式非常脆弱,但是 LaTeX 内核无论如何已经修复了很长时间。
例如
$ latexdef math@version
\math@version:
macro:->normal
$ latexdef alpha # check which symbol font "\alpha" belong to
\alpha:
\mathchar"10B
# ⟹ actually it's not unambiguously defined, we only know it belong to some symbol font
# which correspond to mathgroup 1
$ latexdef symletters # this shows ⟨sym-font⟩ = "letters" → mathgroup 1
\symletters:
\char"1
$ latexdef mathbf # check the math alphabet "mathbf" (→ OT1/cmr/bx/n)
\mathbf:
macro:->\protect \mathbf
\mathbf :
macro:->\select@group \mathbf \M@OT1 \OT1/cmr/bx/n
$ latexdef "mv@bold" # check the math version "bold" (self explanatory)
\mv@bold:
macro:->\getanddefine@fonts \symoperators \OT1/cmr/bx/n \getanddefine@fonts \symletters \OML/cmm/b/i
t \getanddefine@fonts \symsymbols \OMS/cmsy/b/n \getanddefine@fonts \symlargesymbols \OMX/cmex/m/n \
install@mathalphabet \mathbf {\select@group \mathbf \M@OT1 \OT1/cmr/bx/n }\install@mathalphabet \m
athsf {\select@group \mathsf \M@OT1 \OT1/cmss/bx/n }\install@mathalphabet \mathit {\select@group
\mathit \M@OT1 \OT1/cmr/bx/it }\install@mathalphabet \mathtt {\select@group \mathtt \M@OT1 \OT1/c
mtt/m/n }
$ latexdef group@list # list of all math groups defined so far (available in preamble only)
\group@list:
macro:->\@latex@error {Can be used only in preamble}\@eha
(in preamble)
\group@list:
macro:->\group@elt \symoperators \OT1/cmr/m/n \group@elt \symletters \OML/cmm/m/it \group@elt \symsy
mbols \OMS/cmsy/m/n \group@elt \symlargesymbols \OMX/cmex/m/n
# so "letters" → OML/cmm/m/it etc.
可能还想检查的是您是否在里面\mathbf
还是外面等等。
虽然每个符号字体都固定为一个 mathgroup 编号(如上所示),但 mathalphabet → mathgroup 编号的分配是按需的:
(你可以自己测试一下:如果你
$\mathbf{\the\fam} \mathit{\the\fam}$
在文档一开始就这么做,你会得到 mathbf → 4 和 mathit → 5,但如果你这样做
$\mathit{\the\fam} \mathbf{\the\fam}$
先这么做,那么 mathit → 4 和 mathbf → 5。这可能取决于使用的 LaTeX 版本。——LaTeX 可以买得起
这样做是因为您可以\textfont4
在公式的中间设置,然后使用公式末尾有效的设置来呈现整个数学公式)
因为映射\mathgroup
不是固定的,所以我们还需要知道内部查找表的定义位置。
为此,阅读源代码\select@group
很有用。不过文档可能有点误导(例如,它说命令需要 4 个参数,但实际上只需要 3 个)
因此,第一次使用命令后,映射就在命令定义本身中。
%! TEX program = pdflatex
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
\expandafter\meaning\csname mathbf \endcsname
\makeatletter\the\c@mv@normal\makeatother
$\mathbf{a}$
\makeatletter\the\c@mv@normal\makeatother
\expandafter\meaning\csname mathbf \endcsname
\end{document}
你看:
意思是:
- 最初,
\mathbf
未分配给任何数学组。首次调用时\select@group
将用于选择一个数学组。 - 最初使用 4 个数学组。
- 在数学模式下排版粗体后
a
,使用了5个数学组。 - 现在
\mathbf
被分配给 mathgroup 4。
不幸的是,这个答案还没有涵盖使用包的情况——它有也可用作unicode-math
的概念。\setmathfont
\mathversion
要获取一些有用的读物,请参阅texdoc fntguide
以下链接的文档/书籍: