
TeX 不使用哪些標記作為不定界參數(除非嵌套在類別代碼 1 的明確字元標記和類別代碼 2 的明確字元標記之間)?
在 TeXbook 練習 20.4 之前的最後但也是一個危險的段落中,你會發現這樣的句子:
說出 '
\def\row#1#2{...}
' 後,您可以在參數之間添加空格(例如 '\row x n
'),因為 TeX 不使用單一空格作為無限參數。
在 TeXbook 練習 20.5 之前的雙危險彎曲段落中,您可以找到以下句子:
您可能會問,TeX 如何決定參數的停止位置。答:[...]緊隨其後的是一個不帶分隔符號的參數⟨參數文字⟩透過參數標記,或出現在參數文字的最末尾;在這種情況下,相應的參數是下一個非空標記,除非該標記是“
{
”,否則參數將是{...}
後面的整個組。
在 TeXbook 中,我確實找到了術語「單一空格」和術語「非空白標記」的精確定義。
請枚舉 TeX 不用作無分隔參數的所有標記(除非嵌套在類別代碼 1 的明確字元標記和類別代碼 2 的明確字元標記之間)。
到目前為止,我發現 TeX 不使用類別代碼 10 和字元代碼 32 的顯式字元標記作為無分隔參數 - 您需要關注 TeX 對\macro
第二個參數的看法:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A B
\show\macrob
\bye
類別代碼 10 和字元代碼 32 的隱式字元標記用作不定界宏參數:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\X=13
\uppercase{\let\space= } %
\uppercase{\letX= } %
\macro A\space B
\show\macrob
\macro AXB
\show\macrob
\bye
明確有趣的空格用作無限制的宏參數:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\uccode`\ =`\a
\uppercase{\macro A B}%
\show\macrob
\bye
隱式有趣的空格用作無限制的宏參數:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\def\letcs#1#2{\let#1= #2}%
\catcode`\X=13
\uccode`\ =`\a
\uppercase{\letcs\space{ }}%
\uppercase{\letcsX{ }}%
\macro A\space B
\show\macrob
\macro AXB
\show\macrob
\bye
類別代碼 12 和字元代碼 32 的隱式/明確字元標記用作不定界宏參數:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\ =12\relax%
\let\space= %
\macro{A} {B}%
\show\macrob
\macro{A}\space{B}%
\show\macrob
\bye
控制空間用作無限制的巨集參數:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A\ B
\show\macrob
\bye
因此,我測試了一些情況,但測試邊緣情況既不會導致術語「單一空格」的精確定義,也不會導致術語「非空白標記」的精確定義。 ;-)
換句話說:我不知道 TeX 不使用哪些標記作為無分隔參數(除非嵌套在類別代碼 1 的字元標記和類別代碼 2 的字元標記之間)。
看來數量⟨空間代幣⟩不等於「單一空格」/「非空白標記」:
TeXbook 在第 24 章:垂直模式總結中說:
數量⟨空間代幣⟩,它被用在語法中⟨可選空格⟩上面,代表顯式或隱式空間。換句話說,它表示類別 10 的字符標記,或控制序列或活動字符,其當前含義已通過
\let
或等於此類標記\futurelet
。
所提到的“控制序列或活動字符”,可歸入⟨空間代幣⟩, 將用作不定界宏參數(上面的範例顯示了這一點),而「單一空格」/「非空白標記」不用作不定界宏參數。
可能「單一空格」/「非空白標記」是嚴格的子集⟨空間代幣⟩?
如果是的話──到底是哪個子集?
答案1
TeXbook 的風格通常是說一些正確的事情,但不是完整的事實。
「單一空間」沒有正式的定義,因為不需要它。
確實,如果你嘗試
\begingroup\def\\{\global\let\spacetoken= }\\ \endgroup
\def\foo#1#2{(First is #1)(Second is #2)}
\foo AB
\foo A B
\edef\two{\space\space}
\expandafter\foo\expandafter A\two B
\foo A\spacetoken B
\bye
你會得到三個實例
(第一個是A)(第二個是B)
最後一行將產生
(第一個是A)(第二個是)B
此\expandafter
技巧用於在A
和之間注入多個空格B
。所以你會發現下一個練習「更正確」:TeX 跳過任何明確的尋找無分隔參數時的空格標記。
最後一個例子表明隱含的不會跳過空格標記。程式碼中的第一行借自練習 24.6,用於建立\spacetoken
隱式空間標記,因為不能像 中那樣簡單地執行操作\let\bgroup={
。如果你添加\show\spacetoken
你會得到
> \spacetoken=blank space .
但這是不是尋找無分隔參數時被忽略。
明確空格標記是類別代碼 10 的字元標記(正常設定下為空格或製表符;但如果您對它們感興趣,請參閱後面的詳細資訊)。在正常設定下,這可能是由輸入中的空格或製表符或在輸入標記化時分配類別代碼 10 的任何字元產生的。
但是有一個問題。總有一個!
必須考慮到 TeX 將吸收類別代碼 10 的字符,並獨立於其原始字符代碼為它們分配字符代碼 32。因此製表符與空格沒有什麼不同,因為它們是執行標記化後也是如此。
那麼,有什麼問題
\uccode` =`x \uppercase{\foo A B}
這並沒有忽略有趣的空間?它實際上不同於
\catcode`*=10 \foo A*B
忽略星號,因為它的類別代碼為 10。
事實上,類別代碼為 10 的字元是歸一化字元代碼為 32在標記化期間。但是,當應用時,已經執行\uppercase
了標記化,並且空格的字元代碼為 32 。\uppercase
x
因此,僅忽略字元代碼 32 和類別代碼 10 的字元的答案是正確的,但如果不考慮標準化,則會產生誤導。
答案2
tex.web 有
begin if cur_tok=space_token then
跳過被忽略的標記,其中space_token
是
@d space_token=@'5040 {$2^8\cdot|spacer|+|" "|$}
答案3
字元代碼 32 和類別 10(空格)的明確字元標記序列是 TeX 在「尋找」未定界參數的開頭時唯一跳過的內容。
數量⟨空間代幣⟩事實上,從您引用的 TeXbook 段落的意義上來說,確實不等於「單一空格」/「非空白標記」:
數量⟨一個可選空間⟩定義為:
⟨一個可選空間⟩→⟨空間代幣⟩|⟨空的⟩
無論在哪裡⟨一個可選空間⟩是允許的,它也可以是隱式空間令牌。
參見,例如,
\lowercase{\let\sptoken = } %
\edef\result{\number1234 }
\show\result
\edef\result{\number1234\sptoken}
\show\result
\let\result\sptoken\sptoken=\sptoken\TeX
\bye
(這裡\lowercase
只是刪除大括號。這樣您就可以在“=”後面獲得兩個字元代碼為 32 的顯式空格標記。第一個將被丟棄,因為使用 - 賦值,\let
“=”後面的一個空格是可選的\sptoken
。
\sptoken
是一個隱式空間標記。它在 TeX 的求值過程中像顯式空間標記一樣
被丟棄。 它也像其他任何東西一樣被丟棄\number
⟨可選空間⟩在執行第二個\let
任務時。但是 TeX在「尋找」未定界參數的開頭時
不會跳過。\sptoken
所以這個例子證明了數量⟨空間代幣⟩不等於您引用的 TeXbook 段落意義上的「單一空格」/「非空白標記」。
順便一提:
您的問題集中在 TeX 在尋找無分隔參數的開頭時如何處理標記。
您的問題涉及已經完成標記化的處理階段。
儘管如此,值得一提的是與 .tex-input 標記化過程相關的事實:
如果在標記 .tex-input 的過程中,TeX 遇到類別代碼為 10(空格)的字符,而閱讀設備處於狀態 M(行中間),那麼 TeX 將附加一個類別 10 的顯式字元標記(空格)和字元代碼32 到令牌流。即,所得到的標記將具有字元代碼32,而不管所討論的輸入的字元的代碼點具有多少數字。
例如,水平製表符(水平製表符的 ASCII 代碼點編號為 9)通常也指派有類別代碼 10。因此,對水平製表符進行標記通常會產生類別 10(空格)和字元代碼 32 的明確字元標記。