16

Sometimes I receive a message:

! LaTeX Error: Too many math alphabets used in version normal.

I know that there is a limit of 16 alphabets at most allowed to one article. However this message specified version normal, so are there any other version of LaTeX permitting more than 16 alphabets?

Popopo
  • 831
  • 1
    related: http://tex.stackexchange.com/questions/3676/too-many-math-alphabets-error – Marco Daniel Mar 01 '13 at 13:00
  • 2
    The normal there refered to \mathversion{normal} as opposed to \mathversion{bold} not the latex engine. As @egreg says you can use xe/lua latex but usually you can arrange not to use so many math alphabets in standard latex as well. In particular any alphabets such as \mathrm \mathit etc could usually instead be accessed as text fonts \textrm{} etc and avoid using up one of the math font slots. – David Carlisle Mar 01 '13 at 13:20
  • Why do you need more than 16 math alphabets? – Martin Schröder Mar 05 '13 at 14:47
  • 1
    @MartinSchröder Well, says frankly I'm writing an article in logic. Thus need abundant fonts to avoid ambiguity. Take an example, we usually use \mathfrak{A} to denote a single structure, whereas use \mathsf{A} to denote a structure class. – Popopo Mar 06 '13 at 10:44

1 Answers1

18

You can use more that 16 math groups (math alphabets, in particular) with XeLaTeX or LuaLaTeX; here's an example. One must also change the allocation mechanism, of course.

\documentclass{article}
\makeatletter
\def\new@mathgroup{\alloc@8\mathgroup\mathchardef\@cclvi}
\def\document@select@group#1#2#3#4{%
 \ifx\math@bgroup\bgroup\else\relax\expandafter\@firstofone\fi
 {%
 \ifmmode
   \ifnum\csname c@mv@\math@version\endcsname<\@cclvi
     \begingroup
       \escapechar\m@ne
       \getanddefine@fonts{\csname c@mv@\math@version\endcsname}#3%
       \globaldefs\@ne  \math@fonts
     \endgroup
     \expandafter\extract@alph@from@version
         \csname mv@\math@version\expandafter\endcsname
         \expandafter{\number\csname
                       c@mv@\math@version\endcsname}%
          #1%
     \global\advance\csname c@mv@\math@version\endcsname\@ne
   \else
     \let#1\relax
     \@latex@error{Too many math alphabets used
                   in version \math@version}%
        \@eha
  \fi
 \else \expandafter\non@alpherr\fi
 #1{#4}%
 }%
}
\def\select@group#1#2#3#4{%
 \ifx\math@bgroup\bgroup\else\relax\expandafter\@firstofone\fi
 {%
 \ifmmode
  \ifnum\csname c@mv@\math@version\endcsname<\@cclvi
     \begingroup
       \escapechar\m@ne
       \getanddefine@fonts{\csname c@mv@\math@version\endcsname}#3%
       \globaldefs\@ne  \math@fonts
     \endgroup
     \init@restore@version
     \xdef#1{\noexpand\use@mathgroup\noexpand#2%
             {\number\csname c@mv@\math@version\endcsname}}%
     \global\advance\csname c@mv@\math@version\endcsname\@ne
   \else
     \let#1\relax
     \@latex@error{Too many math alphabets used in
                   version \math@version}%
        \@eha
   \fi
 \else \expandafter\non@alpherr\fi
 #1{#4}%
 }%
}
\makeatother
\DeclareMathAlphabet{\mA}{OT1}{pcr}{m}{n}
\DeclareMathAlphabet{\mB}{OT1}{pcr}{m}{it}
\DeclareMathAlphabet{\mC}{OT1}{pcr}{b}{n}
\DeclareMathAlphabet{\mD}{OT1}{pcr}{b}{it}
\DeclareMathAlphabet{\mE}{OT1}{ptm}{m}{n}
\DeclareMathAlphabet{\mF}{OT1}{ptm}{m}{it}
\DeclareMathAlphabet{\mG}{OT1}{ptm}{b}{n}
\DeclareMathAlphabet{\mH}{OT1}{ptm}{b}{it}
\DeclareMathAlphabet{\mI}{OT1}{pag}{m}{n}
\DeclareMathAlphabet{\mJ}{OT1}{pag}{m}{it}
\DeclareMathAlphabet{\mK}{OT1}{pag}{b}{n}
\DeclareMathAlphabet{\mL}{OT1}{pag}{b}{it}
\DeclareMathAlphabet{\mM}{OT1}{pbk}{m}{n}
\DeclareMathAlphabet{\mN}{OT1}{pbk}{m}{it}
\DeclareMathAlphabet{\mO}{OT1}{pbk}{b}{n}
\DeclareMathAlphabet{\mP}{OT1}{pbk}{b}{it}

\begin{document}
$
\mathbf{X}
\mathit{X}
\mathsf{X}
\mathtt{X}
\mA{X}
\mB{X}
\mC{X}
\mD{X}
\mE{X}
\mF{X}
\mG{X}
\mH{X}
\mI{X}
\mJ{X}
\mK{X}
\mL{X}
\mM{X}
\mN{X}
\mO{X}
\mP{X}
$
\end{document}

One could do without copying all that stuff with a simpler patch; the following code should replace all that in the previous one is between \makeatletter and \makeatother:

\usepackage{etoolbox}
\makeatletter
\def\new@mathgroup{\alloc@8\mathgroup\mathchardef\@cclvi}
\patchcmd{\document@select@group}{\sixt@@n}{\@cclvi}{}{}
\patchcmd{\select@group}{\sixt@@n}{\@cclvi}{}{}
\makeatother

Compiling the document with xelatex or lualatex will show the following horror; of course you'll have better use cases.

enter image description here

Important remark

As Khaled Hosny quite rightly observes, there is a very important limitation: this can work only for math alphabets; it's impossible to define \mathchar values that use the extended set (the XeTeX or LuaTeX extensions should be used). Thus one has to be careful when using math symbol fonts which must be loaded in memory before the math alphabets. So, if , say, stmaryrd is loaded, it's best to ensure that a formula using it is typeset before using the new math alphabets; a \sbox0{$\Ydown$} in the preamble should be sufficient, because so a math group will be permanently allocated for stmaryrd.

egreg
  • 1,121,712
  • 1
    It seems a bit "surreal" to declare new alphabets for LuaTeX and XeLaTeX with OT1 encoding:) – yannisl Mar 01 '13 at 13:36
  • @YiannisLazarides That's only an example; probably \DeclareSymbolFont would make for a more interesting one. I was just too lazy for hunting through font catalogs. – egreg Mar 01 '13 at 13:40
  • It's wonderful! – Popopo Mar 01 '13 at 13:46
  • @YiannisLazarides This code might make easier the life for the maintainer of the LaTeX symbol list. – egreg Mar 01 '13 at 13:50
  • @egreg ... Was thinking about it too! For most of the packages over the math alphabet limit they went the text route though. – yannisl Mar 01 '13 at 13:56
  • @egreg Well, I have tested your codes and eventually found it works via LuaLaTex but doesn't work via XeLaTeX. If use XeLaTeX it seems only the first 12 fonts reveal correctly. – Popopo Mar 01 '13 at 14:47
  • @Popopo You probably have an outdated version of XeTeX; the version in TeX Live 2012 (and possibly MiKTeX 2.9, but I'm not sure) has corrected a bug regarding math groups. You should have XeTeX version 0.9998 for this to work. – egreg Mar 01 '13 at 14:50
  • @egreg My version of XeTeX is 3.1415926-2.4-0.9998 (MiKTeX 2.9). – Popopo Mar 01 '13 at 14:53
  • @Popopo Sorry; I'm not a MiKTeX user. It's possible that the bug fix found its way in TeX Live and not in MiKTeX, while the version number didn't change. It was a last minute fix just before TeX Live 2012 was frozen for release. See http://tex.stackexchange.com/a/61027/4427 – egreg Mar 01 '13 at 14:56
  • @egreg Can we fix it manually? – Popopo Mar 01 '13 at 15:00
  • @Popopo No. It requires recompiling the binary from the sources; until C. Schenk doesn't do it, you're stuck. – egreg Mar 01 '13 at 15:06
  • @egreg What a pity... – Popopo Mar 01 '13 at 15:12
  • @egreg I have an idea: to install TeX live 2012, then graft XeTeX files to MiKTeX. Is it a good idea? – Popopo Mar 01 '13 at 15:40
  • @Popopo I don't think it can work. – egreg Mar 01 '13 at 15:41
  • @egreg You are right, they're a bit different. – Popopo Mar 02 '13 at 05:00
  • XeTeX and LuaTeX can use more than 16 math families, but legacy math primitives (\mathchar, \delcode, etc) can not use higher families and the output for any thing but class 7 symbols using higher math family will be wrong. – خالد حسني Mar 05 '13 at 21:12
  • @KhaledHosny The question was about using math alphabets; so exactly for class 7 symbols. There's nothing in the answer that suggests one can use higher families for other than letters, but I'll add it for clarity. – egreg Mar 05 '13 at 21:14
  • @egreg: That is better now. I’ve failing for this for long time, that I’m trying to make sure others don’t :) – خالد حسني Mar 05 '13 at 22:19
  • @KhaledHosny One might try to extend the \DeclareMathSymbol command for using \XeTeXmathchar instead of \mathchar. Hard work, maybe, and probably quite useless if done only for compiling more easily the Comprehensive List of Symbols. :) – egreg Mar 05 '13 at 22:26
  • I'd stick something like \RequirePackage{ifxetex,ifluatex} \begingroup \newif\ifModern\Modernfalse \ifxetex\Moderntrue\fi \ifluatex\Moderntrue\fi \ifModern \def\action{\endgroup} \else \def\action{\endgroup<some kind of error message}\fi \action in there such that if one tried to compile with latex or pdflatex it would output an error message. – kahen Mar 05 '13 at 23:44
  • @egreg: You still have \delcode and \delimiter which has no equivalent since \Udelcode and \Udelimeter work differently (there is no large family). – خالد حسني Mar 06 '13 at 04:31
  • Note that in the upcoming (2015) LaTeX2e release \new@mathgroup will be updated to allow 256 slots with XeTeX/LuaTeX. – Joseph Wright Mar 12 '15 at 08:51