> 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/sononotopikku/24-how-tex-macros-actually-work-part-6.md).

# TeXマクロは実際にどのように動作するのか: 第6部

[第1部](/latex/ja/sononotopikku/19-how-tex-macros-actually-work-part-1.md) [第2部](/latex/ja/sononotopikku/20-how-tex-macros-actually-work-part-2.md) [第3部](/latex/ja/sononotopikku/21-how-tex-macros-actually-work-part-3.md) [第4部](/latex/ja/sononotopikku/22-how-tex-macros-actually-work-part-4.md) [第5部](/latex/ja/sononotopikku/23-how-tex-macros-actually-work-part-5.md) [第6部](/latex/ja/sononotopikku/24-how-tex-macros-actually-work-part-6.md)

## 導入と概要: これまでの話

この連載の前の5回で見てきたのは:

* TeXが入力ファイル内の文字をどのように読み取り、カテゴリコードを使って文字のさまざまな「クラス」を認識し、その後それらを文字トークンやコマンドトークンに変換するか；
* マクロは、実質的には4つの部分から成ること：

```
<TeX macro primitive><macro name><parameter text>{<replacement text>}
```

次のとおりです：

* `<TeX macro primitive>` = 次のいずれか `\def`, `\edef`, `\gdef` または `\xdef`;
* `<macro name>`= マクロの名前。たとえば `\foo`;
* `<parameter text>` は「空」（存在しない）こともあれば、区切りトークンとマクロパラメータトークンの文字列であることもあります。
* `<replacement text>` これはマクロの実際の本体であり、マクロを呼び出したときに「実行」(展開)される部分です。
* どのように `<parameter text>` 部分は幅広いトークンを含めることができ、TeXがこの部分を「トークンテンプレート」として使ってマクロ呼び出しを元の定義に照合し、マクロで使われる引数を割り出すこと—そしてTeXが、マクロの使い方が元の定義に一致することを期待していること；
* TeXの内部では、マクロ定義は `<parameter text>` や `<replacement text>` 部分を表すトークンの連続した並びとして保存されていること。

マクロコマンドを使うと、TeXはまずそれがパラメータを持つかどうかを確認します。もしあれば、TeXは実際の *引数* がマクロ呼び出しで使われているものを特定しなければなりません。TeXは、メモリに保存されたそのマクロの「トークンテンプレート」定義とマクロ呼び出しを照合しなければなりません。具体的には、TeXはマクロの `<parameter text>` 部分の内部保存された定義をテンプレートとして使い、そこから *トークン* を取り出せます。 *トークン* それらは実際の引数であり、ただの区切り文字として存在しているだけのものです。

## マクロ展開の意味

さあ、ついに最も重要な話題に進む準備ができました。TeXがマクロ引数をどのように処理し、実際にマクロを実行するのか、そのプロセスをTeXでは *マクロ展開*.

### と呼びます。

TeXがマクロとその引数を処理する仕組みを説明するための「場を整える」ために、考えるべき मुद्देを示す短い例を使いましょう。

#### 引数はまずトークンに変換される

次の例は、 [The Advanced TeXbook](https://www.amazon.co.uk/Advanced-Texbook-David-Salomon/dp/0387945563) の114〜115ページで取り上げられている例に基づいています。これは、非常に短いTeXマクロの中に中心的な考え方をうまく凝縮しているからです。

通常のTeX/LaTeXの操作では、 `$` $ 記号はカテゴリコード3（「math shift」）を持ち、TeXを行内数式モード（`$...$`）またはディスプレイ数式モード（`$$...$$`）のオン/オフに切り替えます—もちろんLaTeXでは `\(..\)` や `\[..\]` が同じ目的で使われます。

たとえば、 `$` $ 記号のカテゴリコードを11に変えて、通常の文字と同じように組版できるマクロが欲しいとしましょう。TeXの基本コマンド `\catcode` を使うことができ、そのようなマクロの最初の試み `\docat`は、次のようになるかもしれません。

```
\def\docat #1{\catcode`\$=11 #1}
```

しかし、これを使ってみると、たとえば次のように

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
私はその本に \docat{$90} を支払った。
\end{document}
```

とTeXに組版されることを期待しますが、 `その本に90ドル払った。` となるはずが、エラーメッセージで失敗します:

```
! $ が挿入されていません。
<inserted text>
                $
<to be read again>
                   \par
l.7
```

エラーから見ると、 `$` マクロの引数で使われている記号が、依然としてTeXに数式組版を行わせているようです。明らかに、TeX *しませんでした* マクロの引数中で使われている `$` 記号のカテゴリコードを変えませんでした（`$90`）。問題は *なぜでしょうか* なぜTeXは `$` のカテゴリコードを11に変えて、通常の文字として組版しなかったのでしょうか。短く言うと、TeXはまずマクロ引数をトークンに変換し **より前に** それらを `<replacement text>`のトークンリストに送り込むからです—ただし、その基礎的な仕組みはもっと詳しく見ていきます。

ここで覚えておくべきなのは、TeXがテキスト/文字を使うという私たちの考え方は、TeXが読んでいるファイルの内容にのみ関係するということです。いったんTeXが文字を読み込んでしまえば、私たちは *トークン*トークンの世界 *トークン*ではなく、実際の *書き表された* TeX/LaTeXコマンドを扱います—例を追ううちに、これはより明確になるでしょう。

最初は、 `\docat` マクロを `私はその本に \docat{$90} を支払った。` 使うのは、次のような同等のTeX（またはLaTeX）コードを直接書くのと同じだと思うかもしれませんが、 *は* うまくいきます:

```
\begin{document}
I paid \catcode`\$=11 $90 for that book.
\end{document}
```

![Overleaf上で実行されるTeXコードの例](/files/5d20926da63cfd7ac738f6586ad1c58cea0da04c)

しかし、上で見たように、TeXがマクロ引数を処理する方法は、TeXコードを書き出すのとはかなり異なる結果（`! $ が挿入されていません。`）を生みます。これから *なぜでしょうか* その点を見ていきます。

### マクロと引数をトークンリストとして見る

の振る舞いを完全に理解するには、 `\docat` マクロ`$90`とその引数（ `\docat` ）がなぜ失敗するのかを理解するには、 *トークンのリスト*として、文字列の並びではなく見直す必要があります。

TeXが入力テキストを走査すると、 `\docat` をマクロコマンドとして認識します。その後、それがパラメータを取るかどうかを確認します—TeXがそれをどう行うかは、細部に興味のある読者向けに次の節で説明します。

#### 細部が好きな方へ...

マクロが呼び出された後、TeXは（マクロの保存された定義トークンリストの中の）最初のトークンが **終端一致** トークン

**例**

次のノードリスト図は、2つのマクロのトークンリストを比較しています:

* `\def\foo A#1B{#1}`：これは `<parameter text>` のトークン値は次のようになります。 `A#1B`があるので、したがって **終端一致** トークンは **実際の** 最初のトークンなので、TeXは引数を探し始めます；
* `\def\foo{X}`：これは `<parameter text>` 部分がないので、その結果 **終端一致** トークンがトークンリストの最初のものであり、TeXは引数を探さないと分かります。

![TeXがマクロに引数があるかを確認する方法](/files/913d1b1eefb3768460c99017753324bfb4f1578d)

## 「グランドフィナーレ」に向けて: 展開

質問を思い出しましょう。なぜ次のマクロはうまくいかなかったのでしょうか。つまり、なぜTeXは `$` 記号が `\docat` マクロの引数で使われていると、たとえば `\docat{$90}`?

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
私はその本に \docat{$90} を支払った。
\end{document}
```

上で説明したように、TeXが入力を走査してマクロコマンドを認識し—それを実行しようとする時点で—TeXはまずそのマクロがパラメータを取るかどうかを確認します。もし取るなら、TeXは入力ファイルをさらに走査して実際の *引数* ユーザーがこの特定のマクロ呼び出しに対して与えたものを特定しなければなりません。TeXはそれを **より前に** 行う前に、実際のマクロコードを呼び出せるようにします。明らかにTeXは、ユーザーがマクロに渡したいデータを特定する必要があります。

入力中に存在する引数（ユーザーのマクロ呼び出し）を特定するために、TeXはそのマクロの内部保存された定義に導かれます。具体的には、 `<parameter text>` 部分が、ある種の「トークンテンプレート」を提供します。その「トークンテンプレート」を使ってTeXは、ユーザーのマクロ呼び出しのどの *トークン* トークンがただの *区切り記号を* （実質的には「句読点」）であり、どの *トークン* ものが *引数*の一部を成しているのかを判断しなければなりません。TeXが保存されたマクロ定義の **match parameter** トークンに出会うと `<parameter text>` 部分（「トークンテンプレート」）では、 *トークンのリスト* をその特定の引数について形成し始めることが分かります。

TeXがユーザーの引数を特定する必要があると認識すると、入力を走査してトークンを生成し、保存されたマクロ定義と一つ一つ慎重に照合します。TeXは引数のためにトークンを集め続け、実際に区切り文字であるトークンを検出するか、あるいは **終端一致** トークンを検出するまで続けます。どちらの場合でも、その引数の一部を成すトークンを探すのをやめる時だとTeXは分かります。

### \docat マクロが失敗した理由

述べたように、 *より前に* TeXが実際にマクロを呼び出すためには、そのマクロで使う引数を特定し準備しなければなりません。しかし、引数を特定してマクロに渡す準備をするために、TeXは各引数を *トークンのリスト*として生成しなければならず、それが `\docat`の失敗の理由です。

この例では、 `\docat` に引数として `$90` 与えましたが、その引数はまず *トークンのリストに変換され* ます—引数は *より前に* マクロが実際に呼び出される前にトークンへ変換されるのです。ここでは、引数 `$90`について、TeXは3つの文字トークンを生成します： `$`, `9` や `0`.

次の図は、引数 `$90`に対して生成されたトークンリストを示しており、それが `\docat` マクロ:

![マクロ引数に対して生成されたTeXトークンリスト](/files/6acd3fc459fbf5afcdc2b2b540e6f19ee1e44345)

上の図では、引数のトークンリストに `$` がカテゴリコード3に基づく文字トークンとして含まれていることがはっきり分かります。

パート1〜3で見たように、文字トークンは、文字が読み込まれた時点で有効なカテゴリコード値を使って作成されます *—つまり、引数のトークンリストが作成される（トークンへ変換される）時点です。引数がトークン化されている時点では、*&#x30DE;クロはまだ実行されていないので、マクロ呼び出しの中に入れたカテゴリコード変更（ `\docat` ）は、``\catcode`\$=11``) *終了しません* ことはありません。

TeXが `$90`の引数を表すトークンリストを生成すると、その3つの文字トークンが実際のマクロ `<replacement text>`に渡されます。しかし、その結果として `$` が *文字トークン* として渡されることになります。 `$` は *実際の* マクロに渡される *文字*ではなく、 *文字トークン* それに基づく `$` カテゴリコード3を持つ

### &#x20;\docat の実行: マクロ展開

TeXはマクロを「実行」するこのプロセスを *マクロ展開*と呼びます。これは本書の著者の意見では少し紛らわしい用語ですが、慣用的な用語なのでそのまま使い続けます。

#### マクロ展開の本当の意味

TeXが `\docat` コマンドをユーザーの入力から検出した後、引数を走査して、その引数(`$90`)のトークンリストを生成します。マクロを実行（展開）するために、TeXはユーザーの入力ファイルから視線をそらし、TeXのメモリに保存された `\docat`のノードリストでは、 `<replacement text>` トークンリストの中を読み始めます。

TeXが `\docat`の定義を処理すると、もともとマクロを定義するために使われたトークン列（`**カテゴリコード**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**#1**`).

次の図は、 `\docat` マクロ：TeXは入力ファイルからトークンを取得するのをやめ、 `<replacement text>` 部分から `\docat` メモリに保存されたマクロ定義の。TeXは、ある **出力パラメータ** トークンに出会うまで、これらの事前準備されたトークンを実行し続けます。そのトークン `$90` を表す3つの文字トークンです。そしてその結果、 `$` 用に事前に準備された文字トークンがカテゴリコード3を持っているためエラーになります。文字トークンを扱っているのであって文字そのものを扱っているのではないため、 `$` は、 ``\catcode`\$=11``.

![\docat マクロを展開するプロセスを示す](/files/b7b20b6f21bc0befa18975a73d573aa8c6b663f7)

TeXが ``\catcode`\$=11``を表すトークンを処理した後、 `$` のカテゴリコード変更が **出力パラメータ** 有効になります。するとTeXは **挿入します** という「特別なトークン」に遭遇し、それがTeXに *トークン*のトークンリストを `$` トークンであり、その最初のものは

### \docat マクロを修正できるか？

上の議論から、マクロ引数に現れる文字は、トークン化が行われる時点で有効なカテゴリコードを使ってトークン化されることが明らかです—この例では、それは *常に* 前 `<replacement text>` におけるパラメーターを含みます `\docat` に

一つの方法は、 `\docat` を、カテゴリコード変更だけを行うパラメータなしマクロにすることです—トークン化すべき引数は持ちません。そこで次に第二のマクロ `\getarg`を使います。これは1つのパラメータを取り、そのマクロの引数が `$` が有効になっているときにトークン化されるようにします。

```
\begin{document}
\def\docat{\catcode`\$=11 \getarg} % パラメータなし、第二のマクロ \getarg を呼び出す
\def\getarg#1{#1} % 引数がトークン化される1個のパラメータ
これで、次のように実行でき、うまくいきます:

私はその本に \docat{$90} を支払った。
\end{document}
```

新しい版の `\docat` を使うと（こんなふうに `\docat{$90}`）、 *あたかも* がまだ `$90` の引数として使われているかのように見えます。しかし、上で述べたように、TeXが入力中に `\docat` を検出すると、引数を持つかどうかを確認します。今回は持っていないので、TeXはそのまま実行（展開）します。 `\docat` の展開 `\docat` は、トークン列 `**カテゴリコード**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**空白**`, `**getarg**` であり、これは *より前に* TeXが入力ファイル中の次の文字を読み込み（トークン化し）始める前に起こります—つまり、 `{$90}`というグループです。TeXがマクロを展開するとき、次の入力はそのマクロ定義のトークンリストに含まれるトークンを読むことによって得られることを思い出してください。つまり、メモリに保存された `<replacement text>` 部分からです。

TeXは `\docat` の展開を処理し、実行して *トークン* **`を検出します。`**&#x3092;、パラメータを取るコマンドを表すトークンとして認識するのです。この時点でTeXは入力ファイルを走査して **`を検出します。`**&#x306E;引数を探します：文字 `{$90}`。通常どおり、これらはトークン化されますが、TeXが `\docat`の展開を読み取り処理したので、文字 `$90` は、 `$` のカテゴリコードが11に変わった状態でトークン化されます。`<replacement text>`）の `\getarg` は単に `#1` であり、これは与えられた引数を組版することを意味し、そうなることで、カテゴリコード11を持つ `$` が生成され、安全に組版されます。

## 結びのコメント: ノードで見る話

を書き換えて `\docat` マクロを使うようにした結果生じる一連の出来事は、次の注釈付きノードリスト図にまとめられており、そこではマクロ `\getarg` の展開過程が示されています。図をじっくり研究したい読者は、グラフィックを `\docat`としてダウンロードできます。 [PDF](https://assets.ctfassets.net/nrgyaltdicpt/7MOBdavza4WxAEQGISEEht/cabe5097d9063a6415bc553cd38237e6/newdocatexpansion.pdf) または [SVG](https://images.ctfassets.net/nrgyaltdicpt/2FIqqVRXjakdAzTpZsV0m9/10ccc1353741d42d3df18f1692d8aa84/newdocatexpansion--plain.svg) ファイル

![修正版 \docat マクロと \getarg マクロの展開プロセスを示す](/files/01e222af326e2926bacd19f75e60c80bb7d48380)

[第1部](/latex/ja/sononotopikku/19-how-tex-macros-actually-work-part-1.md) [第2部](/latex/ja/sononotopikku/20-how-tex-macros-actually-work-part-2.md) [第3部](/latex/ja/sononotopikku/21-how-tex-macros-actually-work-part-3.md) [第4部](/latex/ja/sononotopikku/22-how-tex-macros-actually-work-part-4.md) [第5部](/latex/ja/sononotopikku/23-how-tex-macros-actually-work-part-5.md) [第6部](/latex/ja/sononotopikku/24-how-tex-macros-actually-work-part-6.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/sononotopikku/24-how-tex-macros-actually-work-part-6.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.
