检查数学字体

检查数学字体

如何检查文档中加载的数学字体? 就像\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

没有“当前数学字体”。基本上,数学公式中的每个符号都附带一种字体选择。

每个字符都有一个“数学码”,例如的数学码b0x7162“排版时,作为普通符号,字符0x62位于当前值指向的字体位置,\mathgroup或者,如果\mathgroup是-1,则使用1定义的字体\mathgroup”。的数学码;0x603B“排版时,作为标点符号,字符位于00x3B指向的字体位置\mathgroup”。

TeX 维护最多 16 个数学组(普通 TeX 术语中的系列,但这里我指的是 LaTeX),但在 XeTeX 和 LuaTeX 中限制提高到 256。

每个数学组最多可以分配三种字体;如果系列编号为n,我们可以这样引用它们:“\textfontn”,“\scriptfontn“ 和 ”\scriptscriptfontn”;顾名思义,下标/上标级别为零、一级和以上的符号分别使用不同的字体。因此,公式$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@versionnormalbold拍摄于此处
  • 对于每个数学版本(例如boldnormal或者如果您使用unicode-math并加载适当的字体,您可能会获得像timesxitsmath等数学版本),
    • 从数学字母表(例如)到文本字体名称的映射\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 编号的分配是按需的:

fntguide 文档

(你可以自己测试一下:如果你 $\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 个)

select@group 文档

因此,第一次使用命令后,映射就在命令定义本身中。

%! 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以下链接的文档/书籍:

fntguide 文档

相关内容