
我有以下純 Tex 程式碼:
\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp\xx a b c
\tempii\tempii
我期望看到以下輸出:
a b c ABCABC
但我實際上看到了這一點:
b c ABCaABCa
為什麼'a'被搶進\tempii的定義中?
答案1
我仍在思考為什麼會這樣,但這次修訂(擁抱\xx
)給了你想要的。
我認為答案是,在用法中\temp\xx a b c
,後面的空格\xx
從TeX解析器的角度來看,根本不是空格,而只是表示巨集名稱的結束\xx
。例如,如果您僅單獨添加\xx A
一行,您將看到它列印出來時ABCA
沒有空格。因此,解析器將尾隨的“A”吸入為連接到\xx
。人們也可以使用\temp\xx{} a b c
, 作為告訴解析器空格是分隔符號的一種方式,而不僅僅是 後面的下一個字元\xx
。
\documentclass{article}
\begin{document}
\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp{\xx} a b c
\tempii\tempii
\end{document}
答案2
為了清楚起見,我將用 表示空間標記•
,因為它們在討論中非常重要;應忽略以下程式碼範例中的空格。
的參數文字\temp
為
#1•
而替換文字是
\def\tempii{#1}
你的呼喚\temp
是
\temp\xx a•b•c•\tempii\tempii
請注意,後面\xx
有一個空格僅用於分隔巨集;這是不是空格標記:沒什麼,因為 TeX 總是忽略控制後面的空格字(不控制符號)。後面的空格c
來自程式碼中的行尾。
掃描後面的標記\temp
(不擴展)以查找與參數文字的匹配,其中參數由空格分隔,因此#1
結束\xx a
,輸入流的下一個狀態是
\def\tempii{\xx a}b•c•\tempii\tempii
現在 TeX 執行定義並將其從輸入流中刪除:
b•c•\tempii\tempii
並且該部分b•c•
被傳遞到排版階段。展開 的兩個副本後\tempii
,這相當於輸入了
b•c•\xx a\xx a
或者
b•c•ABCaABCa
這正是你得到的。
如果您使用\?
而不是\xx
最後兩行將轉換為
\temp\?•a•b•c•\tempii\tempii
因為\?
是一個控制符號,TeX 不會忽略它們後面的空格。在這種情況下,結果將是
a•b•c•ABCABC
注意
\expandafter\temp\xx a•b•c
\tempii\tempii
會產生相同的結果,因為 TeX 的操作之後\expandafter
會顯示
\temp ABCa•b•c
(當然,空間約定與以前相同)。你會得到與 with\?
而不是\xx
with相同的結果
\expandafter\temp\expandafter\xx\space a•b•c
因為這樣 TeX 就會出現
\temp\xx•a•b•c
事實上,只有在標記化過程中,控製字後面的空格才會被忽略。