下面顯示了取自 的程式碼片段multido.tex
。我注意到作業並沒有以 結束%
。
\dimen@=#1\advance\dimen@#2
參見\def\multido@step@d#1#2{% \dimen@=#1\advance\dimen@#2 \edef#1{\number\dimen@ sp}}%
再次
\count@=#1\advance\count@ by #2
參見\def\multido@step@i#1#2{% \count@=#1\advance\count@ by #2 \edef#1{\the\count@}}
再看一遍
\dimen@=#1pt
,\dimen@=#2pt
並\dimen@=#1pt\advance\dimen@#2
在\def\multido@init@r#1#2#3{% \dimen@=#1pt \multido@dimtonum\dimen@#3% \dimen@=#2pt \ifnum\multido@count<\z@\dimen@=-\dimen@\fi \multido@addtostep{\do\multido@step@r{\do#3}{\number\dimen@ sp}}} \def\multido@step@r#1#2{% \dimen@=#1pt\advance\dimen@#2 \multido@dimtonum\dimen@#1}
賦值是否會產生必須以 結尾的尾隨空格%
?
答案1
實施例1
\def\multido@step@d#1#2{%
\dimen@=#1\advance\dimen@#2
\edef#1{\number\dimen@ sp}}%
之後#2
應該有\relax
。事實上,如果#2
是暫存器或參數,例如\z@
或\lineskip
,則行尾提供的空間將不是被忽略。在這種情況下也%
可以使用,因為以下標記是不可擴展的 ( \edef
)。從中獲得的令牌清單\multido@step@d{\x}{2pt}
將是(我用•表示空間令牌)
\dimen@=\x\advance\dimen@2pt•\edef\x{\number\dimen@ sp}
並且前面的空格\edef
將被忽略。但使用 `\multido@step@d{\x}{\parindent} 就會有
\dimen@=\x\advance\dimen@\parindent•\edef\x{\number\dimen@ sp}
空間令牌將不是被忽略。它遵循控製字這一事實是無關緊要的:標記化階段已經發生。之後\relax
將#2
有\relax
空間令牌的位置。
實施例2
都是一樣的。\relax
之後應該有#2
實施例3
為了清楚起見,我將對行進行編號。
1 \def\multido@init@r#1#2#3{%
2 \dimen@=#1pt
3 \multido@dimtonum\dimen@#3%
4 \dimen@=#2pt
5 \ifnum\multido@count<\z@\dimen@=-\dimen@\fi
6 \multido@addtostep{\do\multido@step@r{\do#3}{\number\dimen@ sp}}}
7 \def\multido@step@r#1#2{%
8 \dimen@=#1pt\advance\dimen@#2
9 \multido@dimtonum\dimen@#1}
無需用 ; 終止第 2 行和第 4 行%
。實際上,%
第 4 行末尾的a是錯誤的,因為 TeX 會\ifnum
在執行分配之前開始擴展\dimen@
(在本例中可能是無害的)。
與之前相同的問題出現在第 3 行: the%
在這裡很好,因為下面的標記是\dimen@
that's unexpandable;\relax
會更好。
第 8 行應該\relax
在末尾,原因與之前相同;不是 a ,因為諸如之類的%
參數會在執行賦值之前觸發 的擴展。#2
2pt
\multido@dimtonum
答案2
當 TeX 掃描尺寸時,除非儲存的數量以寄存器的形式呈現,否則它將繼續尋找數字和單位(一路擴展),直到到達空格或不適當的字元。空格被刪除;因此,在功能上顯示時編寫的賦值在刪除以下空格方面與控製字具有相同的行為。當然,如果尺寸是一個寄存器,那麼寄存器名稱要么是一個控製字本身(從而吞掉了空格),要么是 TeX 將掃描的數字......
也就是說,一些您顯示的分配使用參數(如#2
)作為維度。一些偷偷摸摸或太聰明的人可能會使用寄存器來實現這一點,然後空間就不會被佔用,因為它會在讀取控製字之前被寫入巨集定義中。實際上,當此類數據不受程式設計師控制時,最好用\relax
.