Update
The LaTeX-bug described in this question has been resolved. With the new LaTeX in TeXlive 2015 (tested on 2015-05-14) there is no longer an error.
Original Question
The following code gives the error ! Corrupted NFSS tables.
.
Can someone explain why exactly and what should be done to avoid it?
In the real document the error was triggered by a \normalfont
in a font package and a \selectlanguage{vietnam}
in the aux-file (so simply moving the lines in the preamble is not really a solution).
\documentclass{book}
\usepackage[T5,T1]{fontenc}
\renewcommand\rmdefault{fve}%no T5fve.fd
\fontencoding{T1}\fontfamily{\familydefault}\selectfont
\fontencoding{T5}\selectfont
\selectfont %error
\begin{document}
blub
\end{document}
Edit
After some digging I understand a bit more. One gets the error only in the preamble as at \begin{document}
the command \process@table
loads various default font definitions. One can avoid the error by loading t5cmr.fd
early enough. But now I wonder who could ensure that it is done. The font package can't know that perhaps T5 encoding is wanted, babel can't know the \DefaultSubstituationFont
.
Edit 2
I found a work-around to force latex to load the fd-file a bit earlier and so to setup the fallback font. I'm not quite sure if this as no side effects and I forwarded the question to the latex list.
\documentclass{book}
\usepackage[T5,T1]{fontenc}
\makeatletter
\def\wrong@fontshape{%
\csname D@\f@encoding\endcsname % install defaults if in math
\edef\reserved@a{\csname\curr@fontshape\endcsname}%
\ifx\last@fontshape\reserved@a
\errmessage{Corrupted NFSS tables}%
\error@fontshape
\else
\let\f@shape\default@shape
\expandafter\ifx\csname\curr@fontshape\endcsname\relax
\let\f@series\default@series
\expandafter
\ifx\csname\curr@fontshape\endcsname\relax
\let\f@family\default@family
\fi \fi
\fi
\@font@warning{Font shape `\expandafter\string\reserved@a'
\expandafter\@gobble\string\@undefined\MessageBreak
using `\curr@fontshape' instead\@wrong@font@char}%
\begingroup\try@load@fontshape\endgroup %<--------------new
\global\let\last@fontshape\reserved@a
\gdef\@defaultsubs{%
\@font@warning{Some font shapes were not available, defaults
substituted.\@gobbletwo}}%
\global\expandafter\expandafter\expandafter\let
\expandafter\reserved@a
\csname\curr@fontshape\endcsname
\xdef\font@name{%
\csname\curr@fontshape/\f@size\endcsname}%
\pickup@font}
\makeatother
\renewcommand\rmdefault{fve}%no T5fve.fd
\fontencoding{T1}\fontfamily{\familydefault}\selectfont
\fontencoding{T5}\selectfont
\selectfont %error
\begin{document}
blub
\end{document}
Best Answer
An NFSS question ... how nice :-)
Looks like a quarter of century old deficiency. One could argue whether or not this is a bug or whether it is really due to the fact that in the preamble typesetting is not quite supported — I guess in the end it is a bit of both as NFSS sets up its final tables only at begin document. However, I tried to accommodate for font selection before that, but obviously missed one case.
What happens?
In NFSS the csname
\<encoding>/<family>/<series>/<shape>
holds a recipe how to get to the right font given a specific size, e.g., if\T5/fve/m/n/10
is being looked for, then\T5/fve/m/n
will tell us how to get the font for size 10. If this macro is undefined then this is either because NFSS doesn't know about this or it hasn't loaded any definition for this family.In the latter case it tries to find those definitions by loading a file named
t5fve.fd
hoping that this contains the right definitions. If after that it still hasn't got a definition it will change first the shape then the series and finally the family to some defaults in the hope to find some suitable alternative.In the example
\T5/fve/m/n/10
is requested at the first\selectfont
: it doesn't exist and neither does the filet5fve.fd
. So NFSS applies the defaults up to and including changing the family tocmr
. Now that actually exists technically, but the correspondingt5cmr.fd
has not been loaded yet.Thus
\T5/cmr/m/n
does not yet have a definition when\wrong@fontshape
executes and so the part near the endthat equates the original request for
\T5/fve/m/n
(stored in\reserved@a
) with the final substitute\T5/cmr/m/n
just doesn't work as it defines\T5/fve/m/n
to be\relax
rather than something likeAs a result the next
\selectfont
tries again to find\T5/fve/m/n/10
(instead of simply selecting what was found before) calling again on\wrong@fontshape
. This time however\wrong@fontshape
notices that it was tried before with exactly the same request and concludes that the NFSS tables are corrupted.So Ulrike's second edit is correct: after doing the substitution, we should try to load any missing NFSS definitions from an external
.fd
file.The position is not quite correct as this only makes sense if we have changed the family as NFSS definitions are stored per encoding/family, otherwise there is nothing "new" to load and the definition is either already in memory or doesn't exist.
So a correct (fingers crossed :-) change would be
By the way: why is this only an issue in the preamble? Because all the defaults for each encoding are verified at begin document and any missing
.fd
file is loaded then. So inside the document everything has worked just fine, which is probably why nobody ever came across that in 25 years.Update
A cleaned up version of the above code has been added to the new LaTeX kernel code so that the fix will be generally available when the TeX Live 2015 distribution will become generally available.