什么是内部尺寸/胶水/木胶?

什么是内部尺寸/胶水/木胶?

l3skip在的文档中,\dim_eval:n有人警告

这 [...] 如果用于 TeX 风格的分配中,则需要适当的终止,因为它不是 ⟨内部尺寸⟩.

\skip_eval:n类似的警告可以在⟨\muskip_eval:n的描述中找到内胶⟩ 和 ⟨内部胶⟩ 代替 ⟨内部尺寸⟩.

我对 TeX 中跳过和维度的处理相当熟悉,但我从未遇到过这样的表达内部尺寸在 TeXbook 中,除了第 24 章中相当技术性的语法符号之外,我找不到对该短语的任何解释,虽然它肯定包含了所有必要的信息,但并没有真正帮助我。

那么,内部尺寸? 其他类型的维度有哪些?(外部维度?)两者的不同行为的例子有哪些(如上文警告中提到的那样)?

答案1

我将首先介绍 TeX 的一般概念,然后介绍为什么它在这些函数的文档中如此重要expl3

内部维度(或内部计数或其他)是已被 TeX 解析并以正确形式存储的内容。因此 TeX 知道内部维度有效尺寸,无需“寻找”任何其他材料。相反,外部尺寸(ETC。)是由离散标记组成的,必须由 TeX 重新解析才能使用。因此,当我们 12.0pt,我们给出一个外部的表示(TeX 必须解析它才能知道它是一个有效的维度),但之后

\newdimen\mydimen
\mydimen=12pt %

我可以使用\mydimenTeX不是需要解析任何内容:\mydimen拥有内部维度。

为什么这很重要?这都是关于 TeX 的解析规则,特别是 TeX 允许在维度、整数之后添加可选的尾随空格,ETC。更重要的是,有了外部表示,TeX 就不会停止解析,直到找到不“合适”的东西。例如

\def\foo{123}
\newcount\fooint
\fooint=123 %
\newcount\testint
%%%
\testint=\foo 456 %
\showthe\testint
\testint=\fooint 456 %
\showthe\testint

您会发现第一种情况给出了错误的结果:我们有一个宏,它只是扩展为123,而 TeX 一直在寻找整数,直到我们找到可选的空间。相反,使用内部计数表示,不存在解析问题:\fooint 123

关键点在于内部表示使用起来“更安全”(而且速度更快):永远不存在它在哪里终止的问题。


这与什么有关expl3?类似于\dim_eval:n用于将表达式转换为维度。然而,允许它也只是排版,通过宏中的扩展存储()会很方便tlETC。为了做到这一点,我们必须安排评估结果外部的代表,不是一个内部的一。这意味着这些函数的行为就像将值存储为宏一样:您必须观察终止。

对于所有“纯”expl3用法来说,这不是问题,因为我们在正确的地方有正确的终止。但是如果你将这些函数与更经典的 TeX 编程混合使用,你需要知道它们的行为方式。egreg 的回答很好地展示了这一点。


对于那些想要 TeX 细节的人来说,\dim_eval:n这是原始术语

\the\dimexpr #1\relax

如果我们想要得到一个内部表示,我们只需要

\dimexpr #1\relax

但是,它不能用于排版或(成功)在x-type 扩展中使用,因此它不适合我们想要的定义。

答案2

考虑以下示例

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn
\cs_set_eq:NN \dimeval \dim_eval:n
\ExplSyntaxOff

\newlength{\mylen}

\begin{document}

Do an assignment \mylen=\dimeval{3pt+1cm} plus something else.

\end{document}

这会引发错误

! Missing number, treated as zero.
<to be read again> 
                   s
l.12 ...assignment \mylen=\dimeval{3pt+1cm} plus s
                                                  omething else.

这正是 中所提到的interface3

<internal dimension>任意\dimen寄存器或存储(固定)长度的内部寄存器,如\parindent;带有 e-TeX 扩展的 ,也是\dimexpr的一个实例<internal dimension>

另一个重要的事实是\newlength分配一个\skip寄存器,因此 TeX 将期待plusminus规范;当使用时不会发生这种情况\setlength,因为宏提供了合适的\relax终止。

相关内容