> 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/22-how-tex-macros-actually-work-part-4.md).

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

[第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)

## はじめにと概要

第1〜3部では、TeX マクロの仕組みを理解する準備として、いくつかの低レベルな背景情報を詳しく見てきました。この記事では、第5部と第6部でさらに詳しく掘り下げる前に、TeX マクロの基本的な実用原則を確認するために、いったん「一息つき」ます。この記事を通して、TeX のプリミティブコマンドを使って定義したマクロの例を示します `\def`：おそらくよりおなじみの LaTeX コマンドは使いません `\newcommand`。これには非常にもっともな理由があります。私たちの目的は、TeX のマクロの振る舞いを支える基本原理を理解することですが、そのためにはコアコマンドを使う必要があります *に組み込まれた* TeX ソフトウェアです。LaTeX コマンド、たとえば `\newcommand`は、それ自体がマクロです。つまり、特定のプログラムされた振る舞いをもつコマンドであり、最終的には下位レベルの TeX プリミティブコマンドの層から構成されています。TeX の基本的な振る舞いをよりよく理解するには、LaTeX マクロではなく TeX プリミティブを使わなければなりません。

### 私たちはどこへ向かっているのか？

要するに、マクロを特殊なトークン列として説明する方向に進んでいます。TeX にマクロ定義を指示すると、TeX は一連のトークン（トークン列）を作成し、あなたが定義した名前に結び付けてそのメモリに保存します。第5部と第6部ではマクロのトークン列をかなり詳しく見ますが、もしこの記事から先に進んで背景情報を読みたいなら、こちらで見つけられます [TeX のトークン列とは何か？](/latex/ja/xiang-xi-ji-shi/54-what-is-a-tex-token-list.md)

マクロとその引数のトークン列には、いくつかの追加のひねりがあり、それを順を追って詳しく見ていきます――しかも例をたっぷり使って。TeX のマクロ処理の振る舞いをよりよく理解するために、実は覚えておくべき重要な点はただ一つです。TeX が文字について考えるのは、入力処理の最初期段階だけです。その時点以降は、ずっとトークンの世界なのです！ この回と、このシリーズの残りの記事を通して、TeX マクロにおけるトークンの役割を探っていきます。

## マクロの4つの部分

### おさらい：マクロのパラメータとマクロの引数

始める前に、マクロの *パラメータ* とマクロの *引数*、という違いを思い出しておく価値があります。この記事ではこの2つの用語を通して使うからです。たとえば、マクロ \foo を定義したとします

```
\def\foo#1#2{これは #1、これは #2}
```

構成要素（トークン）は `#1`, `#2` （〜まで `#9`）はマクロの *パラメータ*：マクロを呼び出すときに使う実際のデータの「プレースホルダー」だと考えてください：

```
\foo{alpha}{beta}
```

ここで、 `alpha` や `beta` は、 *引数* この \foo の呼び出しで使われる`#1`, `#2`... `#9`）に、マクロを定義したときのものです。

### マクロ定義：4つの要素を持つ

まず、やや形式的に見えるかもしれないマクロの定義から始めますが、これは後の議論のための有用な枠組みを与えてくれます。

どんなマクロ定義も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>` にはマクロのパラメータ（`#1`, `#2`... `#9`）や他の種類のトークンを含めることができます。要するに、そして詳しく見るように、その `<parameter text>` は一種の *トークンのテンプレート* であり、TeX がユーザーがどのトークンをマクロの引数として使いたいのかを判断するために用います。マクロを呼び出すと、TeX はその *引数* トークンをマクロの `<replacement text>` （これもトークン列です）へ渡します；
* `{<置換テキスト>}`：これがマクロの実際の本体です。これは一連のトークンであり、その中に *引数* が、マクロが処理（展開）されるときに「注入」されます。引数は、元の定義で使われたマクロパラメータによって示された位置に渡されます。

**注意**：この議論を通して、次のことを前提にしています `<macro name>` の後には、区切りとして機能してその終わりを示すために、カテゴリーコード10のスペース文字が続く `<macro name>`。 *明示的には* そのスペース文字を本文や説明の中で示してはいませんが、存在すると仮定しています。厳密には、次のように表すべきでしょう：

```
<TeX マクロのプリミティブ><マクロ名><スペース><パラメータテキスト>{<置換テキスト>}
```

しかし、 `<スペース>` 文字の明示的な記載は省き、その存在を暗黙に仮定します。

#### {} についての注記

ここでは2つの波括弧の使用を示しました： `{` や `}` これは、マクロの実際の本体を囲む（区切る）もので、 `<replacement text>`。 `{` や `}` は単に慣用的な決まりにすぎません。というのも、TeX が実際に期待しているのは、あなたのマクロのテキストが `<replacement text>` がカテゴリーコード1（「グループ開始」）の文字で始まり、カテゴリーコード2（「グループ終了」）の文字で終わることだからです。慣例として、それらは `{` や `}` それぞれの文字です。ただし、必要なら任意の文字の組み合わせをそれに割り当てることもできます。たとえば

```
\catcode`\(=1
\catcode`\)=2
```

これで、次のようにマクロを定義して使用できます：

```
\def\foo #1(こんにちは、#1)
\foo(World!)
```

そして、引き続き `{` や `}` を使うこともできます。なぜなら、文字のカテゴリーコードは変更していないからです。複数の文字が同じカテゴリーコードを持つことは可能であり、実際にそうなります。そのため、これまでどおり通常の方法でマクロを定義し続けることができます：

```
\def\foo #1{こんにちは、#1}
\foo{World!}
```

### と {}

私たちの議論に最も関係するマクロ定義の要素は `<parameter text>` や `{<置換テキスト>}`です。 `<parameter text>` は、実質的にはマクロの使い方を定める厳密なトークンテンプレートです。述べたように、 `<parameter text>` は空でもかまいません。たとえば `\def\foo{何らかのテキスト}` ここでは、コマンド名（`\foo`）と開き波括弧 `{` の間には何もありません。ここでは、この波括弧がマクロの `<replacement text>`.

**注**：TeX の「hashquote」機構（`#{`）についてご存じの読者もいるかもしれませんが、ここでは触れません。

### とマクロの区切り記号

この記事は、マクロの記述法を徹底的かつ包括的に総覧することを目的としたものではありませんが、いくつかの例を挙げて、簡単に復習しておく価値はあります。つまり、 `<parameter text>` は複雑になり得ます。なぜなら、TeX では `<parameter text>` に次のものを含めることができるからです：

* **マクロパラメータ**: (`#1`, `#2`,... `#9`）は、ユーザーがマクロを実行したときに提供する値の「プレースホルダー」として機能します。つまり、マクロの *引数*;
* **区切りトークン**：任意のトークンで、パラメータトークンの間や周囲に挿入され、マクロパラメータ間の境界を指定するために使われます。これらの区切り記号は、一種の「句読点」を形成して `<parameter text>` 、マクロを使うときに従う必要のある「トークンテンプレート」を作ります。区切りトークンは組版されません。

では、これは実際にはどういう意味でしょうか。いくつか例を見てみましょう。 `<parameter text>` は、マクロ名と左波括弧の間に置かれます `{` —つまりマクロ定義の

#### 区切り記号：例1

基本的なマクロを次のように定義するとします `\foo` ：

```
\def\foo ABC{こんにちは、そこです}
```

* `<parameter text>` = `ABC`
* パラメータトークン（`#1`, `#2`,... `#9`)
* 区切り記号は *3つの文字トークン* `ABC` ですが、この例ではやや冗長で、単に例として使われているだけです。

この3つの文字トークン `ABC` は区切り記号として扱われます。つまり、組版されるものではなく、マクロを呼び出したときに存在していることが期待される「句読点」です。マクロを使うときには `\foo` 定義時に存在していたのと同じ区切り記号を指定しなければなりません。

次のように入力すると `\foo ABC` 本文中では次のように組版されます `こんにちは、そこです`—文字トークン `ABC` は組版されませんが、TeX はあなたの呼び出しでそれらが確かに存在していることを、とても注意深く確認しました。 `\foo`。TeX はそれらの区切り記号（「句読点」）を探し、それらを取り除き（吸収し）ます。以下の Overleaf の画面画像でそれがわかります： `ABC` は組版されません：

![TeX マクロを実行している Overleaf](/files/cc03843c0d15ce78a006863350b4ca966c1e312c)

もし `\foo` なしで `ABC` 区切り記号がないと TeX はエラーを出します `\foo の使用がその定義と一致しません。`:

![Overleaf 上で TeX エラーを表示](/files/4d6132e5266f3f80b99ba58ebd21b880619b42dc)

上の例では、 `\foo` TeX は3つの文字トークンが見つかることを期待します `ABC` しかし見つかりません。代わりに、次の文字トークンが見えます `w` そして、すぐに何かがおかしいと検出します。

#### 区切り記号：例2

興味深く、おそらく驚くべき事実ですが、区切り記号は任意のコマンドトークンにすることができます。たとえば、 *まだ定義すらされていない*コマンドでもかまいません。たとえば、次のように定義できます `\foo` 次のように定義しています：

```
\def\foo A\bob B\anne{こんにちは \TeX{}}
```

* `<parameter text>` = `A\bob B\anne`
* パラメータトークン（`#1`, `#2`,... `#9`)
* 区切り記号はトークン `A\bob B\anne` ですが、この例でもやはり冗長で、議論のためだけに使っています。なお `\bob` や `\anne` は架空のコマンドであり、 *定義されていません*—そして、定義する必要もありません。

マクロを呼び出すと、TeX は `<parameter text>` そこに存在する *マクロ呼び出し中の* それを1トークンずつ「トークンテンプレート」版と比較します *メモリに保存された*—つまり、マクロが定義されたときに作成されたものです。TeX は *マクロ呼び出しで使われている* そして、そこにあるコマンドを単に数値のトークン値に変換するだけです。これらのコマンドを実行しようとしているわけではないので、 `\bob` や `\anne` が一度も定義されていなくても問題ありません。TeX は、メモリに保存されたトークンテンプレートを手がかりとして使い、次の中のどのトークンが `<parameter text>` あなたのマクロ呼び出しの中で実際に引数として渡されるのかを判断しています `<replacement text>`.

次の Overleaf の画面断片からわかるように、どちらの文字トークン（`ある` や `B`）も `A\bob B\anne` の中では `\bob` や `\anne` 組版されず、未定義のコマンド *は吸収されました* 。TeX は `\foo` の使用を `\foo` メモリに保存された定義（トークンテンプレート、トークン列）と照合しながら吸収したのです。

![TeX マクロを実行している Overleaf](/files/3c1e1f9521ae815f9b56227476a641dd3238dc29)

#### 区切り記号：例3

この例のように、さまざまな区切り記号（文字トークン、コマンドトークン）をマクロパラメータの間に挟むことができます：

```
\def\foo A\bob#1B\anne#2\jane#3bye!{こんにちは、\TeX{} から \#1=#1、\#2=#2、\#3=#3 へ}
```

* `<parameter text>` = `A\bob#1B\anne#2\jane#3bye!`
* マクロパラメータトークンは3つあります： `#1`, `#2`, `#3`
* 今回は、パラメータ（`#1`, `#2`, `#3`）が、次のトークンの組み合わせで区切られています：

  `A\bob#1B\anne#2\jane#3bye!`

ここでは、実質的に TeX にテンプレートを与えており、TeX はマクロを呼び出したときにそれに一致するかどうかを非常に注意深く試み、また一致することを期待します `\foo`：TeX はあなたのマクロ呼び出しを *トークンごとに*たどり、次のものが一致（発見）することを期待します：

* 2つのトークン `ある` や `\bob` より前に `#1`
* 2つのトークン `B` や `\anne` より前に `#2`
* トークン `\jane` パラメータの前の `#3` と *4つの文字トークン* `b`, `と`,`e` や `!` 後に `#3`.

**覚えておいてください**：TeX はトークンで考えるので `さようなら！` は *4つの文字トークン*.

このマクロの使い方には2通りあります。複数トークンからなる引数は、グループを作るために波括弧で囲むことができます：

```
\foo A\bob{これ}B\anne{それ}\jane{ほか}さようなら！
```

しかし、それは *必要ありません* なぜなら、マクロ定義にはトークンテンプレートを与える区切り記号があるからです。TeX はそのテンプレートを使って、純粋に区切り記号だけのトークンの中から各引数のトークンを取り出すことができます。マクロは次のように使えます：

```
\foo A\bob これB\anne それ\jane ほかbye!
```

すると、TeX は引数を取り出して、グループを使った場合と同じ結果を生成できます `{...}`:

![区切り記号を使って TeX マクロを実行している Overleaf](/files/877e36aab9c6b954e10207e2aeac2fd963aeb2ea)

TeX が、どのトークンがパラメータに一致するのかを正確に検出できたことに注目してください `#1` や `#3`:

![区切り記号を使って TeX マクロを実行している Overleaf](/files/1d342871263562b18956c6c7a76d2d89d7d180e6)

#### 区切り記号：例4（重要なのは文字ではなくトークンです！）

ここでは、マクロを扱うときには、私たちが本当に *トークン* や **実際の** *文字*…

区切り記号として機能する文字 A と B があり、どちらもカテゴリーコード 11 を持つ次の短いマクロを定義します。これは問題なく動作します：

```
\documentclass{article}
\begin{document}
\def\foo A#1B{こんにちは、#1}
\foo AGrahamB
\end{document}
```

と組版されます `こんにちは、Graham`.

しかし、A または B のカテゴリーコードを 11 以外に変更すると、マクロ呼び出しは失敗します。たとえば、B のカテゴリーコードを 12 に変更するとします。次のように ``\catcode`B=12`` して、以前と同じように再度マクロを呼び出そうとすると：

```
\documentclass{article}
\begin{document}
\def\foo A#1B{こんにちは、#1}
\foo AGrahamB % これは動作する
\catcode`\B=12\relax
\foo AGrahamB
\end{document}
```

やや不可解なエラーで失敗します：

```
途中で暴走した引数?
GrahamB \end {document}
! \foo の使用を走査中にファイルが終わってしまいました。
<inserted text>
                \par
<*> main.tex

}` を忘れたのではないかと思います。そのため私は
止めてほしかった場所を通り越して読み進めてしまいました。
復旧を試みますが、エラーが深刻なら、
今すぐ `E' か `X' を入力して、ファイルを修正したほうがよいでしょう。

! 緊急停止。
<*> main.tex

***（ジョブ中止、正しい \end が見つかりません）
```

![TeX マクロエラーを表示している Overleaf](/files/5be0877ef621f78daf18681d6b651aef0ee1964b)

残念ながら、TeX の既定の提案である ``}` を忘れたのではないか`` は **は不正確です**。これは波括弧の不足（`}`).

#### 何が起きたのでしょうか？

TeX は次のものに一致させようとしています `\foo` マクロも使います *呼び出し* を `\foo` マクロも使います *definition* メモリに保存したものと照合しています。1つ以上の引数を必要とするマクロを呼び出すとき、TeX はそのマクロの使い方を調べ（走査し）、次のものを判断しなければなりません *引数* あなたがそのマクロに渡しているものです。ここでは、TeX は引数が A（カテゴリーコード 11）と B（カテゴリーコード 11）に挟まれていることを期待しています。忘れないでください：TeX は *トークン*, **実際の** *文字*.

A と B のトークン値は、 $$\mathrm{T\_A}$$ や $$\mathrm{T\_B}$$ それぞれ次のとおりです：

$$\mathrm{T\_A = 256 \times 11 + 65 = 2881}$$ $$\mathrm{T\_B = 256 \times 11 + 66 =2882}$$

しかし、TeX が探索を続けると B が見つかります *しかし* が、今はカテゴリーコード 12 なので、別のトークン値になります：

$$\mathrm{T'\_B= 256 \times 12 + 66 =3138}$$

その `\foo` マクロ定義では、B のトークン値（区切り記号として使用）は 2882 でしたが、TeX には今 3138 のトークン値が見えています。TeX は、これはただの別のトークンであり、 *引数* に渡される `\foo`引数で使われるものだと考えています。TeX にとっては、引数の最後のトークンはまだ見つかっていないので、カテゴリーコード 11 の B を探すためにさらに別のトークンを取得しに行きます。これが、そしてこれこそが、マクロが失敗する理由です。引数を見つけようとする過程で、TeX は「行き過ぎて」しまい、 `\foo` あなたがその引数の一部にするつもりではなかったトークンまで読み始めてしまいます。次に何が起こるかは、B の後に TeX が見つけるトークン次第です。そこからさまざまな `途中で暴走した引数?` エラー

この例では、TeX は行き過ぎてトークン列 `\end {document}` を消費し、すぐにファイルの終わりに達するため、エラーメッセージが出ます：

```
! \foo の使用を走査中にファイルが終わってしまいました
```

## 第5部

上で見たように、 `<parameter text>` マクロ定義の部分は、非常に単純なものから、区切り記号として機能する文字トークンやコマンドトークンが挟み込まれた複雑なマクロパラメータの混在まで、さまざまです。TeX は、次の中に含まれるトークンのさまざまな組み合わせを処理して `<parameter text>` マクロに渡された引数を抽出し、さらにマクロを誤って使おうとしたときにそれを検出できます。その仕組みは、このシリーズの次の記事で扱います。

[第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/22-how-tex-macros-actually-work-part-4.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.
