
私はこの回答に目を通し、コードを理解しようとしていました。私は LaTeX の超初心者 (2 日目) で、コードの次の部分で行き詰まり、テーブル環境以外では動作させることができませんでした。私が理解できないことの最も単純な形は次のとおりです。
\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}
ここで\f
が展開され、 、 という 3 つの引数が検索されます。1
これ1
は1
、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
あまり役に立たず、この特定のケースでは違いはありません。しかし、それが役立つ場合もあります。は便利です。完全を期すために、2 つの例を挙げたいと思います。
拡張可能なマクロ
でなぜ\expandafter\@firstoftwo
慣用句なのですか?\@firstoftwo
完全に展開可能なマクロでのとの典型的な使用例\@secondoftwo
を示します。 は\@firstofone
、LaTeX の「恒等関数」の一種であり、単一のパラメータのみを処理する同様のコンテキストで役立ちます。
\def\gobbleIfZero#1{%
\ifnum#1=0
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
}
foo\gobbleIfZero{0}{bar}
foo\gobbleIfZero{123}{bar}
あげる
フー
フーバー
\@gobble
( のように\@firstofone
) は単一のパラメータを取りますが、それを破棄して「nothing」に展開します。
カタログコードの修正
もう少しトリッキーですが、より興味深いのは、catcode の変更が関係する場合です。TeX がマクロの引数を解析しているとき、引数テキストが読み取られるたびに catcode を修正します。ここでは catcode の変更がないため、これは問題になりません。ただし、次のようなやや不自然な例があるとします。
\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-3four5
4
最初の 4 行は、 に展開されるグローバル マクロを定義しますfour
。通常は4
catcode 12 (その他) なので、マクロを作成できるように 13 (アクティブ) に変更します。\f
ここでは、実行時にこのマクロをスコープに戻します。
が実行されると\exA
、 の catcode は4
13 に変更され、その後、次の 2 つのグループの両方で4
に展開されますfour
。ここにはパラメーターがまったくないため、これは簡単です。
一方、\exB
マクロでは最初の部分は同じテキストを返すだけ{345}
で処理されます。\@firstofone
しかし、catcodeを修正します12に変更します4
。一度修正すると、変更できなくなります。catcodeの変更が\f
処理されても前に最初のグループ345
には影響はありません。2 番目のグループの catcodes は{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
そもそもどこで読んだのかはわかりませんが、おそらくこれらのいずれかの文脈で読んだのでしょう。