有人可以解釋 futurelet之內對齊環境?
例子:
如果下一個字元是 {,則命令 \A 應該給出“A”,如果是 &,則給出“B”,在任何其他情況下給出“C”。
\gdef\A{\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}
對於普通文字或內聯數學,它工作得很好:
\A{a},\A&,\A a % -> "A,B,C"
$\A{a}$,$\A&$,$\A a$ % -> "A,B,C"
但當我在align*環境(amsmath)中使用它時,出現“不完整\ ifx”錯誤:
\begin{align*} \A{a},\A&,\A a \end{align*}% --> error.
有人可以跟我解釋一下嗎?謝謝!
克里斯
PS:在對齊環境中,關於 futurelet 還有更多我不明白的事情:如果我們定義
\gdef\A{\futurelet\thesymbol\alpha}
\gdef\D#1{\detokenize{#1}}
然後
\begin{align*}
\D&,\A a % -> "&,alpha a" (okay)
\A a,\D{&} % -> "alpha a,&" (okay)
\A a,\D& % -> error: "Argument of D has an extra }." (???)
\end{align*}
答案1
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}
當 TeX 看到 時,&
它將在模板的其餘部分中交換為\halign
乳膠大小寫中指定的 等c
r
,因此\ifx
將比較模板的前兩個標記(可能\unskip
然後\hfil
單元格(以及組)將結束出問題。
&
如果你想在 futurelet 之前開始一個群組並在測試後結束它時隱藏,你需要
{\ifnum0=`}
...
\ifnum0=`{\fi}
出現在任何表格程式碼中的形式。
這會產生 A、B、C,我認為這是預期的結果。
\documentclass{article}
\usepackage{amsmath}
\gdef\A{{\ifnum0=`}\fi\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi \ifnum0=`{\fi}}
\begin{document}
\begin{align*} \A{a},\A&,\A a \end{align*}
\end{document}
對於第二個範例,請注意&
結束組
a,\D&
就像{\D}
並且都給出相同的錯誤:
! Argument of \D has an extra }.
<inserted text>
\par
l.15 {\D}
那裡並不清楚修復是什麼,因為不清楚您想要{\D}
做什麼。
答案2
我無法與 David 對 TeX 程式碼的理解競爭,所以我不會嘗試修復你的巨集(不過,我的觀點是你所做的從根本上來說是不明智的)。然而,他對“當 TeX 看到&
”的評論可以擴展如下。在掃描對齊時,TeX 的行為方式與大多數用戶(甚至是經驗豐富且知識淵博的用戶)的執行思維模型有些不一致。也就是說,我們想像TeX 總是做以下三件事之一:
掃描輸入,對字元進行分詞,為巨集解析器「嘴」提供食物;
擴展巨集;
執行不可擴展的標記:要么是諸如
\def
或 之類的編程指令\hbox
,要么是諸如字符之類的直接排版命令。
在這個模型下,每個人都期望在對齊(TeX 原語\halign
或\valign
)內製表符&
在第 3 點下執行其操作:執行。然而事實並非如此。事實上,TeX 在第 1 點中「注意到」製表符!如果TeX曾經讀過&符號(或等效類別的字元)它將立即結束當前單元格,關閉群組,插入v
模板的“部分”,等等。
(編輯:我只是瀏覽一下errorlog.pdf
(即texdoc errorlog
),並在 1978 年 3 月 18 日的一次調試會議上找到了相關評論:
進行取得下一個例程的攔截
&
和\cr
標記。我以為我可以直接將&
and\cr
放入big_switch
[即,在 TeX 的胃中,而不是眼睛中];這是一個很大的錯誤。
這是對導致 Knuth 對這些數組標記做出上述顯然奇怪的行為選擇的有趣的部分見解,並確認這確實是這種行為。
當然,例外是當 TeX 位於未完成的大括號組內時(並且它必須是實際的大括號字符,而不是隱式的大括號字符 或\begingroup
,啟動該組),這會導致 David 的{\ifnum0=
}` 結構可擴展地等效於左大括號無需在可能放置它的巨集定義中實際創建不平衡的大括號。
這種奇怪的解析規則的結果是,人們必須非常小心表格單元格中的巨集讀取的內容或環境中包含的內容。像您這樣的宏,透過賦值而不是宏參數解析來有效地讀取它們的參數,甚至更加不穩定,因為如果沒有必要的大括號,可以讀取的選項卡將不是受到保護。表相容環境包括該\ifnum
內容以保護可能出現在其中的任何製表符;更幼稚的方法將分散到各個單元中,因此可能會失敗。