我的期望应该是什么?

我的期望应该是什么?

最近,我在使用 LaTeX 时遇到了一个令人头痛的问题(实际上我使用 XeLaTeX 进行编译,但我认为这个问题是独立的),原因是我在加载数学字体之前无意中尝试修改它的尺寸。

我的期望应该是什么?

  1. LaTeX 应该已经加载它了。
  2. TikZ (pgf)应该已经加载了。
  3. \fontdimen应该已经加载了。
  4. \textfont2应该已经加载了。
  5. 用户应该已经加载它了。(我以前从未被要求做这样的事情。据我所知,没有任何地方记录我必须这样做。)

根据这个特定问题的答案,我想确定标准化的编程实践。LaTeX 和软件包编写者的标准实际上是什么(软件包是否应始终包含字体检查)?是否应针对步骤 1 至 4 中的任何步骤报告错误?

日志中的失败消息:

!Font \nullfont has only 7 fontdimen parameters.

我知道这条消息的意思。pgfTikZ)在执行键之前切换到数学模式baseline,其中包括对尚未加载的字体(数学字体)的修改。我知道自从实施 LaTeX2e 以来,字体不再加载,直到需要它们时.fontspec立即加载字体(如果我错了请纠正我)。

Ijon Tichy 对 LaTeX2e 自 LaTeX 2.09 以来的变化发表了强有力的言论(这让我和同事笑了。这家伙肯定知道自己在说什么!):

您必须知道,当首次使用字体时,将从 LaTeX 的 NFSS2 和 LaTeX2e 中提取的字体首先被加载。以前,还有 LaTeX 2.09,据我所知还有其他人。通过 bzw 格式的 \font-Anweisungen 可以直接写入字体。请参阅文档进度。接下来可以解决与旧 LaTeX-2.09 版本相关的问题,这些新 LaTeX 将被使用。

翻译: 必须注意的是,自 NFSS2 以来,或者最近自 LaTeX2e 以来,LaTeX 中的 tfm 字体文件仅在首次需要时加载。据我所知,LaTeX 2.09 中的实现方式与 LaTeX2e 中的实现方式不同。在 LaTeX 2.09 中,字体直接通过格式中的 \font 指令以及文档前言加载。因此,使用 LaTeX 2.09 编码样式的软件包可能会在 LaTeX2e 中导致问题。

示例代码

\documentclass{article}
\usepackage{tikz} % Absolute positioning, advanced vector graphics
\newcommand{\ampel}[1]{% input: color
\begin{tikzpicture}[baseline=-\the\dimexpr\fontdimen22\textfont2\relax] %<- Magical vertical alignment code that gives LaTeX a hiccup.
   \node[yshift=.4mm,align=center,fill=#1, shape=circle] (O)at (0,0) {};
\end{tikzpicture}
}%
\begin{document}
\ampel{green!70!black}
\end{document}

解决方法

可以明确加载数学字体。

  1. 添加$\null$\begin{document}
  2. 在序言中添加以下内容:

    \makeatletter
    \AtBeginDocument{\sbox\@tempboxa{$\null$}}
    \makeatother
    
  3. 明确检查数学字体(参见 egreg 的答案)

    \makeatletter
    \AtBeginEnvironment{tikzpicture}{\check@mathfonts}
    \makeatother
    

我想在缩小问题范围的同时补充一些我的发现。我有同一份文档的两个版本,一个用德语写成,另一个用英语写成。英语版排版很好。德语版排版不行。我发现英语版\url{}中有一个脚注,其中包括 ,而德语版中却注释掉了。这\url发生在第一次\ampel调用之前。这意味着\url{}加载了数学字体。

答案1

在使用之前\textfont2,您必须确保它已被定义,只有在 LaTeX 排版了至少一个公式(即使是一个空公式)之后,当前字体大小。这是因为它想要支持任意字体大小的数学运算,同时也避免浪费数学组。

在当前条件下,实际负责定义数学字体的命令是\check@mathfonts

\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}

\makeatletter
\AtBeginEnvironment{tikzpicture}{\check@mathfonts}
\makeatother

\newcommand{\ampel}[1]{% input: color
  \begin{tikzpicture}[baseline=-\the\dimexpr\fontdimen22\textfont2\relax]
    \node[yshift=.4mm,align=center,fill=#1, shape=circle] (O)at (0,0) {};
  \end{tikzpicture}%
}

\begin{document}

X\ampel{green!70!black}X

\Huge

X\ampel{green!70!black}X

\end{document}

使用execute at begin picture并不好,因为可选参数被评估图片开始,钩子被检查。不,如果您打算更改文档中的字体大小,仅\sbox0{$$}在文档开头执行(添加无关紧要)是不够的:例如,您可能会进入一个部分标题(前面有,但这是另一回事):尝试使用该方法,第二种情况下的结果,在之后,会出现错误。\null\ampel\protect\Huge

在此处输入图片描述

答案2

如果我可以根据 Joseph Wright 对 egreg 的回答的评论来贡献自己的答案的话:

谁负责在 LaTeX(或 XeLaTeX)中加载字体?(如果是我的,我怎么知道哪些字体?)

  • 加载字体通常是 LaTeX 或包的责任。
  • 当使用 TeX 原语时,这是用户的责任。

\textfont2是原始的,因此必须实施检查由用户查看字体是否已加载。

相关内容