5

We all know the dreaded error message LaTeX Error: Too many symbol fonts declared.

Is there an up to date survey of why it's there, and what can be done about it?

For example, I know that macros such as \DeclareSymbolFont gobble up some limited capacity of internally allocated counter, dating back to some magic numbers Knuth chose at the time for TeX.

I also know that newer systems (LuaTeX, XeTeX) have a higher capacity, but not for, e.g., \DeclareSymbolFont.

There are also all kinds of tricks one can do to limit the number of font families a standard package (like bbm) loads, and so on.

Is there a source that summarises the problem and solutions/workarounds comprehensively?

If there is more than one, what is the most recent/up-to-date?

Context

I often need to extract only one (or a small number) of symbols from a font. The general advice seems to be to look up that package's sourcecode and extract the bare minimum. For example, to get the \boxright symbols from the boisik font, we could use these four lines:

\DeclareFontFamily{U}{bskma}{\skewchar\font130 }
\DeclareFontShape{U}{bskma}{m}{n}{<->bskma10}{}
\DeclareSymbolFont{bskadd} {U} {bskma}{m}{n}
\DeclareMathSymbol{\boxright} {\mathbin}{bskadd} {"A0} 

The problem is that if I need to this more than a handful of times, I will start getting a Latex Error: Too many symbol fonts declared..

Partial solution

@David-carlisle 's solution below is attractive in this context, but I'm still not quite getting it to work. The basic definition is something like this:

\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

This works well for, e.g., 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}

(Well, it doesn't because boisik currently has a bug with its sans serif Greek Sigma that only appears at scale mag:=0+420/600. I sent a bug report to the author. Commenting out sans serif Greek Sigma in the metafont sources works around it.)

Outstanding problems

But it doesn't seem to work across the board.

  1. It doesn't work for mathabx big-operators:
\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}

as the \bigboxright ends up being typeset below the baseline. I think I'm passing the wrong argument to \setfont, but not sure what I should pass.

  1. It doesn't work for delimiters:
\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}

I can use \lsemsym and \rsemsym on their own, but I cannot use \open\lsemsym \sum_{i=1}^n a_n \close\rsemsym as they are typeset inside a textbox, and not as variable sized delimiters. (Lots of kudos for @David Carlisle for all his patience in getting me this far!)

9
  • 2
    in classic tex there is only one workaround, load less fonts, so it is rather document specific. Especially if you are using unicode math where a single font can hold thousands of characters rather than just 256, the restriction to 16 symbol fonts isn't that much of a problem normally although there you do have the theoretical possibility of using \Umathchardef rather than \mathchardef so going beyond 16. – David Carlisle Mar 16 '20 at 16:15
  • Thanks, a 'there is no solution in TeX' is also a good answer, though of course not comprehensive to the other systems. That said, if I want to mix symbols from different fonts, then unicode access to a single font doesn't help either, unless I create my own custom fonts. – Ohad Kammar Mar 16 '20 at 16:21
  • you don't need a survey and nothing can be done in a system calling itself tex, there is simply a hard limit of at most 16 math fonts in any math expression. – David Carlisle Mar 16 '20 at 16:21
  • 3
    as always the question would be improved if it had a test file that would show the problem and could be used to test answers – David Carlisle Mar 16 '20 at 16:27
  • 2
    If the usage was limited to a small number of symbols for a given font, you could use standalone to create the symbol as a PDF. Then you could import it as an image and use scalerel package to give it the right math sizing characteristics, as in this answer: tex.stackexchange.com/questions/477182/math-saturation-symbol/… – Steven B. Segletes Mar 16 '20 at 16:43
4

The restriction is only to 16 fonts within a single math expression, it is rather rare to need more than that. In luatex or xetex you can use \Umathchardef rather than \mathchardef to access beyond 16 families if you really need that, or even in classic TeX you can avoid the issue in the same way as \boldsymbol avoids the issue, switch to an hbox then set up a different font regime just for the single character then return to the outer formula.

This is a single math expression set with pdflatex with 24 different Z

enter image description here

\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}

12
  • Why do you include a \selectfont if the definition of \usefont includes ones already? – Ohad Kammar Mar 16 '20 at 17:32
  • 1
    @OhadKammar because it is a relic of an earlier version, I'll clean up:-) – David Carlisle Mar 16 '20 at 17:41
  • OK, thanks, this is progress towards something I've been long after, though it doesn't quite answer the original question. Re. what I'm after, some issues with this code: (1) the hbox code doesn't preserve the current math mode (can be worked around). (2) I don't quite see how to import arbitrary math characters from a package, e.g., with what to replace the \DeclareMathSymbol{\mac}{1}{fontname}{"69} I might see in a font .sty file. – Ohad Kammar Mar 16 '20 at 17:50
  • @OhadKammar you can extract the equivalent \usefont or modify the packages math setup to be in a custom mathversion instead of the default one then use \hbox{\mathversion{zz}$\mac$} why do you need this? I don't think I have ever needed this in a real document – David Carlisle Mar 16 '20 at 17:59
  • 1
    @OhadKammar as I said in a comment under the question, if you had provided an example document could make an answer that referenced that. – David Carlisle Mar 16 '20 at 18:26
1

I can explain the "outstanding problem #1".

The \bigboxright symbol is declared in mathabx as

\DeclareMathSymbol{\bigboxright}     {1}{mathx}{"D9}

Note that it has category 1, and so it is operator. TeX has special function for displaying operators (see make_op in the Knuth's tex.web file). In particular, it can switch to a larger version of the symbol in display mode and shift the symbol vertically if necessary. To emulate this behaviour, I suggest the following modification of the code:

\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}

Unfortunately, I don't know an easy way to determine the code corresponding to the paired (a larger) symbol ("F9 in this case), because of this pairing is stored inside of the font (so-called charlist entries). To found "F9, I've analyzed \tracingoutput-generated log of a test page with original \bigboxright command. Alternative way is to look at all glyphs using the fonttable package and found a match there.

Most likely it is possible to emulate most of other math categories as well (by just prepending \hbox with \mathbin, \mathrel, etc. to get correct kerning):

\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} 

But emulation of delimiters is too much complicated (because of construction of left/right delimiters of arbitrary size). It's where I give up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.