> 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/zh-tw/shen-ru-wen-zhang/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md).

# \expandafter 如何運作：TeX 詞元簡介

[第 1 部分](/latex/zh-tw/shen-ru-wen-zhang/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [第 2 部分](/latex/zh-tw/shen-ru-wen-zhang/22-how-does-expandafter-work-the-meaning-of-expansion.md) [第 3 部分](/latex/zh-tw/shen-ru-wen-zhang/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [第 4 部分](/latex/zh-tw/shen-ru-wen-zhang/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [第 5 部分](/latex/zh-tw/shen-ru-wen-zhang/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [第 6 部分](/latex/zh-tw/shen-ru-wen-zhang/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)

## \expandafter 的背景：TeX token 與 token list

作為理解……如何運作的第一步 `\expandafter` 的真正運作方式，我們先來看看 TeX 的兩個基本組成部分，它們對……的運作至關重要 `\expandafter`：TeX tokens（整數）與 token list（整數列表）。想更深入探討這些主題的讀者，可能會有興趣閱讀 Overleaf 發表的以下文章：

* [什麼是 TeX token？](/latex/zh-tw/shen-ru-wen-zhang/53-what-is-a-tex-token.md)
* [什麼是 TeX 詞元清單？](/latex/zh-tw/shen-ru-wen-zhang/54-what-is-a-tex-token-list.md)-[TeX 巨集實際上是如何運作的？](/latex/zh-tw/geng-duo-zhu-ti/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### token 資料是從哪裡來的？

在本文中，我們使用由 TeX 計算出的實際 token 值——這些資料通常無法供使用者存取。對於想知道這些 token 值資料是如何取得的讀者，Overleaf 針對多個 TeX 引擎提供了客製化建置，我們用它們進行研究。這些引擎經過修改，會輸出 TeX 內部處理活動的資訊——有助於為我們撰寫的一些文章提供額外背景資料。透過展示／討論數值化的 token 值，我們的目的是納入一些細節，希望能幫助讀者更好地理解「TeX tokens」，讓這個重要概念不那麼晦澀。

## TeX Tokens 入門（以及展開的概念）

當 TeX 處理你的輸入檔案時，它會讀取文字，並將單一字元與字元序列（命令）轉換成所謂的 *詞元*。TeX token 其實只是 TeX 計算出的整數值，用來「編碼」TeX 需要儲存的資料，這些資料是關於從目前輸入來源讀入的某個項目。可以把 token 想成一小包資訊，它把 TeX 需要記錄的資料「打包」在一起，準備傳給下一個處理階段。在內部，TeX 是以這些整數 token 值運作的——它不會使用原本輸入檔案中實際的字母、符號、數字等：一切都會轉換成 token（整數），而 TeX 就用這些 token 來處理。

## TeX 如何計算 token 值

這裡我們看看 Knuth 原始 TeX、e-TeX 與 pdfTeX 所使用的 token 計算方式；對於其他 TeX 引擎，特別是 XeTeX 與 LuaTeX，因為要考慮 Unicode 的使用，其 token 計算必須略有不同，但計算方法與下文所述類似。

### 字元 token（非活躍字元）

非活躍字元的 token 值計算很直接：

$$\text{character token} = 256\times \text{(category code)} + \text{character (ASCII) code}$$

**範例**：字母 A 具有 [類別碼](/latex/zh-tw/geng-duo-zhu-ti/43-table-of-tex-category-codes.md) 11，而字元碼 65 會被 TeX 表示為字元 token 值 $$256\times 11 + 65 = 2881$$.

你可能會在 TeX 文獻中看到這樣的說法：一旦 TeX 輸入某個字元，它的類別碼值就會「永久綁定」到那個字元上：上述 token 值的計算方式就說明了為什麼這是真的。不過，在 TeX 後續的處理過程中，它可以，而且確實會，把字元 token「解包」，以顯示構成該 token 的（字元碼、類別碼）配對——當 TeX 進行這種「解包」時，並不會改變那個字元的類別碼，只是在後續處理中使用這些資訊。

### 命令 token

TeX 的輸入處理與 token 生成會辨識兩種命令：

* 由一個或多個類別碼為 11 的字元構成的命令；
* 單一字元命令，且該字元的類別碼不是 11：例如 `\$` 或 `\#`.

在這兩種情況下，TeX 都會排除開頭的 `\\` 字元，並使用每個剩餘字元的字元碼來計算一個整數，TeX 稱之為 `curcs` (**cur**rent **c**ontrol **s**序列）。接著 TeX 會使用 `curcs` 來為該命令計算 token 值。

#### 由類別碼 11 字元構成的命令

假設我們的命令（去掉開頭的 `\\` 字元）是由一串字元組成： $$\mathrm{C\_1C\_2C\_3...C\_N}$$ 其中 $$\mathrm{C}\_i$$ 是每個字元的字元碼——例如，A 的字元碼是 65。TeX 會使用所有字元碼 $$\mathrm{C}\_i$$ 來計算整數 `curcs` （使用 [雜湊函式](https://en.wikipedia.org/wiki/Hash_function)）。 `curcs` 接著它只要在該值上加上 4095，就得到 token 值：

$$\text{command token} = \text{curcs + 4095}$$

請注意，變數 `curcs` 在 TeX 的內部處理活動中扮演極其重要的角色。

#### 單一字元命令

用來表示像 `\$`, `\#` 等這類命令的 token 需要採用稍有不同的計算方式：整數 `curcs` 現在的較簡單計算如下：

$$\text{curcs} = 257 + \text{character (ASCII) code}$$

例如，當 `\$`, $$\text{curcs}=257 + 36 = 293$$。TeX 會再次在這個值上加上 4095（使用 $$\text{command token} = \text{curcs} + 4095$$）而得到 `\$` 其 token 值為 $$293 + 4095 = 4388$$.

與由類別碼 11 的字元組成的命令相比，這裡唯一的差別在於 TeX 如何計算……的值 `curcs`.

**注意**：整數 `curcs` 不會為字元 token 計算：當 TeX 建立或處理字元 token 時，它一律設為 0。

#### 活躍字元 token

TeX 有所謂的 *活躍字元*：任何被指定為類別碼 13 的字元。這類特殊字元的 token 與一般字元相比，計算方式不同。

活躍字元機制讓 TeX 能建立實際上等同於單一字元巨集的東西，你可以用它們而不必 *而不* 必須在活躍字元前加上跳脫字元（通常是 `\\`）：單獨出現的該字元就會觸發其巨集行為。經典範例是 TeX/LaTeX 用於不換行空格的波浪號字元（\~），可如下定義／啟用：

```
\catcode`~=13 % 將 ~ 的類別碼設為 13
\def~{\penalty100000\ } % 將 ~ 定義為巨集
```

當 TeX 之後讀到一個 `~` 字元時，它會偵測其類別碼為 13，並將其視為「迷你巨集」來處理。若要計算代表活躍字元的 token，TeX 會套用另一種計算 `curcs`:

$$\begin{align\*} \text{curcs} &= \text{character code} + 1\ \text{active character token} &= \text{curcs} + 4095\ \end{align\*}$$

例如，\~ 字元的字元碼是 126，表示其活躍字元 token 值表示如下計算：

$$\begin{align\*} \text{curcs} &= 126 + 1\ \text{active character token} &= 127 + 4095\ &=4222\ \end{align\*}$$

請注意，與命令一樣，代表活躍字元的 token 也大於 4095。

### 影響／附註

* 任何值超過 4095 的 token 都可立刻辨識為命令 token——因此 TeX 很容易判斷某個 token 代表的是字元還是命令。
* 對於任何 token 值，TeX 在需要時都可以「解包」該 token，以顯示原本存在於你的 `.tex` 檔案中、儲存在巨集定義裡，或包含在其他 token list 中的字元（及其類別碼），或命令。
* 名為 `curcs`的「中間」數值——TeX 用它來計算命令 token 值——在 TeX 的低階處理中扮演重要角色。 `curcs` 可作為 TeX 用來儲存／查找某個命令目前意義的「索引值」。給定任何命令 token， $$\mathrm{T}$$，TeX 只要減去 4095 就能取得 `curcs`: $$\text{curcs} = \mathrm{T}-4095$$

順帶一提，TeX 會儲存產生命令 token 的可讀字元字串——這對錯誤報告以及其他命令來說是必要的，例如 `\string` 其展開結果就是 token 值的可讀版本。然而，儲存在 TeX 內部的那些可讀字元字串只會在需要時使用／輸出：對於其他所有處理，使用的是 token 的整數值。

## 看看一些真實的 token

為了讓 token 這個概念不那麼晦澀，我們來定義下面這個簡單巨集，並看看 TeX 會產生哪些 token：

```
\def\hello{Greetings, from \TeX. \hskip 10pt}
```

對於 `\hello` 巨集，TeX 會使用字元 `h`, `e`, `l`, `l`, `o` 來為……計算出 3745 的值 `curcs`；接著 TeX 會加上 4095， $$3745 + 4095 = 7840$$ （適用於 Knuth 的 TeX、e-TeX 或 pdfTeX）。

在建立用來表示 `\hello`中使用時， `\def` 命令的 token 之後，這個命令會使 TeX 讀取後續 token，並用它們建立一個 token list，該 list 會儲存為 *定義* 於 `\hello` 命令。當你要 TeX 使用該 `\hello` 來完成的。

下表列出在……中包含的每個項目（字元、巨集或原語）所建立的實際 token 值 `\hello` 巨集定義——這個 token（整數）列表就是 TeX 儲存在記憶體中的內容（作為一種稱為 [linked-list](https://en.wikipedia.org/wiki/Linked_list)）中。想更深入了解 token list 的讀者，可參考 Overleaf 文章 [什麼是 TeX 詞元清單？](/latex/zh-tw/shen-ru-wen-zhang/54-what-is-a-tex-token-list.md)

|                 |            |
| --------------- | ---------- |
| **TeX token 值** | **所代表的項目** |
| 2887            | G          |
| 2930            | r          |
| 2917            | e          |
| 2917            | e          |
| 2932            | t          |
| 2921            | i          |
| 2926            | n          |
| 2919            | g          |
| 2931            | s          |
| 3116            | ,          |
| 2592            |            |
| 2918            | f          |
| 2930            | r          |
| 2927            | o          |
| 2925            | m          |
| 2592            |            |
| 5235            | \TeX       |
| 3118            | .          |
| 2592            |            |
| 7943            | \hskip     |
| 3121            | 1          |
| 3120            | 0          |
| 2928            | p          |
| 2932            | t          |

在上面的 token list 中，字元的類別碼為 10、11 或 12。例如：

* 字元的類別碼為 10、字元碼為 32，因此 token 值為 $$256\times 10 + 32 = 2592$$
* `,` 以及 `.` 的類別碼為 12，而字元碼分別為 44 與 46，因此 token 為：
* 代表……的 token `,` $$= 256 \times 12 + 44 = 3116$$
* 代表……的 token `.` $$= 256\times 12+ 46 = 3118$$

當 TeX 之後遇到 token 值 7840（代表 `\hello`）時，如有需要，它可以「解包」該 token 以擷取 `curcs` ，方法是透過簡單的計算 $$\text{curcs} = \text{token value} - 4095$$ （見上文）。利用 `curcs` TeX 可以查詢其內部資料表，判定命令 token 7840 代表一個巨集命令。此外，透過 `curcs`，TeX 也可以查找並擷取 `\hello`.

當 TeX 需要完整處理 token 7840，也就是要執行這個 `\hello` 巨集時，它就不再需要 token 7840：該 token 已經 *完成了它的工作*——也就是說，它觸發 TeX 執行了該巨集 `\hello`。TeX 現在可以丟棄 token 7840，並取得表示儲存在記憶體中的定義（token list）的 tokens。實際上， `\hello` 巨集命令（token 7840）已被 *移除* 自 TeX 目前的輸入來源，並 *被取代* 為包含在……定義中的 tokens `\hello`。我們剛才所描述的是一種 *token 展開*.

該 `\TeX` 命令（上文列出的 token 值 5235）在 `\hello` 本身也是由更多 token 構成的巨集——因此它的定義也會儲存為 token list：

|                 |            |
| --------------- | ---------- |
| **TeX token 值** | **所代表的項目** |
| 2900            | T          |
| 19598           | \kern      |
| 3117            | -          |
| 3118            | .          |
| 3121            | 1          |
| 3126            | 6          |
| 3126            | 6          |
| 3127            | 7          |
| 2917            | e          |
| 2925            | m          |
| 19597           | \lower     |
| 3118            | .          |
| 3125            | 5          |
| 2917            | e          |
| 2936            | x          |
| 6175            | \hbox      |
| 379             | {          |
| 2885            | E          |
| 637             | }          |
| 19598           | \kern      |
| 3117            | -          |
| 3118            | .          |
| 3121            | 1          |
| 3122            | 2          |
| 3125            | 5          |
| 2917            | e          |
| 2925            | m          |
| 2904            | X          |

如果我們要把 `\hello` 命令替換成構成它的完整 token 列表，包括 `\TeX` 巨集，那麼這會是一個相當長的列表——也就是說，如果我們也將 *展開* 加上 `\TeX` 巨集，我們會看到：

![儲存在 TeX 巨集中的 token 列表](/files/95589fb25a07bb74fcaf5703c73f9610471098d5)

基本上，單一的 token 值 7840（代表 `\hello`）在完全展開後，會產生總共 51 個 tokens（整數），代表字元與原語命令。以下列表中，每個 token 所代表的字元或命令都以括號「(...)」標示——這些內容並不直接儲存在 TeX 的 token list 中，僅為方便讀者理解而顯示：

```
2887 (G), 2930 (r), 2917 (e), 2917 (e), 2932 (t), 2921 (i), 2926 (n), 2919 (g), 2931 (s), 3116 (,), 2592 (<space>), 2918 (f), 2930 (r), 2927 (o), 2925 (m), 2592 (<space>),  2900 (T), 19598 (\kern), 3117 (-), 3118 (.), 3121 (1), 3126 (6), 3126 (6), 3127 (7), 2917 (e), 2925 (m), 19597 (\lower), 3118 (.), 3125 (5), 2917 (e), 2936 (x), 6175 (\hbox), 379 ({), 2885 (E), 637 (}), 19598 (\kern), 3117 (-), 3118 (.), 3121 (1), 3122 (2), 3125 (5), 2917 (e), 2925 (m), 2904 (X), 3118 (.), 2592 (<space>), 7943 (\hskip), 3121 (1), 3120 (0), 2928 (p), 2932 (t)
```

對人類讀者來說，這只是一串整數，但對 TeX 來說，它編碼了大量資訊。

## 現在讀取 token 並將其存起來，供日後使用

當 TeX 讀取你的輸入時，有時它可能需要（或被指示）延後完整處理某一組特定 token。若被要求這麼做，TeX 會在接到停止指令之前，持續從輸入中建立 token，但把它們先存起來，以便日後使用——之後再將它們取出並處理，作為排版活動的一部分。這些被儲存的 token 稱為所謂的 *token list* ，實際上是 TeX 唯一的（內部）token 資料儲存機制。

我們已經看過 token list 的例子——也就是 `\hello` 以及 `\TeX` 上面列出的巨集：這些巨集的定義是以 token 列表的形式儲存在 TeX 的記憶體中。只有當你決定呼叫這些巨集時，TeX 才會處理（執行）這些 token list。也請記住，每個 token（整數值）都編碼了足夠的資訊，讓 TeX 能輕易判斷儲存在巨集定義中的每個 token 代表的是字元還是命令。

### 使用 token register 儲存 token

token 儲存的另一個例子，是明確建立 token 列表，並將其儲存在所謂的 *token register*：TeX 提供給使用者用來儲存 token list 的專用內部儲存區域。TeX 的原語 `\toksdef` 是使用 token register 的一種方式；例如，要使用 token register `100` 並用命令 `\mylist`:

```
        \toksdef\mylist=100
        \mylist={some \TeX{} tokens here}
```

`\mylist` 實際上，只是你指定給儲存在索引位置 `100`的 token 列表的名稱。類似於巨集定義， `\mylist` 包含以下 token 列表：

|                 |            |
| --------------- | ---------- |
| **TeX token 值** | **所代表的項目** |
| 2931            | s          |
| 2927            | o          |
| 2925            | m          |
| 2917            | e          |
| 2592            |            |
| 5235            | \TeX       |
| 379             | {          |
| 637             | }          |
| 2592            |            |
| 2932            | t          |
| 2927            | o          |
| 2923            | k          |
| 2917            | e          |
| 2926            | n          |
| 2931            | s          |
| 2592            |            |
| 2920            | h          |
| 2917            | e          |
| 2930            | r          |
| 2917            | e          |

**注意**：為了終止該 `\TeX` 巨集並防止它吸收後面的 `<space>` 字元，我們使用了一對大括號 `{}` 緊接在 `\TeX`之後—— `{` （379）與 `}` （637）會儲存在 token 列表中。另一個選項是使用「控制空格」token `\<space>` ，它會如下所示出現在 token 列表中（以粗體顯示）：

|                 |            |
| --------------- | ---------- |
| **TeX token 值** | **所代表的項目** |
| 2931            | s          |
| 2927            | o          |
| 2925            | m          |
| 2917            | e          |
| 2592            |            |
| 5235            | \TeX       |
| **4384**        | **\\\\**   |
| 2932            | t          |
| 2927            | o          |
| 2923            | k          |
| 2917            | e          |
| 2926            | n          |
| 2931            | s          |
| 2592            |            |
| 2920            | h          |
| 2917            | e          |
| 2930            | r          |
| 2917            | e          |

請注意， `<space>` 字元會被表示為一個 *字元記號* ，其值為 $$256\times 10 + 32 = 2592$$ 但是 `\﻿<space>` 會被視為一個單一字元的 *命令記號* （值為 4384），其計算方式如下：

\begin{align\*} \text{curcs} & = 257 + \text{character (ASCII) code}\\\ & = 257 + 32\\\ &=289\\\ \text{command token for} \left<\text{\\\space}\right> & = \text{curcs + 4095}\\\ & = 289+4095\\\ &=4384\\\ \end{align\*}

本質上 `\mylist={some \TeX{} tokens here}` 是在對 TeX 說：請掃描我的輸入檔，將以下字元／命令轉換成 tokens 並儲存起來供日後使用。TeX 會照做，並將那些 tokens 儲存在你可以透過撰寫 `\the\mylist`來存取的記憶體位置，並指示 TeX 插入一份 token register 中所含 tokens 的副本 `\mylist`。TeX 引擎包含許多會明確產生並儲存 token list 的原語命令——例如 `\everyjob`, `\everypar`, `\mark`，以及許多其他命令。

[第 1 部分](/latex/zh-tw/shen-ru-wen-zhang/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [第 2 部分](/latex/zh-tw/shen-ru-wen-zhang/22-how-does-expandafter-work-the-meaning-of-expansion.md) [第 3 部分](/latex/zh-tw/shen-ru-wen-zhang/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [第 4 部分](/latex/zh-tw/shen-ru-wen-zhang/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [第 5 部分](/latex/zh-tw/shen-ru-wen-zhang/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [第 6 部分](/latex/zh-tw/shen-ru-wen-zhang/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/zh-tw/shen-ru-wen-zhang/19-how-does-expandafter-work-an-introduction-to-tex-tokens.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.
