更新
这个问题中描述的 LaTeX 错误已解决。使用 TeXlive 2015 中的新 LaTeX(于 2015-05-14 测试)不再出现错误。
原始问题
以下代码给出错误! Corrupted NFSS tables.
。
有人能解释一下具体原因以及应该怎么做才能避免这种情况吗?
在实际文档中,错误是由\normalfont
字体包中的和\selectlanguage{vietnam}
在辅助文件中(因此,简单地移动序言中的线条并不是真正的解决方案)。
\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}
编辑
经过一番挖掘,我明白了一点。只有在\begin{document}
命令\process@table
加载各种默认字体定义时,才会在前言中出现错误。通过尽早加载可以避免错误t5cmr.fd
。但现在我想知道谁能确保它已经完成。字体包无法知道可能需要 T5 编码,babel 无法知道\DefaultSubstituationFont
。
编辑2
我找到了一个解决方法,强制 latex 稍早一点加载 fd 文件,从而设置后备字体。我不太确定这是否没有副作用,我将问题转发给了 latex 列表。
\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}
答案1
一个 NFSS 问题...真好 :-)
看起来像是 25 年前的缺陷。人们可能会争论这是否是一个错误,或者这是否真的是由于序言中的排版不太支持——我猜最终两者都有,因为 NFSS 仅在文档开始时设置其最终表格。然而,我在此之前尝试过适应字体选择,但显然错过了一个案例。
会发生什么?
在 NFSS 中,csname\<encoding>/<family>/<series>/<shape>
保存着一个关于如何在给定特定大小的情况下获取正确字体的配方,例如,如果\T5/fve/m/n/10
正在查找,那么\T5/fve/m/n
将告诉我们如何获取大小为 10 的字体。如果这个宏未定义,那么这是因为 NFSS 不知道这个,或者它没有为这个系列加载任何定义。
在后一种情况下,它会尝试通过加载名为的文件来查找这些定义,t5fve.fd
希望其中包含正确的定义。如果之后它仍然没有得到定义,它会首先将形状更改为某些默认值,然后是系列,最后是系列,以期找到一些合适的替代方案。
在示例中\T5/fve/m/n/10
,第一次请求\selectfont
:它不存在,文件 也不存在t5fve.fd
。因此,NFSS 应用默认值,包括将系列更改为cmr
。现在从技术上讲,这实际上是存在的,但相应的内容t5cmr.fd
尚未加载。
因此执行\T5/cmr/m/n
时还没有定义\wrong@fontshape
,所以接近结尾的部分
\global\expandafter\expandafter\expandafter\let
\expandafter\reserved@a
\csname\curr@fontshape\endcsname
将原始请求\T5/fve/m/n
(存储在\reserved@a
)与最终替代品等同起来,就像\T5/cmr/m/n
它定义的那样,而不是像\T5/fve/m/n
\relax
T5/fve/m/n=macro:
-><-5.5>vnr5<5.5-6.5>vnr6<6.5-7.5>vnr7<7.5-8.5>vnr8<8.5-9.5>vnr9<9.5-11>vnr10<1
1-15>vnr12<15->vnr17
因此,下一个\selectfont
尝试再次查找\T5/fve/m/n/10
(而不是简单地选择之前找到的内容)再次调用\wrong@fontshape
。然而,这一次\wrong@fontshape
注意到之前已经尝试过完全相同的请求,并得出结论,NFSS 表已损坏。
因此 Ulrike 的第二次编辑是正确的:在进行替换之后,我们应该尝试从外部.fd
文件加载任何缺失的 NFSS 定义。
这个位置不太正确,因为只有当我们改变了系列时这才有意义,因为 NFSS 定义是按编码/系列存储的,否则就没有任何“新”内容可加载,并且定义已经在内存中或不存在。
因此,正确的(祈祷 :-) 更改应该是
\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
\begingroup\try@load@fontshape\endgroup %<--------------new
\fi \fi
\fi
\@font@warning{Font shape `\expandafter\string\reserved@a'
\expandafter\@gobble\string\@undefined\MessageBreak
using `\curr@fontshape' instead\@wrong@font@char}%
\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}
顺便问一句:为什么这只是序言中的一个问题?因为每个编码的所有默认值都在文档开始时进行验证,然后.fd
加载任何缺失的文件。因此在文档内部一切都运行正常,这可能就是为什么 25 年来没有人遇到过这种情况的原因。
更新
上述代码的清理版本已添加到新的 LaTeX 内核代码中,以便当 TeX Live 2015 发行版普遍可用时,该修复程序也将普遍可用。
答案2
在手动安装后,我在 Ubuntu 系统上遇到了“损坏的 NFSS 表”消息newtxmath.sty
。我删除了该文件并执行以下操作:
sudo aptitude install texlive-fonts-extra
然后它就成功了。