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
。
An<internal dimension>
是任何儲存(剛性)長度的\dimen
暫存器或任何內部暫存器,例如\parindent
;帶有 e-TeX 擴展,\dimexpr
也是<internal dimension>
.
另一個重要的事實是\newlength
分配一個\skip
寄存器,因此 TeX 將期待plus
或minus
規範;\setlength
使用時不會發生這種情況,因為巨集提供了適當的\relax
終止。