> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/ja/xiang-xi-ji-shi/17-how-does-expandafter-work-a-detailed-macro-case-study.md).

# \expandafter はどのように動作するか：詳細なマクロ事例研究

&#x20;[第1部](/latex/ja/xiang-xi-ji-shi/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [第2部](/latex/ja/xiang-xi-ji-shi/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [第3部](/latex/ja/xiang-xi-ji-shi/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [第4部](/latex/ja/xiang-xi-ji-shi/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [第5部](/latex/ja/xiang-xi-ji-shi/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [第6部](/latex/ja/xiang-xi-ji-shi/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)&#x20;

## ケーススタディ: \expandafter を用いた The の例 $$\varepsilon\mathrm{\text{-}{\TeX}}$$ マニュアル

その $$\varepsilon\mathrm{\text{-}{\TeX}}$$ 組版エンジンはクヌースの TeX ソフトウェアから派生したもので、当初は「暫定的な」段階として、その開発に向けて意図されていた [新組版システム](https://en.wikipedia.org/wiki/New_Typesetting_System) （NTS）であり、Java プログラミング言語で書かれている。 $$\varepsilon\mathrm{\text{-}{\TeX}}$$ は、Knuth の元のプログラムでは利用できない追加機能を提供する一連の新しいプリミティブ命令を加えるために、1990年代後半に最初に開発された。 $$\varepsilon\mathrm{\text{-}{\TeX}}$$ は初版リリース以来、定期的に更新されてきたが、今日では独立した組版エンジンとして広く使われているわけではない。ただし、その革新は後の世代の TeX、すなわち pdfTeX、XeTeX、LuaTeX に取り込まれている。

その [$$\varepsilon\mathrm{\text{-}{\TeX}}$$ manual](http://mirror.ox.ac.uk/sites/ctan.org/systems/doc/etex/etex_man.pdf) には、\expandafter を巧妙に利用したマクロの示唆に富む例が含まれている `\expandafter`:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter\foo
    \expandafter{\number\numexpr#1+1\expandafter}%
    \expandafter{\number#2\expandafter}%
    \fi}
```

`\foo` 反復機構を実装しており、たとえば `\foo{7}{13}` を生成する。 `7, 8, 9, 10, 11, 12, 13`しかし、 `\foo` いかなる *変数への代入も* 行わずにループ処理を制御している。これは、もう少し詳しく見てみる価値のある興味深いマクロである。

### 背景: 式と代入

のコードにおける重要な要素の1つは、コマンド `\foo`の使用である `\numexpr`。これは、 $$\varepsilon\mathrm{\text{-}{\TeX}}$$: `\numexpr`, `\dimexpr`, `\glueexpr` と `\muexpr`によって最初に導入された、相互に関連する4つのプリミティブからなるセットの1つである。これらの目的は、いわゆる *式* を構築することにある $$\varepsilon\mathrm{\text{-}{\TeX}}$$ マニュアルの8〜9ページで論じられているように、 *式* の重要な特徴は、その評価（計算）に TeX が何らかの *代入*.

を行う必要がないことである。プログラミング用語では、代入とは、変数に特定の値を持たせる（割り当てる）処理である。たとえば、 `\count` レジスタ `99` に値を `12345` 〜を介して `\count99=12345`。TeX の処理中には、トークンレジスタにトークン列を入れたり、ボックスレジスタにボックス内容を入れたりといった、多くの種類の代入が行われる。

たとえば `\count99=12345`のような代入を行うには、TeX は `\count` あるいは、何らかの代入を行う他のプリミティブの動作を実装する内部コードを実行する必要がある。しかし、TeX が純粋な *展開* を行っているときには、そうした代入は実行されず、*TeX の処理のその時点では*。この状況の例としては、次のコマンドがある。

* `\edef\command {*token list*}` トークンを展開する「展開済み定義」のマクロ定義コマンドで、 *トークンリスト* 内のトークンを展開し、その結果を `\command`.
* `\write *number* {*token list*}` 内のトークンを展開し、 `*token list*` で表されるファイルへそれらを書き出す `*number*`.
* `\directlua {*token list*}` この LuaTeX のプリミティブコマンドは、Lua コードを組み込みの Lua インタプリタに渡すために使われる。 `*token list*` 内のすべてのトークンは、実行のために Lua インタプリタへ渡される前に完全に展開される。

#### \edef の簡単な例

次の基本マクロを書くとする：

```
     \def\mycount{\count99=12345}
     \edef\mymacro{\mycount}
```

`\edef` は展開される `\mycount` をその構成トークンにまで展開するが、それ以上は進まない。定義の中に含まれるコマンドはどれも `\mymacro` は実行されない。つまり、 `12345` を `\count99` *の代入はこの時点では起こらない*。その代入が行われるのは、TeX が `\mymacro` を処理するコードを実行するときになってからである。TeX が `\count` プリミティブを処理しているときに。 *展開のみの処理* を行っている間に代入が行われることはなく、代入は TeX の処理の後の段階で実行される。

#### なぜここで代入が重要なのか？

ループを実行するコードを書くときは——どのプログラミング言語でも同じだが——ループの実行回数を制御するために「ループカウンタ」として働く変数を用意するのが一般的である。ループ処理は通常、その指定したループカウンタ変数が特定の値に達したかどうかを調べることで制御される。その変数は、ループの各反復ごとにインクリメント（またはデクリメント）される。しかし、ループカウンタ変数を変更するということは、新しい値を代入することを意味し、TeX では通常、プリミティブコマンド `\advance` に格納された値をインクリメント（またはデクリメント）するために `\count` レジスタ。 `\foo` はこの制約を巧妙に回避している。

### \foo の説明に戻る

このマクロは `\foo` ループ処理を制御することができる *ことなく* 、いずれの変数にも値を代入する必要がない。展開から生じるデータ、すなわち一時的なトークンリストに保存されたデータ値を使って、ループが何回起こるかを制御しているのである。TeX が一時的なトークンリストをどのように使う（生成する）かについての知識を活かせば、どのように `\foo` その結果を実現しているのかを詳しく見ることができる。

**覚えておこう**：私たちは、定義の元のテキスト—物理的な `.tex` ファイル—がスキャン（TeX による読み込み）され、マクロ定義を表すトークンリストに変換された後の、マクロの実行を追っている。要するに、私たちは TeX のメモリのどこかにある、その保存された *トークン* を、TeX がマクロ定義の中のトークンを読み取り処理している様子に沿って追っているのである。マクロ定義の TeX コードに元々あった空白文字（ `.tex` ファイル）内のテキスト）は、TeX がそのテキストをコマンドとして走査している間に吸収される（空白は終端記号として）か、あるいはカンマの後ろの空白文字（`,`）のようにトークンへ変換されている。 `\ifnum#1<#2,` これは行末文字（`\r`）を空白に変換したことで生じたものである。

TeX コードでは `\foo` 複数の `\expandafter` コマンドを使っているので、説明しやすいようにそれぞれの `\expandafter`に下付き文字を付け、どれを指しているのかを示す。さらに、 `\expandafter` を $$\mathrm{T^i\_1}$$ と $$\mathrm{T^i\_2}$$によって処理されるトークンの表記を拡張し、 $$\mathrm{T\_1}$$ と $$\mathrm{T\_2}$$ を `\expandafter<sub>i</sub>`: `\expandafter<sub>i</sub>` $$\mathrm{T^i\_1T^i\_2}$$

注釈付きのマクロコードは次のとおり：

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}％
    \expandafter4{\number#2\expandafter5}％
    \fi}
```

`\foo` は次で始まる `\number#1` これは展開可能なコマンド `\number` を使って第1引数の値を組版表現に変換する。 `\number` コマンドは、ある数値に含まれる各桁を表す文字トークンを含む一時的なトークンリストを生成することで動作する。 `\number` が処理対象としている。そのトークンリストが TeX の次の入力ソースになる。ここでは、そのトークンリストが読み込まれ、トークンが出力されて、 `#1`.

次に、このマクロは次のテストを行う `\ifnum#1<#2` 〜の引数が `#1` に渡された引数より小さいかどうかを確認するために `#2`。`,`)`,`）である。その空白文字は、TeX がこの行を `.tex` ファイルから読み込んだときに最初に生成された。

このマクロは次のコード部分を処理し続ける。ここが動作の核心である：

```
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}％
    \expandafter4{\number#2\expandafter5}％
    \fi}
```

要するに、このコードは複数の一時的なトークンリストを生成し、その結果として `\foo` マクロへの複数回の呼び出しを生み、if テストが `\ifnum#1<#2` もはや真でなくなったときに終了する。だが、 *どのように* 代入が行われていないのにループはどのように制御されているのか。いったい「ループカウンタ」はどこにあるのか？

まずはコードを見てみよう `\expandafter<sub>1</sub>\foo\expandafter<sub>2</sub>`。 `<sub>token</sub>` （または `<sub>(token)</sub>`）は、ここで TeX が数値（整数）のトークン値を読み取り／処理していることを思い出すためのものだ。

ここでは、次のトークンが `\expandafter<sub>1</sub>`:

* $$\mathrm{T^1\_1} =$$`\foo<sub>token</sub>` は読み込まれて後で *再挿入* して入力に戻す
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>2 (token)</sub>` 展開される

については `\expandafter<sub>2</sub>` 結果は次のとおり：

* $$\mathrm{T^2\_1} =$$`{<sub>token</sub>` これは後で使うために保存され *再挿入* して入力に戻す
* $$\mathrm{T^2\_2} =$$ `\number<sub>token</sub>` 展開される

**注：**`\number` は展開可能なコマンドで、その目的は「トークンに変換する」こと、つまり数値をそれを表す一連の文字トークンに変換することである。 `\number` それが展開されると、TeX が最初に行うのは入力を走査して整数を探すことであり、その過程がさらなる展開を引き起こす。

**この話の鍵は：** ここで、 `\number` は〜に対して作用している *式* `\numexpr#1+1` これは〜の値を計算する `#1+1`。 `\number` それを、〜の値を表す文字トークンを含む一時的なトークンリストに変換するために `#1 + 1`。 `\number`によって生成された、その一時的なトークンリストは、 `\foo`への別の呼び出しの第1引数として最終的に読み込まれることになる。ループカウンタを（ `\advance` および代入 `\numexpr` で）インクリメントする代わりに、`\foo`のパラメータ `#1`）がインクリメントされ、ループの反復が制御されて終了する。なんとも巧妙だ！

次に、 `\expandafter<sub>3</sub>` が処理され、次が得られる：

* $$\mathrm{T^3\_1} =$$`}<sub>token</sub>` これは後で使うために保存され *再挿入* して入力に戻す
* $$\mathrm{T^3\_2} =$$`\expandafter<sub>4 (token)</sub>`、これは展開される：

については `\expandafter<sub>4</sub>` 結果は次のとおり：

* $$\mathrm{T^4\_1} =$$`{<sub>token</sub>` これは後で使うために保存され *再挿入* して入力に戻す
* $$\mathrm{T^4\_2} =$$`\number<sub>token</sub>` これは展開され、 `#2` 別の一時的なトークンリストへ変換する。

最後に、`\expandafter<sub>5</sub>` が展開される：

* $$\mathrm{T^5\_1} =$$`}<sub>token</sub>` これは後で使うために保存され *再挿入* して入力に戻す
* $$\mathrm{T^5\_2} =$$`\fi<sub>token</sub>`。これは展開可能なコマンドである。

  〜の展開は `\fi` 実質的に〜を終了させ `\ifnum` 、実質的にはこのマクロのこの反復を閉じる。TeX は今、複数の `\expandafter` コマンドによって一時保存されたトークンをもとにした、単一トークンのトークンリストの系列を生成する。 `\expandafter`さらに TeX は、 `\number`.

### トークンリストの組み立て

要するに、 `\foo` マクロはトークンリストの連続を生成する。 `\foo` トークンリストの「製造工場」と考えることができる。これらのトークンリストは TeX に読み込まれて次の入力ソースになる。巧妙な部分は、先に行われた `\foo`:

```
    \expandafter1\foo\expandafter2
```

これによって `\foo` 自身を再び呼び出すようにしつつ、 `\number`。 `{` と `}` これらのトークンリスト全体をマクロ呼び出しとして振る舞わせるために、波括弧 `\expandafter` はすべて保存され、

![\foo マクロによって生成されたトークンリスト](/files/a0cf89587a08df00028c8d8d5e5486ba549bcac6)

&#x20;[第1部](/latex/ja/xiang-xi-ji-shi/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [第2部](/latex/ja/xiang-xi-ji-shi/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [第3部](/latex/ja/xiang-xi-ji-shi/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [第4部](/latex/ja/xiang-xi-ji-shi/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [第5部](/latex/ja/xiang-xi-ji-shi/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [第6部](/latex/ja/xiang-xi-ji-shi/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/ja/xiang-xi-ji-shi/17-how-does-expandafter-work-a-detailed-macro-case-study.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
