更新

更新

更新

这个问题中描述的 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

然后它就成功了。

相关内容