> 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/bai-viet-chuyen-sau/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

# Giới thiệu về \endlinechar: Cách TeX đọc các dòng từ tệp văn bản

Là con người, chúng ta thích xem và chỉnh sửa các tệp văn bản theo từng dòng. Khi chúng ta nghĩ rằng một dòng văn bản đã đủ dài, chúng ta nhấn “return” (trong trình soạn thảo văn bản) để báo hiệu kết thúc của dòng đó. Ở hậu trường, trình soạn thảo văn bản của bạn sẽ hiểu điều đó là một chỉ dẫn để thêm một [ký tự xuống dòng](https://en.wikipedia.org/wiki/Newline) tại vị trí bạn quyết định ngắt dòng.

Tuy nhiên, nếu chỉ đơn giản vậy thì đã tốt: vấn đề là các hệ điều hành khác nhau có quan niệm khác nhau về điều gì cấu thành một ký tự xuống dòng. Tệ hơn nữa, Windows sẽ xử lý các ký tự xuống dòng khác nhau tùy thuộc vào việc một tệp được mở ở cái gọi là [*chế độ nhị phân* hoặc *chế độ văn bản*](https://docs.microsoft.com/en-us/cpp/c-runtime-library/text-and-binary-mode-file-i-o?view=vs-2017). Kết quả là, tùy theo hệ điều hành chủ, các dòng trong một tệp văn bản có thể được kết thúc bằng những tổ hợp ký tự khác nhau gọi là *ký tự xuống dòng về đầu dòng* (ký tự ASCII/Unicode 13) và *ký tự xuống dòng* (ký tự ASCII/Unicode 10): được ký hiệu bằng `\r` và `\n` tương ứng.

Rõ ràng, để không phụ thuộc vào hệ thống, TeX cần một cách để xử lý những biến thiên do các ký tự khác nhau được dùng để kết thúc một dòng trong các tệp văn bản mà nó cần đọc và xử lý gây ra.

### Bộ đệm đầu vào của TeX

Có thể bạn sẽ ngạc nhiên, hoặc không, khi biết rằng các bộ máy TeX (bao gồm LuaTeX và XeTeX) đọc các tệp đầu vào từng dòng một: chúng không đọc toàn bộ tệp văn bản vào bộ nhớ. Dù hầu hết các tệp văn bản được các bộ máy TeX xử lý đều rất nhỏ so với dung lượng bộ nhớ sẵn có trên các thiết bị hiện đại, mỗi dòng trong tệp đều được đọc riêng và lưu trong một bộ đệm nội bộ nhỏ. Nhưng dĩ nhiên, quá trình đọc và lưu một dòng của TeX còn có vài điểm phức tạp bổ sung.

## “Tôi sẽ làm theo cách của tôi”—lệnh \endlinechar của TeX

Khi TeX đọc thêm một dòng văn bản khác từ một tệp đầu vào, nó thực hiện hai “nhiệm vụ bảo trì”:

* nó xóa mọi ký tự xuống dòng kết thúc (\r hoặc \n) có ở cuối dòng—tức là loại bỏ tất cả các ký tự kết thúc dòng đã được thêm vào khi tệp văn bản ban đầu được lưu xuống đĩa;
* nó cũng xóa mọi ký tự khoảng trắng ở cuối dòng.

Hai quá trình này xảy ra trước khi TeX thực sự bắt đầu quét các ký tự chứa trong chính dòng đó: hãy xem chúng như một dạng “bảo trì” để chuẩn bị cho giai đoạn xử lý tiếp theo (quét). Vì vậy, trong giai đoạn đầu tiên này của quá trình đọc dòng, TeX đã loại bỏ mọi ký tự kết thúc dòng phụ thuộc nền tảng (và mọi khoảng trắng cuối dòng): vậy làm sao TeX biết (phát hiện) dòng đó kết thúc ở đâu? TeX còn một “mẹo” nữa trong tay áo: `\endlinechar` lệnh này.

Để tránh vấn đề về các ký tự xuống dòng phụ thuộc nền tảng, TeX giới thiệu khái niệm về `\endlinechar`, một tham số do người dùng định nghĩa mà TeX dùng để chèn ký tự kết thúc dòng của riêng nó vào tận cuối một dòng văn bản vừa được đọc từ một tệp. Lưu ý một lần nữa rằng điều này xảy ra trước khi TeX thực sự bắt đầu quét các ký tự—đây là bước cuối cùng trong “bảo trì” của TeX trước khi nó sẵn sàng bắt đầu đọc (quét) các ký tự thực sự có trong dòng.

TeX sẽ dùng giá trị được lưu trong `\endlinechar` để thêm bộ kết thúc dòng của chính nó nếu, và chỉ nếu, `\endlinechar` được định nghĩa thích hợp—trong TeX của Knuth điều đó có nghĩa là nó phải có một giá trị >-1 và < 256. Thông thường, `\endlinechar` được gán giá trị 13: ký tự carriage return—thường được ký hiệu bằng `\r` trong tài liệu lập trình.

Nhưng nếu bạn viết `\endlinechar=-1` ở đâu đó trong phần nhập của bạn thì *lần tiếp theo* TeX đọc một dòng văn bản từ tệp, nó sẽ *không* thêm bất kỳ ký tự kết thúc bổ sung nào vào cuối dòng. Do đó, phần nhập của bạn sẽ được xử lý như một chuỗi văn bản dài liên tục cho đến khi bạn đặt lại `\endlinechar` về một giá trị thích hợp—thường là 13 (`\r`):

```latex
\endlinechar=13
```

Một trong 16 mã phân loại của TeX (giá trị 5) được dành riêng để nhận diện ký tự “kết thúc dòng”, vốn thường là ký tự mà `\endlinechar` chèn vào—và nó chỉ được chèn nếu (và chỉ nếu) giá trị của `\endlinechar` được đặt về một giá trị thích hợp.

## Tóm tắt quá trình xử lý kết thúc dòng

Mặc dù các chi tiết này khá ở mức thấp, chúng sẽ hữu ích cho bất kỳ ai muốn tìm hiểu cách viết các macro xử lý việc đọc các dòng văn bản.

1. Khi TeX đọc một dòng từ tệp của bạn, trước tiên nó sẽ loại bỏ tất cả các ký tự kết thúc dòng (`\r` và `\n`) do trình soạn thảo văn bản của bạn thêm vào khi tệp được lưu. Ngoài ra:

* TeX cũng loại bỏ mọi ký tự khoảng trắng ở cuối dòng;
* TeX *không* loại bỏ các ký tự tab ở cuối dòng (mã ký tự ASCII 9).

**Bên lề**: Một trong các tệp mã nguồn của LuaTeX, tệp có mã thực hiện việc loại bỏ khoảng trắng này, chứa ghi chú sau:

> (Được trích dẫn trong tệp `luatex.c`) “David Fuchs cho biết việc loại bỏ \[khoảng trắng] này được thực hiện để đảm bảo khả năng di chuyển của các tài liệu TeX, do việc đệm bằng khoảng trắng trên các "dòng" có bản ghi cố định ở một số hệ thống thời bấy giờ, ví dụ IBM VM/CMS và OS/360.”

3. Sau bước (1), TeX thêm (chèn) một ký tự bổ sung có giá trị được lưu trong \endlinechar (với điều kiện nó được định nghĩa phù hợp: >-1 và < 256)
4. \endlinechar thường được đặt thành giá trị 13 (`\r`), có nghĩa là ký tự được thêm ở bước (2) thường là ký tự 13 (`\r`)—nhưng dĩ nhiên, bạn có thể đặt \endlinechar sang một giá trị khác để tạo ra các hiệu ứng đặc biệt thông qua lập trình macro.
5. Khi các thủ tục quét đầu vào của nó phát hiện ký tự `\r` (mã ký tự 13) ở cuối bộ đệm nội bộ của nó, TeX sẽ, như thường lệ, kiểm tra mã phân loại của nó để quyết định sẽ làm gì với nó.
6. Ký tự 13 *thường* có giá trị mã phân loại là 5 (“kết thúc dòng”) trừ khi, dĩ nhiên, mã phân loại của nó đã bị thay đổi—một số macro làm cho ký tự kết thúc dòng trở nên active để thực hiện xử lý phức tạp.
7. Tùy theo trạng thái nội bộ của TeX (thực chất là những gì nó đang làm), TeX có thể chuyển ký tự kết thúc dòng (thường là `\r`, mã phân loại 5) thành một ký tự khoảng trắng—đó là cách các ký tự kết thúc dòng trở thành khoảng trắng.
8. Cũng lưu ý rằng TeX dùng các ký tự có mã phân loại 5 để phát hiện khi nó đã đọc một dòng trống và cần tạo ra một `\par` token.

Hình minh họa sau đây cho thấy bản tóm tắt trực quan của các bước (1) và (2): loại bỏ các ký tự xuống dòng và các ký tự khoảng trắng ở cuối dòng, rồi chèn `\endlinechar` sẵn sàng cho nhiệm vụ quét đầu vào.

![TeX sử dụng \endlinechar như thế nào](/files/f9160f6745c99449b6dd991bcec669ed67dd7364)


---

# 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/bai-viet-chuyen-sau/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.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.
