phst / lualatex-math

LuaTeX-specific enhancements and fixes for LaTeX math typesetting
LaTeX Project Public License v1.3c
13 stars 3 forks source link

The 16 math families limit in LaTeX kernel should be kept #7

Closed khaledhosny closed 9 years ago

khaledhosny commented 11 years ago

Though LuaTeX allows for 256 math families, the syntax of old math primitives (\mathcode, \mathchar, etc.) does not allow for more than 16 families thus increasing the limit set in LaTeX kernel will just cause unexpected behavior when more than 16 families are used with legacy math packages (extended math primitives can use more families but there you actually don’t need that many, thanks to Unicode and OpenType requiring less number of fonts).

Actually the patch in lualatex-math does not work and the limits is still there, so I suggest just dropping the patch.

\documentclass{article}
\usepackage{lualatex-math}

\DeclareSymbolFont{testa}{U}{txmia}{m}{it}
\DeclareSymbolFont{testb}{U}{txmia}{m}{it}
\DeclareSymbolFont{testc}{U}{txmia}{m}{it}
\DeclareSymbolFont{testd}{U}{txmia}{m}{it}
\DeclareSymbolFont{teste}{U}{txmia}{m}{it}
\DeclareSymbolFont{testf}{U}{txmia}{m}{it}
\DeclareSymbolFont{testg}{U}{txmia}{m}{it}

\DeclareSymbolFont{lettersA}{U}{txmia}{m}{it}

\usepackage{amsfonts}
\usepackage{MnSymbol}

\begin{document}
\[\mathtt{Test} \mathcal{L} * - ><\]
\end{document}
phst commented 10 years ago

From JFBU:

% Time-stamp: <10-12-2013 18:10:56 CET jfb>
% use luatex engine
\documentclass{article}
\usepackage[T1]{fontenc}

% this will allow more than sixteen families
\usepackage{lualatex-math}

% but although ok for declaring SymbolFonts, and SymbolFontMathAlphabets,
% not be enough for direct MathAlphabets

% define a bunch of math alphabets
% (definition is ok)

\makeatletter
\@tfor\x:=abcdefghijklmnopqrstuvwxyz\do
 {\expandafter\DeclareMathAlphabet\csname MATH\x\endcsname{OML}{cmmi}{m}{it}}
\makeatother

% one more
\DeclareMathAlphabet\OneMoreAlphabet{T1}{ptm}{bx}{sl}

% but we *must* patch \select@group
\usepackage{etoolbox}
\makeatletter
\patchcmd{\select@group}{\sixt@@n}{\@cclvi}{}{}
\patchcmd{\document@select@group}{\sixt@@n}{\@cclvi}{}{}
\makeatother

% original macros: (and \let\select@group\document@select@group is done
% by \process@table, itself executed by \document)

% \def\select@group#1#2#3#4{%
%  \ifx\math@bgroup\bgroup\else\relax\expandafter\@firstofone\fi
%  {%
%  \ifmmode
%   \ifnum\csname c@mv@\math@version\endcsname<\sixt@@n
%      \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}%
%  }%
% }
% \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<\sixt@@n
%      \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}%
%  }%
% }

\begin{document}

% without the patches we get
% ERROR: LaTeX Error: Too many math alphabets used in version normal.
%

$\MATHa{a}$

% checking with some other alphabet

$\OneMoreAlphabet{A}$

\end{document}
khaledhosny commented 10 years ago

Not sure I understand what this code is trying to do, but giving \mathcode etc. a family number bigger than 0xf will not do what you expect it to do, so does this code fix this?

jfbu commented 10 years ago

I was on the seemingly false premise (*) that \DeclareMathSymbol etc.. from the latex format had been patched to use internally the unicode \Umathcode when compiled for the XeTeX/LuaTeX engines. Your code sample revealed to me that it is not the case,

(*) I can't investigate more now, perhaps what I say is not accurate or even radically wrong

my package mathastext uses conscientiously \DeclareMathSymbol, and if not it then uses \mathcode/mathchardef only for 8bit TeX, and under Unicode engines the correct U primitives. Despite that indeed when it is loaded at a time with more than 16 families, the characters it re-declares do not show up correctly.

if mathastext is loaded at a time with less than 16 families however all is fine, even if later the number of Symbol fonts exceeds the limit, as long as the luatex-math patch and my proposed patch, are applied

So my comment is that legacy math packages are fine if they do not by themselves exceed the 16 math families, and that then the only obstacle to compilation if some package declares new symbol fonts, exceeding the 16 families limit, is the hard-coded check for at most 16 math groups, particularly the check on the number of math alphabets which is done by LaTeX prematurely on entering math mode, LaTeX seems to believe all declared math alphabets are going to be actually used simultaneously in the current math formula :(

see code sample below which compiles successfully

I apologize in advance as I will be unable to engage in the near future in more discussion, but hope to learn more in some weeks (or months) best regards, with apologies,

\documentclass{article}
\usepackage[no-math]{fontspec}
\renewcommand{\familydefault}{\ttdefault}
\usepackage[italic]{mathastext}
% This defines also new alphabets \mathnormalbold, \Mathbf, etc..
% (it does \let\mathbf\Mathbf)

\usepackage{lualatex-math}

% Declare many Symbol fonts
\makeatletter
\@tfor\x:=abcdefghijklmnopqrstuvwxyz\do
{\DeclareSymbolFont {essai\x}{OML}{cmm}{m}{it}
 \expandafter\DeclareSymbolFontAlphabet\csname MATH\x\endcsname{essai\x}}
\makeatother

% Patch LaTeX's limit to 16 families
% (all of the above did not need it, the patch is needed to
% circumvent LaTeX's error when entering math mode and realizing
% many math alphabets are defined)
\usepackage{etoolbox}
\makeatletter
\patchcmd{\select@group}{\sixt@@n}{\@cclvi}{}{}
\patchcmd{\document@select@group}{\sixt@@n}{\@cclvi}{}{}
\makeatother

% sadly if mathastext is loaded at a time with >16 families
% although it used conscientiously \DeclareMathSymbol etc...
% we do see that although no error raised, output is not ok
% 1.3c fixed a bug for >16 families for \$, \%, \&, \#
% but this makes me realize it might have been in vain
% \usepackage[italic]{mathastext}[2013/12/14]

\begin{document}
\[\mathtt{Test} \mathcal{L} \mathnormalbold{abc} * - >< \]
\[ !\,?\,*\,,\,.\,:\,;\,+\,-\,=\,(\,)\,[\,]\,/\,\#\,%
   \$\,\%\,\&\,<\,>\,|\,\{\,\}\,\backslash, \sum, \prod \] 
\end{document}
davidcarlisle commented 9 years ago

Just changing \newmathgroup to 256 without changing \DeclareMathSymbol and friends isn't safe but \DeclareMathAlphabet is OK, the code I suggest at

http://tex.stackexchange.com/a/232620/1090

allows the extended range for math alphabets but restricts \DeclareSymbolFont to 16

I suspect it would be too intrusive for the format by default to use \U... but a package could add extended versions, say \UDeclareSymbolFont , \UDeclareMathSymbol etc that did go past 16 and use \U.... versions of the math primitives.

Note that the extended allocation (and possibly the extension of \DeclareMathAlphabet) are planned for inclusion in latex 2015 which will include engine-aware allocation for all register types in the format, so the redefinition of \new@mathgroup/\newfam needs to be conditional on it being an "old" format wrapping it in \ifx\e@alloc\@undefined ... \fi would be enough.

The 2015 latex release is on public test currently as advertised on latex-l.

josephwright commented 9 years ago

I suggest that lualatex-math checks for the kernel update and if present does nothing. With older kernels it can use the same code as @davidcarlisle has suggested for a kernel addition, so extending the bit that works but not the bit that doesn't. If someone wants to then do the \U... bit (might I guess be me) that will apply to both XeTeX and LuaTeX so should be separate anyway.

phst commented 9 years ago

If the new kernel will support all available families in LuaTeX out of the box, I'd prefer to drop the patch unconditionally rather than trying to support multiple kernels. Given that the patch itself doesn't work reliably and that user who update lualatex-math should hopefully also update LaTeX itself, that looks like a better way forward.

josephwright commented 9 years ago

The kernel update will appear in TL2015 and is on CTAN now (for the TL2015 pretest).