理解 \@firstofone

理解 \@firstofone

我正在查看這個答案並試圖理解程式碼,我是 LaTeX 的超級新手(我的第二天),我堅持了程式碼的以下部分,我無法使其在非表格環境中工作。這是我不明白的最簡單的形式。

\documentclass{article}
\begin{document}
    \newcommand*\f[3]{#1-#2-#3}
    \newcommand*\ex[1]{\f#1 - \expandafter\f\@firstofone}
     Try \ex{111}{221}
\end{document}

由於某種原因,我不清楚,在連結的程式碼中,最後一個參數沒有被消耗,但它被構造所消耗expandafter\f\...。根據我的理解,\expandafter應該首先“運行” \@firstofone,獲取{221}參數,去掉括號並將其輸入到\f.這不會發生,我不明白為什麼。

答案1

您需要使用\makeatletter它才能工作,但這是最少的。

呼叫\ex{111}{221}首先擴展為

\f 111 - \expandafter\f\@firstofone{221}

Now\f被展開,它會尋找三個參數,尋找111,因為如果缺少大括號,TeX 將使用單一標記。

根據定義,\f它被擴展並且替換文字被重新插入到輸入流中:

1-1-1 - \expandafter\f\@firstofone{221}

代幣1-1-1 -不可擴展,因此它們被發送到下一階段。現在還剩下

\expandafter\f\@firstofone{221}

這將預留\f並展開\@firstofone,僅返回其(無括號參數),所以我們得到

\f221

那就變成了2-2-1。因此,您的程式碼的最終效果是列印

1-1-1 - 2-2-1

這似乎不太有用。無論你在哪裡發現它,都不要相信它。

答案2

正如egreg在他的回答中指出的那樣\@firstofone不是很有用,在這種特殊情況下沒有什麼區別。然而,也有這樣的情況有用。為了完整起見,我想舉兩個例子。

可擴充宏

為什麼\expandafter\@firstoftwo成語?給出了完全可擴展巨集的典型用例\@firstoftwo。,一種 LaTeX 的“恆等函數”,在僅應處理單一參數的類似上下文中很有用:\@secondoftwo\@firstofone

\def\gobbleIfZero#1{%
  \ifnum#1=0
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
}

foo\gobbleIfZero{0}{bar}

foo\gobbleIfZero{123}{bar}

會給

富巴

\@gobble(如\@firstofone)採用單一參數,但將其丟棄並擴展為“無”。

修復目錄程式碼

更棘手但也更有趣的是涉及catcode更改的情況。當 TeX 解析巨集的參數時,它會在讀取參數文字時修復catcodes。這對於您的情況並不重要,因為這裡沒有目錄程式碼變更。但假設給了以下一些人為的例子:

\begingroup
\catcode`4=\active
\gdef 4{four}
\endgroup

\newcommand*\f{\catcode`4=\active}
\newcommand*\exA{\f}
\newcommand*\exB{\expandafter\f\@firstofone}

{\exA{345}--{345}}

{\exB{345}--{345}}

這導致

3four5-3four5

345-3四5

前四行定義了一個4擴展為 的全域巨集four。通常4有catcode 12(其他),因此我們將其更改為13(活動)以便能夠從中建立巨集。\f執行時,此處將此巨集帶回作用域。

執行時\exA,catcode4改為 13,隨後使其4擴展到four以下兩組。這裡根本沒有參數,所以這很簡單。

另一方面,在\exB巨集中,第一{345}部分由\@firstofone僅傳回相同的文本,但修復了catcode412.一旦確定,就不能再更改了!即使catcode從\f已處理第一個345,不會對其產生任何影響。由於第二組的目錄程式碼{345}尚未修復,因此變更仍將適用於該群組。

如果您想將額外的程式碼注入處理 catcode 變更的現有巨集中,此行為會非常方便,例如\verb(靈感來自這顆 TeX 珍珠):

\begingroup
\catcode`\/\active
\catcode`\_\active
\@firstofone{%
  \verb|%
  \catcode`\/\active \def/{\par}%
  \catcode`\_\active \def_#1_{\textcolor{blue}{#1}}%
}_\documentclass_{article}/_\begin_{document}/  We all love _\LaTeX_!/_\end_{document}|
\endgroup

哪個輸出

輸出

我不知道你\@firstofone首先在哪裡讀到的,但它可能是在其中一個上下文中。

相關內容