我们都知道可怕的错误信息LaTeX Error: Too many symbol fonts declared.
有没有最新调查来了解它出现的原因以及可以采取什么措施来解决这个问题?
例如,我知道诸如 之类的宏\DeclareSymbolFont
会吞噬一些有限容量的内部分配计数器,这可以追溯到 Knuth 当时为 TeX 选择的一些神奇数字。
我也知道较新的系统(LuaTeX、XeTeX)具有更高的容量,但不适用于例如\DeclareSymbolFont
。
还可以使用各种技巧来限制标准包(如 bbm)加载的字体系列数量等等。
是否有资料可以全面总结该问题和解决方案/解决方法?
如果有多个,最新的是什么?
语境
我经常需要从字体中提取一个(或少数)符号。一般建议似乎是查找该包的源代码并提取最少的内容。例如,要从\boxright
boisik 字体中获取符号,我们可以使用以下四行:
\DeclareFontFamily{U}{bskma}{\skewchar\font130 }
\DeclareFontShape{U}{bskma}{m}{n}{<->bskma10}{}
\DeclareSymbolFont{bskadd} {U} {bskma}{m}{n}
\DeclareMathSymbol{\boxright} {\mathbin}{bskadd} {"A0}
问题是,如果我需要这样做多次,我就会开始得到一个Latex Error: Too many symbol fonts declared.
。
部分解决方案
@David-carlisle 的解决方案在这种情况下很有吸引力,但我仍然无法让它发挥作用。基本定义如下:
\makeatletter
\newcommand\NewFontImport[6]{
\newcommand#1{\begingroup\mathchoice%
{\hbox{\fontsize{\tf@size}{\tf@size} \usefont{#2}{#3}{#4}{#5}\char#6}}%
{\hbox{\fontsize{\tf@size}{\tf@size} \usefont{#2}{#3}{#4}{#5}\char#6}}%
{\hbox{\fontsize{\sf@size}{\sf@size} \usefont{#2}{#3}{#4}{#5}\char#6}}%
{\hbox{\fontsize{\ssf@size}{\ssf@size}\usefont{#2}{#3}{#4}{#5}\char#6}}%
\endgroup
}}
\makeatother
例如,这对于 boisik 非常有效\boxright
:
\DeclareFontFamily{U}{bskma}{\skewchar\font130 }
\DeclareFontShape{U}{bskma}{m}{n}{<->bskma10}{}
\DeclareFontSubstitution{U}{mathx}{m}{n}
\NewFontImport\boxright{U}{bskma}{m}{n}{"A0}
(其实不然,因为 boisik 目前有一个 bug,其无衬线希腊字母 Sigma 只出现在 scale 上mag:=0+420/600
。我向作者发送了一个 bug 报告。在 metafont 源中注释掉无衬线希腊字母 Sigma 可以解决这个问题。)
未解决的问题
但它似乎并不是全面有效的。
- 它不适用于
mathabx
大型运营商:
\DeclareFontFamily{U}{mathx}{\hyphenchar\font45}
\DeclareFontShape{U}{mathx}{m}{n}{
<5> <6> <7> <8> <9> <10>
<10.95> <12> <14.4> <17.28> <20.74> <24.88>
mathx10
}{}
\DeclareFontSubstitution{U}{mathx}{m}{n}
\NewFontImport\bigboxright{U}{mathx}{m}{n}{"D9}
因为\bigboxright
最终排版在基线以下。我认为我传递了错误的参数给\setfont
,但不确定应该传递什么。
- 它不适用于分隔符:
\DeclareFontFamily{OMX}{MnSymbolE}{}
\DeclareFontFamily{OMX}{MnSymbolA}{}
\DeclareFontShape{OMX}{MnSymbolE}{m}{n}{
<-6> MnSymbolE5
<6-7> MnSymbolE6
<7-8> MnSymbolE7
<8-9> MnSymbolE8
<9-10> MnSymbolE9
<10-12> MnSymbolE10
<12-> MnSymbolE12}{}
\DeclareFontShape{OMX}{MnSymbolE}{b}{n}{
<-6> MnSymbolE-Bold5
<6-7> MnSymbolE-Bold6
<7-8> MnSymbolE-Bold7
<8-9> MnSymbolE-Bold8
<9-10> MnSymbolE-Bold9
<10-12> MnSymbolE-Bold10
<12-> MnSymbolE-Bold12}{}
\NewFontImport{\lsemsym}{OMX}{MnSymbolE}{m}{n}{'102}
\NewFontImport{\rsemsym}{OMX}{MnSymbolE}{m}{n}{'107}
我可以单独使用\lsemsym
和,但我不能使用,因为它们是在文本框内排版的,而不是可变大小的分隔符。(非常感谢@David Carlisle的耐心帮助我走到这一步!)\rsemsym
\open\lsemsym \sum_{i=1}^n a_n \close\rsemsym
答案1
限制仅限于单个数学表达式中的 16 种字体,很少需要超过这个数字。在 luatex 或 xetex 中,如果您确实需要,您可以使用\Umathchardef
而不是\mathchardef
访问超过 16 个系列,或者即使在经典 TeX 中,您也可以使用与避免问题相同的方式避免此\boldsymbol
问题,切换到 hbox,然后仅为单个字符设置不同的字体方案,然后返回外部公式。
这是用 pdflatex 设置的单个数学表达式,有 24 个不同的 Z
\documentclass{article}
\usepackage{amsmath,amsfonts}
\DeclareFontEncoding{LS1}{}{}
\DeclareFontEncoding{LS2}{}{\noaccents@}
\DeclareFontSubstitution{LS1}{stix2}{m}{n}
\DeclareFontSubstitution{LS2}{stix2}{m}{n}
\begin{document}
$
Z % 0
\mathrm{Z} % 1
\mathit{Z} % 2
\mathsf{Z} % 3
\mathbf{Z} % 4
\mathfrak{Z} % 5
\mathcal{Z} % 6
\mathbb{Z} % 7
\mathtt{Z} % 8
\hbox{\usefont{OML}{txmi}{m}{it}Z} % 9
\hbox{\usefont{OML}{txmi}{bx}{it} Z} % 10
\hbox{\usefont{OT1}{txr}{m}{n} Z} % 11
\hbox{\usefont{OT1}{txr}{bx}{n} Z} % 12
\hbox{\usefont{LS1}{stix2}{m}{n} Z} % 13
\hbox{\usefont{LS1}{stix2}{m}{it} Z} % 14
\hbox{\usefont{LS1}{stix2}{b}{n} Z} % 15
\hbox{\usefont{LS2}{stix2}{b}{it} Z} % 16
\hbox{\usefont{LS2}{stix2}{m}{n} Z} % 17
\hbox{\usefont{LS2}{stix2}{m}{it} Z} % 18
\hbox{\usefont{LS2}{stix2}{b}{n} Z} % 19
\hbox{\usefont{LS2}{stix2}{b}{it} Z} % 20
\hbox{\usefont{LS1}{stix2frak}{m}{n} Z} % 21
\hbox{\usefont{LS1}{stix2frak}{b}{n} Z} % 22
\hbox{\usefont{LS2}{stix2cal}{m}{n} Z} % 23
$
\end{document}
答案2
我可以解释“未解决的问题 #1“。
该\bigboxright
符号声明mathabx
为
\DeclareMathSymbol{\bigboxright} {1}{mathx}{"D9}
请注意,它有类别1
,因此操作员。TeX 具有显示运算符的特殊功能(请参阅make_op
Knuth 的tex.web
文件)。特别是,它可以在显示模式下切换到符号的较大版本,并在必要时垂直移动符号。为了模拟此行为,我建议对代码进行以下修改:
\newcommand\makeopNewFont[6]{
\setbox0\hbox{\fontsize{#1}{#1}\usefont{#2}{#3}{#4}{#5}\char#6}%
\lower\dimexpr .5\ht0-.5\dp0-\fontdimen22\textfont2\copy0
}
\newcommand\NewFontImportOp[7]{
\newcommand#1{%
\mathop{\mathchoice%
{\makeopNewFont{\tf@size}{#2}{#3}{#4}{#5}{#7}}%
{\makeopNewFont{\tf@size}{#2}{#3}{#4}{#5}{#6}}%
{\makeopNewFont{\sf@size}{#2}{#3}{#4}{#5}{#6}}%
{\makeopNewFont{\ssf@size}{#2}{#3}{#4}{#5}{#6}}%
}%
}%
}
%....
\NewFontImportOp\bigboxright{U}{mathx}{m}{n}{"D9}{"F9}
不幸的是,我不知道如何简单地确定与配对(较大)符号("F9
在本例中)相对应的代码,因为此配对存储在字体内部(所谓的charlist
条目)。为了找到答案"F9
,我\tracingoutput
使用原始命令分析了测试页面的生成日志\bigboxright
。另一种方法是使用该包查看所有字形fonttable
并在那里找到匹配项。
最有可能的是,它也可以模拟大多数其他数学类别(只需在前面加上\hbox
,\mathbin
等\mathrel
即可获得正确的字距调整):
\newcommand\NewFontImport[7]{%
\newcommand#1{%
#5{\mathchoice%
{\hbox{\fontsize{\tf@size}{\tf@size}\usefont{#2}{#6}{#3}{#4}\char#7}}%
{\hbox{\fontsize{\tf@size}{\tf@size}\usefont{#2}{#6}{#3}{#4}\char#7}}%
{\hbox{\fontsize{\sf@size}{\sf@size}\usefont{#2}{#6}{#3}{#4}\char#7}}%
{\hbox{\fontsize{\ssf@size}{\ssf@size}\usefont{#2}{#6}{#3}{#4}\char#7}}%
}%
}%
}
% Note: I've changed the order of arguments to match \DeclareMathSymbol
\NewFontImport\times{U}{m}{n}{\mathbin}{matha}{"02}
但是分隔符的模拟太复杂了(因为左/右分隔符的构造是任意大小的)。所以我放弃了。