> 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/14-how-do-tex-engines-typeset-tables.md).

# Các bộ máy TeX dàn trang bảng như thế nào

## Các bộ máy TeX dàn trang bảng như thế nào

## Giới thiệu: Chuỗi này đề cập đến điều gì?

Việc tạo ra các bảng đẹp mắt về mặt thẩm mỹ có thể là một công việc tốn thời gian—dù bạn đang dùng công cụ bố cục trực quan, LaTeX hay một ngôn ngữ đánh dấu như HTML hoặc markdown. Đặc biệt với người dùng LaTeX, dàn trang bảng đứng rất cao trong danh sách nhiều người xem là “điểm đau”, có lẽ được chứng thực bởi việc “tables” là một trong những [chủ đề được gắn thẻ nhiều nhất trên tex.stackexchange](https://tex.stackexchange.com/tags).

Ngoài các câu trả lời và ví dụ trên tex.stackexchange, chỉ cần xem qua các tài nguyên hỗ trợ sẵn có về dàn trang bảng bằng LaTeX cũng cho thấy một số nguồn thông tin liên quan đến bảng:

* Trang [trợ giúp](https://www.overleaf.com/learn/latex/tables) và các trang khác như [learnlatex.org](https://www.learnlatex.org/en/lesson-08)
* CTAN, Mạng TeX Toàn diện, liệt kê hơn [70 gói TeX/LaTeX](https://ctan.org/topic/table) liên quan đến việc tạo bảng
* cả một [cuốn sách về dàn trang bảng bằng LaTeX](https://www.amazon.co.uk/Typesetting-Tables-LaTeX-Herbert-Voss/dp/1906860254)
* một [trình tạo bảng LaTeX trực tuyến](https://www.tablesgenerator.com/latex_tables)

Một tìm kiếm Google đơn giản cho [bảng LaTeX](https://www.google.com/search?q=latex+tables) cho ra vô số kết quả, liệt kê nhiều trang cung cấp trợ giúp, lời khuyên, ví dụ và giải thích.

### TeX, không phải LaTeX

Với sự phong phú của tài liệu hiện có về dàn trang bảng bằng LaTeX, liệu còn gì để viết về chúng nữa—thêm các ví dụ bảng và việc liệt kê/minh họa các lệnh của gói? Có cách nào tiếp cận chủ đề dàn trang bảng để làm nổi bật hoặc tập trung vào các nguyên lý và khái niệm nền tảng của việc dàn trang bảng không? Có, nhưng nó đòi hỏi phải bóc từng lớp củ hành LaTeX…

Chúng tôi quyết định thực hiện một chuỗi bài viết nhằm cung cấp cho độc giả thông tin bối cảnh và giải thích về các *cơ chế* của việc dàn trang bảng dựa trên TeX. Thay vì tập trung vào việc dàn trang bảng bằng các macro/gói LaTeX cụ thể, chúng tôi sẽ khám phá *hành vi nền tảng* của các bộ máy TeX: khám phá bộ máy dàn trang ở mức thấp, nền tảng cho các lệnh macro của LaTeX được xây dựng dựa trên đó. Mục tiêu cuối cùng là rút ra, và giải thích, các phương pháp và thuật toán cốt lõi của việc dàn trang bảng dựa trên TeX—hy vọng giúp độc giả/người dùng hiểu rõ hơn vì sao các bảng lại hoạt động như vậy. Một hệ quả không thể tránh khỏi của cách tiếp cận này, bóc đi các lớp bảo vệ cách ly macro của LaTeX, là việc tiếp xúc với những chi tiết rối rắm ở mức thấp vốn thường bị che phủ (và một cách vui vẻ) khỏi người dùng qua các lớp mã macro LaTeX.

Đã tốn rất nhiều thời gian để nghiên cứu, viết và minh họa các bài viết này nên chúng tôi hy vọng chúng sẽ là một bổ sung xứng đáng cho kho tài liệu hiện có, cung cấp nội dung giúp độc giả hiểu rõ hơn lĩnh vực phức tạp này của dàn trang TeX. Chúng tôi cần nhấn mạnh rằng chuỗi bài viết này sẽ *không* đi lạc sang việc thảo luận *thẩm mỹ* của thiết kế bảng—đó là một chủ đề đầy rẫy các sở thích chủ quan và những lập luận về nó phải được tranh luận ở nơi khác…

### Khám phá cơ chế của bảng TeX: Bạn có thể làm điều đó như thế nào?

Để khám phá, rồi viết về, các cơ chế và quy trình ở mức thấp hơn diễn ra bên trong các bộ máy TeX, như dàn trang bảng, Overleaf đã xây dựng (biên dịch) các phiên bản “gỡ lỗi” của bộ máy TeX của Knuth bằng cách sử dụng [quy trình Web2W](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/index.html).

Theo truyền thống, việc xây dựng TeX liên quan đến một quy trình gọi là Web2C, được dùng trong TeX Live, tạo ra mã C bằng cách chuyển mã nguồn Pascal gốc của TeX sang tương đương C của nó. Quy trình đó tạo ra mã C vốn chưa bao giờ được dự định để con người đọc, mà chỉ để các trình biên dịch C đọc. Mã C được tạo ra một cách cơ học là *cực kỳ* khó đọc hoặc sửa đổi cho mục đích thử nghiệm.

Ngược lại, Web2W tạo ra mã nguồn C (có sẵn [ở đây](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/ctex.c)) là *lớn hơn hàng bậc* dễ đọc hơn mã do Web2C tạo ra. Vì vậy, mã nguồn C của Web2W dễ sửa đổi hơn nhiều cho mục đích học tập/thử nghiệm.

Web2W tạo ra một phiên bản TeX (“CTeX”) *cực kỳ* gần với chương trình gốc của Knuth: “CTeX” không bao gồm nhiều thay đổi và cải tiến được đưa vào qua quy trình Web2C—chẳng hạn SyncTeX, xử lý dòng lệnh và tìm tệp thông qua Kpathsea. Mặc dù bạn phải hy sinh những cải tiến hữu ích đó, mã C kết quả (Web2W) tương đối dễ điều hướng nhờ dùng mã nguồn TeX đã công bố của Knuth, dù TeX được viết bằng Pascal.

* **Một lưu ý về tên gọi:** Nói chặt chẽ, tên “TeX” chỉ được dùng để chỉ phần mềm gốc do Donald Knuth viết và công bố. Mọi sửa đổi đối với phần mềm của ông phải dùng một tên khác cho phần mềm dàn trang dựa trên TeX thu được. Ở đây, chúng tôi dùng quy trình Web2W để xây dựng một bộ máy về thực chất vẫn là phần mềm gốc của Knuth. Tuy nhiên, để tránh nhầm lẫn, chúng tôi sẽ dùng thuật ngữ “CTeX” để chỉ phiên bản cụ thể được xây dựng bằng Web2W, đồng thời cũng sẽ dùng “TeX” để chỉ hoặc bộ máy gốc của Knuth, hoặc một thuật ngữ chung cho ngôn ngữ dàn trang dựa trên các nguyên lý của TeX của Knuth. Chúng tôi hy vọng độc giả sẽ bỏ qua vài lần dùng thuật ngữ không hoàn toàn chặt chẽ: hy vọng ý nghĩa/ý định được truyền đạt qua ngữ cảnh.

Phiên bản gỡ lỗi của CTeX đã được chạy bằng [Eclipse IDE](https://www.eclipse.org/downloads/packages/), cho phép quan sát quá trình xử lý theo thời gian thực của mã C hiện thực các lệnh TeX nguyên thủy (tích hợp sẵn), và các thuật toán, do Knuth thiết kế để hỗ trợ dàn trang bảng.

Đoạn video ngắn sau đây (khoảng 90 giây) minh họa bộ máy CTeX chạy bên trong [Eclipse IDE](https://www.eclipse.org/downloads/packages/):

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/7drdFwYR6h5xD88XnurDIH/36511f504755ab274f4da2e3f3fc1ce5/TeXtables.mp4>" %}

Ngoài CTeX, chúng tôi cũng biên dịch e-TeX để truy cập thêm một vài nguyên thủy bổ sung không có trong phần mềm gốc của Knuth. Mặc dù CTeX và e-TeX hiện nay đều là các bộ máy dựa trên TeX đã cũ, chúng vẫn phù hợp làm nền tảng để khám phá cơ chế dàn trang bảng vì các nguyên lý nền tảng đó vẫn áp dụng cho mọi bộ máy dàn trang dựa trên TeX.

### Tại sao dùng một bộ máy TeX cũ hơn để khám phá các bảng?

Thứ nhất, cuốn sách in, [TeX:The Program](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373), liệt kê và giải thích mã nguồn của TeX, vẫn là một hướng dẫn cực kỳ tiện lợi về những vùng nước mù mờ bên trong hoạt động của TeX, dù đã được xuất bản hơn 30 năm trước (1986). Tất nhiên, bạn có thể tự dàn trang tài liệu mã nguồn TeX, ví dụ xem dự án Overleaf [Dàn trang tài liệu mã nguồn cho TeX, e-TeX hoặc pdfTeX](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv). Kể từ khi TeX:The Program được xuất bản năm 1986, các bộ máy TeX mới đã phát triển, bao gồm pdfTeX, XeTeX và LuaTeX, tất cả đều giới thiệu các tính năng và lệnh không được ghi trong TeX:The Program đơn giản vì chúng không có mặt trong phần mềm gốc của Knuth.

Đối với nhiều quy trình cốt lõi, như việc dàn trang bảng của TeX, mã được ghi trong TeX:The Program vẫn còn liên quan như một nền tảng để nghiên cứu—dù mã nguồn của TeX được viết bằng Pascal. Ngoài ra, TeX của Knuth tương đối dễ, và nhanh, để biên dịch—đặc biệt thông qua [quy trình Web2W](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/index.html) cực kỳ hữu ích do Martin Ruckert phát triển. Dễ/nhanh biên dịch khiến việc sửa đổi TeX theo những cách đơn giản trở nên thuận tiện hơn nhiều—chẳng hạn như việc tạo đồ họa SVG được dùng sau này trong chuỗi bài viết này.

### Hiểu sự khác biệt giữa TeX và LaTeX

Nhiều độc giả có lẽ đã biết rằng LaTeX thực ra không phải là một *tệp thực thi* chương trình dàn trang mà là một tập hợp lớn các lệnh (*macro*) mà, rốt cuộc, được viết bằng một ngôn ngữ dàn trang/lập trình ở mức thấp hơn gọi là TeX. Mã LaTeX của bạn chỉ tạo ra đầu ra đã dàn trang sau khi nó được xử lý bởi một chương trình thực thi gọi là một *bộ máy TeX*—phần mềm nằm giữa mã LaTeX (tài liệu) của bạn và tệp PDF đã dàn trang. Ngày nay, người dùng có thể chọn giữa nhiều bộ máy TeX khác nhau để dàn trang mã LaTeX của mình, bao gồm pdfTeX, XeTeX và các biến thể của LuaTeX.

Những người mới làm quen với hệ sinh thái TeX/LaTeX thường, và dễ hiểu thôi, bối rối trước vô số tên gọi nghe bí hiểm được dùng cho các công cụ họ gặp: TeX, LaTeX, pdfTeX, pdfLaTeX, XeTeX, XeLaTeX, LuaTeX và LuaLaTeX. Nếu bạn cũng thấy vậy, Overleaf có bài [Tên gọi có ý nghĩa gì: Hướng dẫn về nhiều biến thể của TeX](/latex/vi/bai-viet-chuyen-sau/55-what-s-in-a-name-a-guide-to-the-many-flavours-of-tex.md) giải thích nguồn gốc và ý nghĩa của tất cả các thuật ngữ đó.

#### Các phương ngữ và nguyên thủy TeX

Mọi bộ máy TeX đều có một tập hợp các lệnh tích hợp sẵn được gọi là *các nguyên thủy* mà, xét tổng thể, tạo thành “phương ngữ” của bộ máy đó trong ngôn ngữ dàn trang TeX, phản ánh các khả năng được tích hợp vào từng bộ máy. Ở đây, thuật ngữ “nguyên thủy” dùng để mô tả các lệnh tích hợp sẵn của các bộ máy TeX không *không* có nghĩa là các lệnh đó cơ bản hay đơn giản mà là chúng nền tảng và không thể chia nhỏ: không được tạo thành từ các lệnh khác (không giống như các macro). Tất cả các bộ máy TeX đều chia sẻ một bộ nguyên thủy cốt lõi lớn nhưng một số bộ máy có chứa các nguyên thủy riêng của bộ máy đó—từ đó hình thành nên khái niệm “phương ngữ” của TeX.

Bất kể bộ máy TeX nào được dùng để dàn trang tài liệu LaTeX của bạn, nhiệm vụ của nó là xử lý (“thực thi”) tập hợp các lệnh LaTeX (tức là các macro) được dùng để viết và xây dựng tài liệu của bạn. Thực chất, bộ máy TeX “chuyển đổi” mã LaTeX (các macro) của bạn *trở lại thành* các lệnh nguyên thủy của bộ máy TeX cấu thành chúng mà bộ máy có thể thực thi để tiến hành dàn trang thực sự. Bạn không *phải* cần *phải dùng các lệnh LaTeX để dàn trang tài liệu bằng các bộ máy TeX—bạn* có thể *chọn xây dựng tài liệu hoàn toàn bằng các nguyên thủy TeX, tức là trực tiếp bằng ngôn ngữ* lập trình TeX

ở mức thấp được tích hợp trong các bộ máy TeX. Tuy nhiên, theo chuẩn ngày nay, ngôn ngữ TeX khá bí hiểm và thường được xem là khó để lập trình—nó cũng có thể đòi hỏi một số lượng lớn các nguyên thủy tích hợp sẵn để đạt được mục tiêu dàn trang của bạn, khiến công việc lập trình dễ mắc lỗi và có thể lặp đi lặp lại. *macro*Để tránh phải viết trực tiếp bằng ngôn ngữ TeX, hoặc liên tục gõ lại cùng một chuỗi lệnh, các bộ máy TeX cho phép bạn tạo ra các “phím tắt” gọi là [ConTeXt](https://wiki.contextgarden.net/Main_Page)Bằng cách tạo macro, bạn định nghĩa các lệnh riêng của mình đóng gói các chuỗi nguyên thủy của ngôn ngữ TeX (hoặc các macro khác) có thể dài và phức tạp thành một lệnh “cấp cao” duy nhất. Các lập trình viên TeX có thể viết những macro rất tinh vi, bao hàm rất nhiều chức năng trong một lệnh duy nhất—chẳng hạn như các lệnh do LaTeX cung cấp. Bằng cách sử dụng các gói macro, như LaTeX (hoặc

## Thuở ban đầu...

Cùng với việc thiết kế các thuật toán cho dàn trang toán học và ngắt dòng tinh vi, Knuth phải đối mặt với thách thức lập trình phần mềm TeX của mình để dàn trang bảng. Rõ ràng, mọi thuật toán xây dựng bảng phải không được quá hạn chế vì điều đó sẽ làm nản lòng người dùng cần quyền tự do tạo ra gần như vô hạn kiểu bố cục bảng. Hơn nữa, các ô bảng có thể chứa nhiều loại nội dung, bao gồm toán học, đồ họa và các đoạn văn bản được ngắt thành các dòng được dàn trang đẹp mắt—thực ra là bất cứ thứ gì TeX có thể dàn trang. Để mang lại sự linh hoạt này, các thuật toán dựng bảng của TeX phải hoạt động chặt chẽ với các phần khác trong bộ máy dàn trang của TeX.

Tuy nhiên, các bộ máy TeX phải trả giá cho sự linh hoạt mà khả năng dựng bảng mang lại: nhiều sắc thái tinh tế và khác biệt trong hành vi ở mức thấp của các lệnh dàn trang bảng tích hợp (nguyên thủy), trong đó có 9 lệnh:

* **`\halign`**, **`\valign`**: các lệnh cốt lõi để dựng bảng
* **`\tabskip`**: glue được chèn giữa các cột \halign hoặc các hàng \valign
* **`\cr`**: bộ kết thúc bắt buộc kiểu “carriage return” cho mọi dòng trong một bảng
* **`\noalign`**: chèn vật liệu giữa các hàng \halign hoặc các cột \valign
* **`\everycr`**: các lệnh (thanh ghi token) được đọc sau khi phát hiện \cr
* **`\span`**: một lệnh hai chức năng: \span tạo các ô trải trên nhiều cột hoặc hàng, hoặc mở rộng các lệnh trong phần mở đầu của bảng (chúng ta sẽ xem xét chi tiết)
* **`\omit`**: bỏ qua các mẫu cho một ô cụ thể
* **`\crcr`**: được dùng trong các macro để tránh lỗi nếu người dùng quên \cr bắt buộc

Chúng ta sẽ gặp các lệnh này trong hành trình tìm hiểu cách dựng bảng.

### Những tiếng vọng xa xôi của các thách thức

Ẩn trong [mã nguồn của TeX](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv) là một phần mở đầu khá đáng ngại về chủ đề triển khai các lệnh mức thấp \halign và \valign được thiết kế để dàn trang bảng:

> “Thật ra thì mỗi khi \halign và \valign hoạt động được là một điều gần như kỳ diệu, bởi chúng cắt ngang quá nhiều cấu trúc điều khiển của TeX. Vì vậy, trang hiện tại có lẽ không phải là nơi tốt nhất để người mới bắt đầu đọc chương trình này; tốt hơn là phải làm chủ mọi thứ khác trước.”

Knuth tiếp tục nói

> “Lưu ý rằng khi \halign đang được xử lý, chúng ta không ngần ngại giao quyền điều khiển cho phần còn lại của TeX. Ở những thời điểm then chốt, một thủ tục căn chỉnh được gọi vào để can thiệp và thực hiện một hành động nhỏ nào đó, nhưng phần lớn thời gian các thủ tục này chỉ ẩn nấp ở hậu trường. Nó giống như một gợi ý sau thôi miên.”

Từ những nhận xét này, có vẻ hợp lý khi kết luận rằng, ngay cả với Knuth, việc triển khai dàn trang bảng của TeX cũng là “một thử thách” — vừa phải cung cấp khả năng điều khiển và linh hoạt cho người dùng, vừa đồng thời đảm bảo các thuật toán dựng bảng tự động của TeX được phối hợp tốt với các quy trình dàn trang cốt lõi của TeX.

Tác giả sẵn lòng xác nhận độ phức tạp của mã và các thuật toán đứng sau khả năng dàn trang bảng của TeX nhưng cũng bày tỏ sự ngưỡng mộ trước lượng năng lực khổng lồ chứa trong một khối lượng Pascal (hoặc C) code tương đối nhỏ, dù dày đặc.


---

# 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/14-how-do-tex-engines-typeset-tables.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.
