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 %
我可以使用\mydimen
TeX不是需要解析任何内容:\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
用于将表达式转换为维度。然而,允许它也只是排版,通过宏中的扩展存储()会很方便tl
,ETC。为了做到这一点,我们必须安排评估结果外部的代表,不是一个内部的一。这意味着这些函数的行为就像将值存储为宏一样:您必须观察终止。
对于所有“纯”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 将期待plus
或minus
规范;当使用时不会发生这种情况\setlength
,因为宏提供了合适的\relax
终止。