> 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/vi/chu-de-khac/23-how-tex-macros-actually-work-part-5.md).

# Các macro TeX thực sự hoạt động như thế nào: Phần 5

[Phần 1](/latex/vi/chu-de-khac/19-how-tex-macros-actually-work-part-1.md) [Phần 2](/latex/vi/chu-de-khac/20-how-tex-macros-actually-work-part-2.md) [Phần 3](/latex/vi/chu-de-khac/21-how-tex-macros-actually-work-part-3.md) [Phần 4](/latex/vi/chu-de-khac/22-how-tex-macros-actually-work-part-4.md) [Phần 5](/latex/vi/chu-de-khac/23-how-tex-macros-actually-work-part-5.md) [Phần 6](/latex/vi/chu-de-khac/24-how-tex-macros-actually-work-part-6.md)

## Giới thiệu và tổng quan

Trong Phần 4, chúng tôi đã xem xét một số thuộc tính cơ bản của macro TeX để chuẩn bị cho hai bài tiếp theo, nơi chúng ta sẽ xem xét kỹ cơ chế nền tảng của các macro TeX: các danh sách token chuyên biệt. Trong hai bài cuối này, chúng tôi sử dụng các sơ đồ, gọi là danh sách nút, được tạo từ dữ liệu sinh ra bằng một phiên bản TeX gốc của Knuth đã được sửa đổi đặc biệt — những sửa đổi đó được thiết kế để truy cập các cấu trúc dữ liệu nội bộ của TeX vốn thường không thể truy cập đối với người dùng. Bằng cách “móc nối” vào các quy trình xử lý macro và thực thi nội bộ của TeX, chúng tôi có thể xuất ra dữ liệu đồ họa cho phép thảo luận chi tiết và chính xác hơn về hành vi xử lý macro của TeX. Overleaf hy vọng rằng các sơ đồ này sẽ giúp độc giả hiểu rõ hơn về cách macro TeX thực sự hoạt động.

### Bài đọc nền bổ sung có thể tham khảo

Overleaf đã xuất bản hai bài viết liên quan đến token cung cấp thêm thông tin nền về các token TeX và các danh sách token TeX. Hãy dành thời gian xem qua nếu bạn cần lấp các khoảng trống trong hiểu biết của mình và muốn tận dụng tối đa Phần 5 và 6 của loạt bài này.

* [“TeX token” là gì?](/latex/vi/bai-viet-chuyen-sau/53-what-is-a-tex-token.md)
* [Danh sách token TeX là gì?](/latex/vi/bai-viet-chuyen-sau/54-what-is-a-tex-token-list.md)

## Macro như các danh sách token

Khi TeX phát hiện một lệnh tạo macro (`\def`, `\edef`, `\gdef` hoặc `\xdef`) trong luồng nhập, nó kích hoạt một quá trình chuyển đổi cả hai phần `<parameter text><replacement text>` của định nghĩa macro của chúng ta thành một danh sách token dài duy nhất — nhưng là một loại danh sách token rất đặc biệt.

Các danh sách token dành cho macro hơi khác với các danh sách token khác được dùng trong TeX vì chúng chứa các giá trị token “đặc biệt” mà chỉ các quy trình nội bộ của chính TeX mới có thể tạo ra: những token đặc biệt đó không thể được tạo trực tiếp bởi bất kỳ lệnh nào mà bạn có thể đưa vào tệp .tex của mình. TeX tạo ra và sử dụng các giá trị token “đặc biệt” đó để hỗ trợ xử lý lời gọi macro của bạn, như chúng ta sẽ khám phá và giải thích bên dưới.

### Vài lời ngắn về cách các danh sách token được lưu trữ: các nút

Để lưu trữ một danh sách token (các giá trị nguyên), TeX sử dụng một cấu trúc dữ liệu gọi là [danh sách liên kết](https://en.wikipedia.org/wiki/Linked_list), mà trong trường hợp của TeX, bao gồm một danh sách các *nút*. Bạn có thể hình dung một nút như một gói bộ nhớ máy tính nhỏ có thể dùng để lưu trữ một tập hợp các mục dữ liệu. Để lưu một macro, các nút này được nối với nhau như một chuỗi, trong đó mỗi nút (mắt xích trong chuỗi) có thể lưu nhiều mẩu thông tin — bao gồm một giá trị token và địa chỉ bộ nhớ của nút tiếp theo trong danh sách. Để biết thêm thông tin, bạn có thể đọc bài viết [Danh sách token TeX là gì](/latex/vi/bai-viet-chuyen-sau/54-what-is-a-tex-token-list.md) nhưng sơ đồ sau tóm tắt các đặc điểm chính của một macro được lưu dưới dạng danh sách token:

![Sơ đồ về một danh sách token macro TeX được lưu dưới dạng danh sách nút liên kết](/files/d271063b01b6bffef2b2e4d75110fc298d3f6516)

### Nhắc lại: 4 phần của định nghĩa macro

Như đã thảo luận trong Phần 4, cấu trúc của bất kỳ macro nào có thể được viết là:

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

trong đó:

* `<TeX macro primitive>` = một trong `\def`, `\edef`, `\gdef` hoặc `\xdef`;
* `<macro name>`= tên của macro của bạn, chẳng hạn như `\foo`;
* `<parameter text>` có thể là “null” (không có mặt) hoặc có thể là một chuỗi các token phân tách và các token tham số macro;
* `<replacement text>` là phần thân thực sự của macro của bạn: phần được “thực thi” khi bạn gọi macro.

**LƯU Ý**: (Như cũng đã nhận thấy trong Phần 4) trong toàn bộ phần thảo luận chúng ta giả định rằng `<macro name>` sẽ được theo sau bởi một ký tự khoảng trắng có mã loại 10 để đóng vai trò dấu phân tách nhằm kết thúc `<macro name>`. Chúng tôi *không* đã hiển thị rõ ký tự khoảng trắng đó trong văn bản/phần thảo luận của chúng tôi nhưng chúng tôi giả định rằng nó ở đó. Nói chặt chẽ, chúng ta nên biểu diễn nó như sau:

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

Tuy nhiên, chúng tôi sẽ bỏ qua việc đưa rõ ràng một `<space>` ký tự và ngầm giả định sự hiện diện của nó.

**LƯU Ý**: Các ký tự `{` và `}` *không* trở thành một phần của danh sách token macro: mục đích của chúng chỉ là cho bộ quét đầu vào của TeX (bộ tạo token) biết nơi mà `<replacement text>` bắt đầu và kết thúc.

Khi TeX định nghĩa một macro, các phần `<parameter text><replacement text>` được chuyển thành một danh sách token liên tục dài duy nhất — tổng số token trong danh sách đó phụ thuộc vào độ phức tạp của macro. Như chúng ta đã thấy, phần này có mục đích cụ thể là đóng vai trò như một “mẫu token” hoặc “bản thiết kế” mà TeX dùng để chọn ra các token tạo thành các đối số (giá trị) dùng với macro thực sự: tức là các token được đưa vào `<replacement text>`.

Để làm rõ những ý tưởng này, hãy lấy một macro ví dụ nhưng giữ nó ngắn gọn để các sơ đồ sau đó không trở nên quá rối:

```
\def\foo A#1\fake{123 #1}
```

Đối với macro của chúng ta, `\foo`

* `<parameter text>` = `A#1\fake`
* `<replacement text>` = `123 #1`

Mặc dù ví dụ này là một macro đơn giản, nó chứa đầy đủ mọi đặc điểm mà chúng ta cần khám phá.

Như đã lưu ý, TeX sẽ chuyển `<parameter text><replacement text>` thành một danh sách token dài duy nhất mà bạn có thể thấy trong sơ đồ bên dưới. Trong ví dụ của chúng ta, các token được tạo từ `A#1\fake{123 #1}` đã được chuyển thành một chuỗi token liên tiếp được lưu trong một danh sách token (dưới dạng danh sách liên kết các nút).

## Hình minh họa một danh sách token macro thực tế

Sơ đồ sau đây, cho thấy macro `\def\foo A#1\fake{123 #1}` được lưu trữ như thế nào, sử dụng dữ liệu thực từ bên trong một bộ máy TeX. Nó được tạo bằng một [phiên bản TeX của Knuth đã được tùy chỉnh](/latex/vi/bai-viet-chuyen-sau/01-a-new-series-of-articles-tex-tokens-and-related-concepts-but-why-and-how.md#how-can-you-study-tex-tokens3f) được sửa đổi với mã bổ sung để chặn các lời gọi macro, kiểm tra dữ liệu nội bộ của TeX và xuất nó ra định dạng để xử lý bằng một chương trình đồ họa mã nguồn mở có tên là [Graphviz](https://www.graphviz.org/).

Bạn có thể tải đồ họa sau đây dưới dạng một [tệp PDF](https://assets.ctfassets.net/nrgyaltdicpt/N6gT757eXCxRV3FtdPPga/7ce120dc05ed05962bb911ff1124734b/annotatednodelist-plain.pdf) (675 KB) hoặc [tệp SVG](https://images.ctfassets.net/nrgyaltdicpt/4PkmtHDhO8KF892ZDWuLHP/2c9c8385c6948fd122b228c5c780a3a6/annotatednodelist-plain.svg) (1,8 MB).

![Sơ đồ về một danh sách token TeX có chú thích](/files/176fce823c28564725961918f7ee263b0cc53c14)

#### Hiểu các nút

Trong sơ đồ ở trên, bạn sẽ thấy rằng mỗi nút chứa hai mục dữ liệu gọi là **nút tiếp theo** và **nút hiện tại**. Đây chỉ là các giá trị nguyên biểu thị các vị trí bộ nhớ bên trong TeX — những vị trí lưu các nút khác. Các giá trị của **nút tiếp theo** và **nút hiện tại** không quan trọng, chúng chỉ đơn giản lưu các vị trí (địa chỉ bộ nhớ) cho phép các nút được liên kết với nhau thành một danh sách.

![Ý nghĩa của nút tiếp theo và nút hiện tại](/files/6b52787e2a289fd835c243db5537b929224c6008)

#### Quay lại ví dụ

Trong sơ đồ nút, danh sách token được tạo từ `A#1\fake{123 #1}` chứa một số “token đặc biệt” đã được giới thiệu ở đầu bài viết này. Ngoài ra, danh sách nút biểu diễn macro của chúng ta bắt đầu bằng một “nút đầu tiên đặc biệt”: chúng ta sẽ khám phá đó là gì và chúng làm gì.

Mục đầu tiên trong danh sách token của macro (và một số kiểu danh sách token khác) không lưu một giá trị token mà là một mục dữ liệu gọi là *số đếm tham chiếu* mà TeX dùng để theo dõi việc sử dụng macro.

![Một nút số đếm tham chiếu là nút đầu tiên trong một danh sách token](/files/18039ac32387770f462af2b6b29f87e95a56c796)

Token đầu tiên của `<parameter text>` được lưu trong nút ngay sau số đếm tham chiếu: bạn có thể thấy đó là một token đại diện cho chữ cái `Một` với mã loại 11. Từ các thảo luận ở Phần 2 và 3, chúng ta biết rằng một token ký tự được tính bằng

$$\text{token value}=256\times \text{category code} + \text{character code}$$

mà, đối với một chữ cái `Một` với mã loại 11, là

$$\text{token value}=256\times 11 + 65$$

cho ra giá trị 2881, như hiển thị trong nút.

#### “Lệnh” \fake được dùng trong \foo

Trong định nghĩa macro của chúng ta `\def\foo A#1\fake{123 #1}` một trong các dấu phân tách là một *chưa được định nghĩa* lệnh `\fake` được lưu trong danh sách token như một phần của `<parameter text>` phần. Như bạn có thể thấy, trong toàn bộ danh sách token macro, `\fake` là một token có giá trị `19491`—một giá trị nguyên được TeX tính bằng công thức đã thảo luận trong Phần 3. Khi TeX cố gắng thực thi `\foo` nó sẽ mong đợi tìm thấy `\fake` giá trị token ở cuối phần `<parameter text>` phần. TeX *sẽ không* cố gắng thực thi `\fake` lệnh vì vai trò của nó chỉ đơn giản là cung cấp một dạng “dấu câu” trong `<parameter text>` “mẫu token”.

![Dùng một token lệnh làm dấu phân tách macro](/files/5ce717dfef5d20b144fcfb6cadbe9570736b31a7)

#### Các token đặc biệt trong danh sách token

**Token “kết thúc khớp”**

Khi gọi một macro, nhiệm vụ đầu tiên của TeX là quét macro đúng như người dùng nhập và so sánh các token có trong `<parameter text>` phần với các token chứa trong mẫu `<parameter text>` được lưu trong bộ nhớ (được tạo vào thời điểm macro được định nghĩa). Vì toàn bộ định nghĩa của macro, được tạo từ `<parameter text><replacement text>` được lưu như một danh sách token liên tục dài duy nhất, TeX cần biết ở đâu, trong danh sách token đó, `<parameter text>` *ngừng* và ở đâu `<replacement text>` *bắt đầu*. **kết thúc khớp** token làm token cuối cùng trong tập các token được tạo từ `<parameter text>`. Gói **kết thúc khớp** token này không thể được tạo ra từ các lệnh của người dùng, chỉ chính TeX mới có thể tạo ra nó, do đó TeX chắc chắn sẽ phát hiện phần kết thúc của `<parameter text>`.

![Hiển thị token kết thúc khớp trong một danh sách token TeX](/files/001703ffb17cf5683e7b2a1870aa91b7e68ce171)

Ở đây, chúng ta có thể thấy rằng token đầu tiên theo sau **kết thúc khớp** là một token đại diện cho chữ số `1` với mã loại 12. Điều này là điều có thể mong đợi vì `<replacement text>` đối với macro của chúng ta `\foo` là `123 #1`—tức là, nó bắt đầu bằng token đại diện cho chữ số `1` (với mã loại 12).

Từ phần thảo luận ở Phần 2 và 3, chúng ta biết rằng một token ký tự được tính bằng

$$\text{token value}=256\times \text{category code} + \text{character code}$$

mà, đối với một chữ số `1` với mã loại 12 là

$$\text{token value}=256\times 12 + 49$$

cho ra giá trị token 3121, như hiển thị trong nút.

**các token “tham số khớp”**

Khi TeX lưu định nghĩa macro, nó chuyển bất kỳ token tham số nào (`#1`, `#2`… `#9`) `<parameter text>` thành một token gọi là **tham số khớp** token. Những token này cho TeX biết rằng nó cần bắt đầu tìm các token, trong lời gọi macro của người dùng, đóng vai trò là các đối số của macro.

![Hiển thị token tham số khớp trong một danh sách token TeX](/files/329e8e215e240f233bc71e1fb91213a932bd9961)

### Các token đặc biệt trong danh sách token

#### các token “tham số đầu ra”

Khi TeX đã xử lý mọi thứ và sẵn sàng thực sự chạy (mở rộng) macro, các **tham số đầu ra** token chỉ dẫn cho TeX các vị trí trong `<replacement text>` nơi nó cần chèn vào các token đại diện cho các đối số do người dùng cung cấp khi macro được gọi. Về bản chất: “Tại vị trí này, hãy chèn các token đại diện cho đối số n của người dùng, trong đó n=1...9”.

Trong `<replacement text>` phần của danh sách token định nghĩa macro được lưu sẽ có một **tham số đầu ra** token tương ứng với mỗi `#1`, `#2`... `#9` có mặt trong định nghĩa gốc.

![Hiển thị token tham số đầu ra trong một danh sách token TeX](/files/2fcad875fe351ba098be5a10c318bc952bfc14f9)

Nếu chúng ta xem định nghĩa của `\foo` (`\def\foo A#1\fake{123 #1}`) chúng ta thấy chỉ có 1 tham số macro (`#1`) `<parameter text>` (`A#1\fake`) và do đó cũng chỉ có 1 tham số macro (`#1`) xuất hiện trong `<replacement text>` (`123 #1`): điều này dẫn đến chỉ có 1 **tham số đầu ra** token có mặt trong danh sách token biểu diễn `<replacement text>`.

Hãy lưu ý điều sau trong danh sách nút biểu diễn `\foo`của `<replacement text>`:

* token ngay trước **tham số đầu ra** token đại diện cho một ký tự khoảng trắng (mã loại 10, mã ký tự 32) vì có một khoảng trắng giữa `123` và tham số macro (`#1`) trong định nghĩa gốc của `\foo`;
* trang **tham số đầu ra** là token cuối cùng trong danh sách:  **nút tiếp theo** có một giá trị đặc biệt là “null” (nghĩa là “rỗng”) được dùng để kết thúc danh sách: không còn nút nào sau **tham số đầu ra** vì nó là token cuối cùng, báo hiệu phần kết thúc của `<replacement text>` và do đó là kết thúc của định nghĩa macro.

## Phần 6

Trong Phần 6, chúng tôi sử dụng một số đồ họa chi tiết để giải thích và khám phá ý nghĩa chính xác của việc mở rộng macro và những hệ quả của việc TeX token hóa các đối số macro trước khi đưa chúng vào phần của một macro `<replacement text>`.

[Phần 1](/latex/vi/chu-de-khac/19-how-tex-macros-actually-work-part-1.md) [Phần 2](/latex/vi/chu-de-khac/20-how-tex-macros-actually-work-part-2.md) [Phần 3](/latex/vi/chu-de-khac/21-how-tex-macros-actually-work-part-3.md) [Phần 4](/latex/vi/chu-de-khac/22-how-tex-macros-actually-work-part-4.md) [Phần 5](/latex/vi/chu-de-khac/23-how-tex-macros-actually-work-part-5.md) [Phần 6](/latex/vi/chu-de-khac/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/vi/chu-de-khac/23-how-tex-macros-actually-work-part-5.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.
