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

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

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

## Các bộ máy TeX gọi các bảng là các căn chỉnh

Trong [tài liệu của mã nguồn TeX](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv) Knuth không bàn về khả năng “dàn trang bảng” của TeX mà thay vào đó, ông mô tả các thuật toán của TeX để xây dựng cái gọi là *các căn chỉnh*. Việc dàn trang bảng của TeX, trên thực tế, là một quá trình căn chỉnh hộp tự động: sắp xếp các hộp (ô bảng, hàng và cột) để đạt được một lưới hay ma trận hình chữ nhật dễ nhìn—tất nhiên, vì là TeX nên vẫn có *nhiều* những sắc thái tinh tế trong quá trình đó.

Thuật ngữ “alignment” cũng được phản ánh trong tên của hai lệnh dàn trang bảng có sẵn trong mọi bộ máy TeX:

* `\halign` (căn chỉnh ngang), và
* `\valign` (căn chỉnh dọc).

Chúng ta sẽ tìm hiểu cả hai lệnh trong suốt loạt bài này, bắt đầu bằng cái nhìn tổng quan mang tính hình thức hơn về định dạng/cấu trúc của các `\halign` và `\valign` lệnh nhằm đặt nền tảng cho các bài viết chuyên sâu hơn sau này trong loạt bài này.

### Bảng của TeX là các hộp và khoảng cách

Các ô bảng riêng lẻ thường chứa nhiều loại nội dung như các dòng văn bản, toán học hoặc đồ họa, tạo ra một tập hợp các ô bảng có độ rộng, chiều cao hoặc độ sâu khác nhau của tài liệu đã dàn trang. Bằng cách nào đó, TeX cần làm việc với các ô đó, với kích thước nội dung khác nhau, để xây dựng bảng cuối cùng trong đó mỗi hàng có một chiều cao nhất định và mỗi cột có một độ rộng nhất định. TeX cần suy ra các giá trị thích hợp cho chiều cao của từng hàng và độ rộng của từng cột từ tập hợp các ô bảng có kích thước thay đổi này.

Tuy nhiên, TeX không thể biết kích thước thực sự của nội dung trong từng ô cho đến khi nội dung đó được dàn trang; do đó, TeX xử lý toàn bộ bảng, dàn trang từng ô, để thu được dữ liệu kích thước cần thiết nhằm hoàn tất bố cục bảng. Từ dữ liệu kích thước đó, TeX có thể xác định chiều cao đúng cho từng hàng và độ rộng cho từng cột. TeX cũng có thể gặp các ô trống hoặc các ô mà người dùng muốn trải qua nhiều cột hoặc nhiều hàng, tất cả những điều này TeX đều phải cẩn thận đưa vào tính toán của mình. Sau khi “lọc” tập hợp rời rạc dữ liệu kích thước của các ô (hộp) này, chỉ khi đó TeX mới có thể xác định các giá trị cuối cùng cho độ rộng cột trong một `\halign`, hoặc chiều cao hàng cho `\valign` và sử dụng các giá trị đó ở các giai đoạn cuối của các thuật toán bố cục bảng.

Trên thực tế, và “ở bên trong”, việc dàn trang bảng của TeX gồm nhiều bước. Tóm lược, TeX trước hết dàn trang một phiên bản “bản nháp” hoặc “chưa hoàn chỉnh” của bảng trong khi nó ghi nhận và xử lý dữ liệu kích thước của các ô—và dữ liệu về bất kỳ `\span` lệnh nào được dùng trong bảng. Ở các bước cuối, TeX xử lý lại phiên bản “chưa hoàn chỉnh” đó của bảng, để hoàn tất `\halign` độ rộng cột hoặc `\valign` chiều cao hàng và đạt được bố cục hoàn chỉnh—all of which we’ll explore in this article series.

## \halign và \valign: hai cách để tạo bảng

Mọi bộ máy TeX đều cung cấp hai *tích hợp sẵn* lệnh (primitive) được thiết kế để dàn trang bảng (căn chỉnh): `\halign` và `\valign`, chúng có nhiều đặc điểm cốt lõi chung nhưng cũng khác nhau ở một số điểm cơ bản. Điểm khác biệt then chốt giữa `\halign` và `\valign` là cách chúng xây dựng các bảng tương ứng: theo từng hàng hay theo từng cột:

* `\halign`: dàn trang bảng theo từng hàng để tạo ra các hàng riêng lẻ được xếp chồng theo chiều dọc nhằm tạo thành các cột của bảng
* `\valign`: dàn trang bảng theo từng cột để tạo ra các cột riêng lẻ được xếp chồng theo chiều ngang nhằm tạo thành các hàng của bảng

### \halign

Sơ đồ sau mô tả cách xây dựng một bảng được tạo bởi `\halign`. Bảng được dàn trang theo từng hàng với các hàng riêng lẻ được xếp chồng theo chiều dọc. Một số hệ quả của điều này bao gồm:

* các cột của bảng phát sinh từ việc xếp chồng theo chiều dọc các hàng của bảng
* có thể xảy ra ngắt trang giữa các hàng của bảng
* có thể chèn nội dung không phải bảng giữa các hàng (thông qua `\nolign`, mà chúng ta sẽ xem sau)

![](/files/60d475a52137328c7f243bde4177a4d9a1a1e025)

### \valign

Sơ đồ sau mô tả cách xây dựng một bảng được tạo bởi `\valign`. Bảng được dàn trang theo từng cột với các cột riêng lẻ được xếp chồng theo chiều ngang (cạnh nhau). Một số hệ quả của điều này bao gồm:

* các hàng của bảng phát sinh từ việc xếp chồng theo chiều ngang các cột của bảng
* có thể xảy ra ngắt dòng giữa các cột của bảng
* có thể chèn nội dung không phải bảng giữa các cột (thông qua `\noalign`, mà chúng ta sẽ xem sau)

![](/files/02409bf560ab0325b3d14fc9469a3b2886fafb72)

### Ví dụ

Ví dụ sau nhằm làm nổi bật cách tiếp cận theo hàng *so với*. cách tiếp cận theo cột của \halign và \valign.

```latex
\documentclass{article}
\begin{document}
\pagestyle{empty}
% Viền hộp khít sát
\setlength{\fboxsep}{0pt}

Đây là một bảng \verb|\valign|:
\begingroup
% \hsize điều khiển
% độ rộng cột của \valign. Chúng ta cũng đặt
% \parindent thành một giá trị nhỏ hơn
\hsize=30pt
\parindent=10pt
\fbox{\valign{
#&#&#\cr % Phần tiền đề: sẽ được trình bày sau (rất chi tiết!)
A&B&C\cr % CỘT đầu tiên của bảng \valign này
D&E&F\cr
G&H&I\cr
}}
\endgroup

% Lưu ý: vì những lý do sẽ được giải thích sau
% \halign phải được đặt trong một \vbox
Đây là một bảng \verb|\halign|: \fbox{%
\vbox{\halign{
#&#&#\cr % Phần tiền đề: sẽ được trình bày sau (rất chi tiết!)
A&B&C\cr % HÀNG đầu tiên của bảng \halign này
D&E&F\cr
G&H&I\cr
}}}
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Basic+table+example\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%25+Close-fitting+box+borders+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table%3A+%0A%5Cbegingroup%0A%25+%5Chsize+controls+the+%5Cvalign+%0A%25+column+widths.+We+also+set+%0A%25+%5Cparindent+to+a+smaller+value%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign%7B%0A%23%26%23%26%23%5Ccr+%25+The+preamble%3A+covered+later+%28in+great+detail%21%29%0AA%26B%26C%5Ccr+%25+The+first+COLUMN+of+this+%5Cvalign+table%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%0A%25+Note%3A+for+reasons+explained+later%0A%25+the+%5Chalign+has+to+be+put+in+a+%5Cvbox%0AHere+is+an+%5Cverb%7C%5Chalign%7C+table%3A+%5Cfbox%7B%25%0A%5Cvbox%7B%5Chalign%7B%0A%23%26%23%26%23%5Ccr+%25+The+preamble%3A+covered+later+%28in+great+detail%21%29%0AA%26B%26C%5Ccr+%25+The+first+ROW+of+this+%5Chalign+table%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau: ![](/files/82dad8072c300afb851a8b6f4936a49226525621)

Hình minh họa sau cho thấy phiên bản có chú thích của các bảng được tạo bởi đoạn mã trên. Sau này trong loạt bài này, chúng ta sẽ đề cập đến các chủ đề như:

* phần tiền đề của bảng là gì?
* tại sao chúng ta đặt `\hsize` và `\parindent` cho `\valign` các bảng?

Tạm thời, chỉ cần lưu ý cách tiếp cận theo hàng so với theo cột của `\halign` *so với*. `\valign` việc xây dựng bảng:

![](/files/024deec5b91822c441eddd8e9b0eb50679a860ae)

## Dạng tổng quát của \halign và \valign

Trước hết, chúng ta sẽ xem lại các tính chất cơ bản và định dạng tổng quát của `\halign` và `\valign` nhưng chưa đi sâu vào bất kỳ chi tiết thực sự nào. [Như đã lưu ý](#intro), chúng ta trình bày cái nhìn tổng quan hơi mang tính hình thức về dạng/cấu trúc của các `\halign` và `\valign` lệnh để đặt nền tảng cho các bài tiếp theo trong loạt bài này.

Dạng tổng quát nhất của các `\halign` và `\valign` lệnh có thể được viết như sau:

`\halign` $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ { $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ $$\langle$$⁠`phần thân`⁠$$\rangle$$ }

`\valign` $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ { $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ $$\langle$$⁠`phần thân`⁠$$\rangle$$ }

Như bạn thấy, cả hai `\halign` và `\valign` đều gồm ba phần chính:

* [$$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$](#optspec)
* [$$\langle$$⁠`phần mở đầu`⁠$$\rangle$$](#preamble)
* [$$\langle$$⁠`phần thân`⁠$$\rangle$$](#body)

## Tính năng $$\langle$$⁠thông số tùy chọn⁠$$\rangle$$

Kích thước/độ lớn mặc định của một bảng, cái gọi là “kích thước tự nhiên”, được xác định bởi nội dung của nó—để làm rõ, ở đây kích thước/độ lớn mà chúng ta muốn nói đến là

* trang *chiều rộng* của một bảng được tạo bởi `\halign`, hoặc
* trang *chiều cao* của một bảng được tạo bởi `\valign`

Một $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ có thể được dùng để “ghi đè” kích thước tự nhiên của bảng và có một trong hai dạng sau:

* **`sang`** $$\langle$$**⁠`kích thước`⁠**$$\rangle$$
* **`spread`** $$\langle$$**⁠`kích thước`⁠**$$\rangle$$

trong đó

* $$\langle$$**⁠`kích thước`⁠**$$\rangle$$ là một độ dài được cho theo các đơn vị TeX hiểu được, chẳng hạn pt, mm hoặc cm—độ dài này cũng có thể được chỉ định bằng một lệnh mở rộng thành một giá trị được nêu bằng các đơn vị thích hợp;
* **`sang`** và **`spread`** là các từ khóa của TeX chỉ định kiểu “ghi đè” kích thước tự nhiên:
  * **`sang`**: đặt kích thước của bảng thành $$\langle$$⁠`kích thước`⁠$$\rangle$$ giá trị
  * **`spread`**: cộng thêm $$\langle$$⁠`kích thước`⁠$$\rangle$$ giá trị được chỉ định vào kích thước tự nhiên của bảng

Tác dụng của một $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ phụ thuộc vào kiểu bảng đang được dàn trang: nó sẽ điều chỉnh một `\halign` kích thước tự nhiên của bảng *chiều rộng*, hoặc một `\valign` kích thước tự nhiên của bảng *chiều cao*.

Sau đây là một vài ví dụ:

* `\halign **to 100pt**{...}`: đặt `\halign` chiều rộng của bảng thành `100pt`
* `\valign **to 50pt**{...}`: đặt `\valign` chiều cao của bảng thành `30pt`
* `\halign **spread 30pt**{...}`: cộng thêm 30pt vào `\halign` chiều rộng tự nhiên của bảng. Ngược lại, viết **spread -30pt** sẽ làm giảm chiều rộng của bảng đi 30pt.
* `\valign **spread 20pt**{...}`: cộng thêm 20pt vào `\valign` chiều cao tự nhiên của bảng. Ngược lại, viết **spread -20pt** sẽ làm giảm chiều cao của bảng đi 20pt.

Đoạn mã sau tái sử dụng các ví dụ bảng ở trên nhưng áp dụng một $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ vào một `\valign` và `\halign` bảng:

```latex
\documentclass{article}
\begin{document}
\pagestyle{empty}
% Viền hộp khít sát
\setlength{\fboxsep}{0pt}

Đây là một bảng \verb|\valign|:
\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign to 50pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup

Đây là một bảng \verb|\halign|:
\fbox{
\vbox{\halign to 100pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}}
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Basic+table+example\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%25+Close-fitting+box+borders+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table%3A+%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign+to+50pt%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%0AHere+is+an+%5Cverb%7C%5Chalign%7C+table%3A%0A%5Cfbox%7B%25%0A%5Cvbox%7B%5Chalign+to+100pt%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả hiển thị bên dưới:

![](/files/3823913b07683f9b3da6e9bb41076ba76489dd77)

—nhưng lưu ý rằng nội dung của cả hai bảng đều bị “co cụm lại”. Lý do là thiếu khoảng cách linh hoạt (glue) mà TeX có thể dùng để giãn nội dung ra nhằm lấp đầy khoảng trống bổ sung do **`sang`** $$\langle$$**⁠`kích thước`⁠**$$\rangle$$. Ở đây chúng ta sẽ nói trước đến `\tabskip` lệnh này.

#### Giới thiệu sơ bộ về lệnh \tabskip

Tính thẩm mỹ của bố cục bảng có thể đòi hỏi điều chỉnh khoảng cách giữa các hàng hoặc cột, nên không có gì ngạc nhiên khi các bộ máy TeX cung cấp một lệnh gọi là `\tabskip` cho phép bạn làm điều đó. `\tabskip` được dùng để đặt (và thay đổi) lượng khoảng trắng linh hoạt (“glue”) mà TeX đặt giữa các cột của một `\halign` hoặc giữa các hàng của một `\valign`. Các bài sau sẽ khám phá `\tabskip` chi tiết hơn nhiều.

Là một ví dụ giới thiệu, đoạn mã sau sử dụng thiết lập cho `\tabskip` khiến TeX chèn một ít khoảng trắng (rất) linh hoạt giữa các hàng của một `\valign` bảng. Khoảng trắng linh hoạt đó cho phép các hàng của bảng trải ra và lấp đầy khoảng trống bổ sung được tạo bởi $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ của **`đến 50pt`**:

```latex
\documentclass{article}
\setlength{\fboxsep}{0pt}
\setlength{\parindent}{0pt}
\newcommand{\optspec}{\(\langle \texttt{thông số tùy chọn} \rangle\)}
\begin{document}
\pagestyle{empty}
Đây là một bảng \verb|\valign|:
\vspace{6pt}

\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup
\vspace{6pt}

Đây là cùng một bảng \verb|\valign| nhưng với \optspec{} là ``\texttt{to 50pt}''. Lưu ý các hàng bị ``dồn chặt'' vì không có ``glue có thể kéo giãn'' sẵn có giữa các hàng:

\vspace{6pt}
\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign to 50pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup
\vspace{6pt}

Chúng ta sẽ dùng bảng \verb|\valign| với \optspec{} là ``\texttt{to 50pt}'', nhưng cung cấp ``khoảng cách linh hoạt'' thông qua lệnh \verb|\tabskip|. Ở đây, \verb|\tabskip| đang cung cấp đủ ``glue'' để cho phép các hàng của \verb|\valign| ``giãn ra'' và lấp đầy mọi khoảng trống bổ sung có sẵn. Đây là bảng \verb|\valign| ``đã giãn ra'':

\tabskip=0pt plus1fil % Điều này đặt \tabskip thành một glue rất linh hoạt
\vspace{6pt}

\def\mylen{50pt}
\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign to \mylen{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Basic+example+using+tabskip+glue\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%5Csetlength%7B%5Cparindent%7D%7B0pt%7D%0A%5Cnewcommand%7B%5Coptspec%7D%7B%5C%28%5Clangle+%5Ctexttt%7Boptional+specification%7D+%5Crangle%5C%29%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table%3A%0A%5Cvspace%7B6pt%7D%0A%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cvspace%7B6pt%7D%0A%0AHere+is+the+same+%5Cverb%7C%5Cvalign%7C+table+but+with+an+%5Coptspec%7B%7D+of+%60%60%5Ctexttt%7Bto+50pt%7D%27%27.+Note+how+the+rows+are+%60%60bunched+up%27%27+because+there%27s+no+available+%60%60stretchable+glue%27%27+between+the+rows%3A+%0A%0A%5Cvspace%7B6pt%7D%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign+to+50pt%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cvspace%7B6pt%7D%0A%0AWe%27ll+use+the+%5Cverb%7C%5Cvalign%7C+table+with+%5Coptspec%7B%7D+of+%60%60%5Ctexttt%7Bto+50pt%7D%27%27%2C+but+provide+%60%60flexible+spacing%27%27+via+the+%5Cverb%7C%5Ctabskip%7C+command.+Here%2C+%5Cverb%7C%5Ctabskip%7C+is+providing+enough+%60%60glue%27%27+to+enable+the++%5Cverb%7C%5Cvalign%7C+rows+to++%60%60stretch+out%27%27+and+fill+any+available+extra+space.+Here+is+the+%60%60stretched+out%27%27+%5Cverb%7C%5Cvalign%7C+table%3A%0A%0A%5Ctabskip%3D0pt+plus1fil+%25+This+sets+%5Ctabskip+to+a+very+flexible+glue%0A%5Cvspace%7B6pt%7D%0A%0A%5Cdef%5Cmylen%7B50pt%7D%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign+to+%5Cmylen%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/38070834b17e521c6022717e735774f7e1f86cb3)

## Giới thiệu về bảng $$\langle$$⁠phần tiền đề⁠$$\rangle$$ và $$\langle$$⁠phần thân⁠$$\rangle$$

Phần này giới thiệu phần tiền đề của bảng $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$, và *một cách ngắn gọn* đề cập sơ lược đến phần tiền đề của bảng $$\langle$$⁠`phần thân`⁠$$\rangle$$ mà sau đó [được khám phá chi tiết hơn](#bodydetails).

Các bài viết sau trong loạt bài này sẽ khám phá $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ và $$\langle$$⁠`phần thân`⁠$$\rangle$$ chi tiết hơn, đặc biệt là cách TeX sử dụng và xử lý phần tiền đề của bảng $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$.

Như đã nêu ở trên, định dạng tổng quát nhất của `\halign` hoặc `\valign` các bảng có thể được viết như sau:

`\halign` $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ { $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ $$\langle$$⁠`phần thân`⁠$$\rangle$$ }

`\valign` $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ { $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ $$\langle$$⁠`phần thân`⁠$$\rangle$$ }

### Tính năng $$\langle$$⁠phần tiền đề⁠$$\rangle$$

Tính năng $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ phần này chứa một $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$ vốn là *được kết thúc* bởi `\cr` lệnh; do đó, $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ có thể được viết lại như sau:

$$\langle$$⁠`phần mở đầu`⁠$$\rangle$$=$$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$**`\cr`**

### Tính năng $$\langle$$⁠phần thân⁠$$\rangle$$

Tương tự, tệp $$\langle$$⁠phần thân⁠$$\rangle$$ phần này có thể được chia nhỏ hơn nữa thành một hoặc nhiều “dòng” thành phần, nhưng ở đây mỗi dòng có hai lựa chọn:

* một dòng gồm một tập hợp các ô tạo thành một `\halign` hàng hoặc `\valign` cột; hoặc
* a `\noalign` lệnh “chèn” vật liệu giữa các `\halign`'s các hàng hoặc `\valign`'s các cột.

Trong phạm vi hiện tại chúng ta sẽ bỏ qua `\noalign` lệnh (xem [sau này trong bài viết](#noalign)) và giả sử mỗi dòng của $$\langle$$⁠phần thân⁠$$\rangle$$ là dữ liệu cho một tập hợp các ô và *được kết thúc* được `\cr` lệnh này.

Bỏ qua `\noalign`, còn $$\langle$$⁠`phần thân`⁠$$\rangle$$ phần, phần này đại diện cho nội dung do người dùng cung cấp, chứa một chuỗi các dòng, mỗi dòng chúng ta sẽ gọi là một $$\langle$$⁠`dòng thân`⁠$$\rangle$$ được *được kết thúc* bởi dòng tiền đề đi kèm của nó `\cr` lệnh này.

Tính năng $$\langle$$⁠`phần thân`⁠$$\rangle$$ có thể được viết lại như sau:

$$\langle$$⁠dòng thân$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠dòng thân$${}*\mathrm{N}$$⁠$$\rangle$$\cr

Ghép tất cả lại, chúng ta có thể viết lại dạng tổng quát của `\halign` và `\valign` như sau:

`\halign` $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ { $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠dòng thân$${}*\mathrm{N}$$⁠$$\rangle$$\cr }

`\valign` $$\langle$$⁠`thông số tùy chọn`⁠$$\rangle$$ { $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠dòng thân$${}*\mathrm{N}$$⁠$$\rangle$$\cr }

Vì những lý do sẽ được đề cập trong các bài sau, $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$, chỉ một $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$, có định dạng khác với tất cả các dòng khác trong bảng $$\langle$$⁠`phần thân`⁠$$\rangle$$. Chúng ta cũng sẽ [xem lại `\noalign` lệnh](#noalign) cũng có thể được dùng bên trong bảng $$\langle$$⁠`phần thân`⁠$$\rangle$$.

### Tính năng $$\langle$$⁠dòng tiền đề⁠$$\rangle$$

Tính năng $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$ đóng vai trò *thiết yếu* trong việc dàn trang bảng vì nó cung cấp một dạng “bản thiết kế” dùng để dàn trang nội dung—`\halign` các hàng hoặc `\valign` các cột—có trong bảng $$\langle$$⁠`phần thân`⁠$$\rangle$$. Gói $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$ cũng có thể chứa các “mẫu” ô được dùng để xây dựng các hàng của một `\halign` hoặc các cột của một `\valign`—một chủ đề sẽ được khám phá chi tiết.

Mục đích của $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$ là hai mặt:

* nó xác định *giá trị lớn nhất* số lượng ô mỗi hàng của một `\halign` hoặc mỗi cột của một `\valign`.
* nó lưu trữ *các mẫu ô* có thể được dùng để tự động hóa việc định dạng hoặc chèn nội dung trong các ô chứa trong bảng $$\langle$$⁠`phần thân`⁠$$\rangle$$. Các mẫu ô là tùy chọn và có thể “trống”, hoặc bạn có thể đưa vào các ký tự hay lệnh mà TeX sẽ tự động chèn trước và/hoặc sau nội dung thực tế của các ô cụ thể trong bảng. Điều này giúp bạn khỏi phải mất công tự viết/chèn các ký tự hay lệnh đó vào mọi ô mà bạn muốn áp dụng.

**Lưu ý**: một `\halign` hàng hoặc `\valign` cột có thể chứa ít ô hơn mức tối đa được chỉ định bởi $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$ nhưng không thể chứa nhiều hơn mức tối đa đó, nếu không TeX sẽ báo lỗi. Trong phạm vi hiện tại, chúng ta lược bỏ chi tiết về *tuần hoàn* các phần tiền đề.

Tiếp tục với các sơ đồ cấu trúc của chúng ta, bảng $$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$ cho

* một `\halign` với tối đa $$\mathrm{K}$$ ô mỗi *hàng*, hoặc
* a `\valign` với tối đa $$\mathrm{K}$$ ô mỗi *cột*

có thể được viết như sau:

$$\langle$$⁠mẫu$${}\_1$$⁠$$\rangle$$&$$\langle$$⁠mẫu$${}\_2$$⁠$$\rangle$$&$$\langle$$⁠mẫu$${}*3$$⁠$$\rangle$$ $$\cdots$$ &$$\langle$$⁠mẫu$${}*\mathrm{K}$$⁠$$\rangle$$

trong đó `&` là *ký tự tab căn chỉnh* để chỉ ra kết thúc của một ô và bắt đầu của ô tiếp theo. Theo truyền thống, ký tự dấu và (`&`) được dùng làm tab căn chỉnh nhưng bất kỳ ký [mã loại](/latex/vi/chu-de-khac/43-table-of-tex-category-codes.md) 4 cũng có thể được dùng thay thế.

Nhắc lại, phần $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ có thể được viết $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$=$$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$**`\cr`**, hoặc tương đương

$$\langle$$⁠`phần mở đầu`⁠$$\rangle$$=$$\langle$$⁠mẫu$${}\_1$$⁠$$\rangle$$&$$\langle$$⁠mẫu$${}\_2$$⁠$$\rangle$$&$$\langle$$⁠mẫu$${}*3$$⁠$$\rangle$$ $$\cdots$$ &$$\langle$$⁠mẫu$${}*\mathrm{K}$$⁠$$\rangle$$**`\cr`**

#### Cấu trúc của từng ô $$\langle$$⁠mẫu⁠$$\rangle$$

Mỗi ô $$\langle$$⁠mẫu$${}\_i$$⁠$$\rangle$$ có thể được viết như sau:

$$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ trong đó:

* $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$ là một tập hợp các ký tự hoặc lệnh (tokens) mà TeX sẽ tự động chèn *trước khi* nội dung do người dùng cung cấp cho ô $$i$$;
* $$\texttt{#}$$ là phần giữ chỗ, cho biết nội dung do người dùng cung cấp sẽ xuất hiện ở ô $$i$$. Một lần nữa, ký tự `#` chỉ là một *quy ước*, bất kỳ ký tự nào có [mã loại](/latex/vi/chu-de-khac/43-table-of-tex-category-codes.md) 6 cũng có thể được dùng thay thế. Lưu ý rằng mã loại 6 được dùng cho tham số macro;
* $$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ là một tập hợp các ký tự hoặc lệnh (tokens) mà TeX sẽ tự động chèn *sau* nội dung do người dùng cung cấp cho ô $$i$$.

Lưu ý rằng tất cả $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$ và $$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ đang *tùy chọn*: bạn không cần dùng bất kỳ ký tự hay lệnh nào trước hoặc sau nội dung của ô.

**Hoàn thiện** $$\langle$$**⁠phần tiền đề⁠**$$\rangle$$

Cuối cùng, dùng ký hiệu ở trên, bảng $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ cho

* một `\halign` với tối đa $$\mathrm{K}$$ ô mỗi *hàng*, hoặc
* a `\valign` với tối đa $$\mathrm{K}$$ ô mỗi *cột*

có thể được viết như sau:

$$\langle$$⁠`phần mở đầu`⁠$$\rangle$$=$$\langle$$⁠`dòng tiền đề`⁠$$\rangle$$`**\cr**`

hoặc

$$\langle$$⁠`phần mở đầu`⁠$$\rangle$$=$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}*3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*3$$⁠$$\rangle$$$$\cdots$$$$\langle$$⁠$$\texttt{U}*\mathrm{K}$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*\mathrm{K}$$⁠$$\rangle$$`**\cr**`

**Tính năng** $$\langle$$**⁠phần tiền đề⁠**$$\rangle$$ **và việc đếm hàng và cột**

Một **`\halign`** bảng với $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ chỉ định $$\mathrm{K}$$ ô và một $$\langle$$⁠`phần thân`⁠$$\rangle$$ chứa $$\mathrm{N}$$ $$\langle$$⁠`các dòng thân`⁠$$\rangle$$ sẽ tạo ra một bảng với $$\mathrm{K}$$ *cột* và $$\mathrm{N}$$ *hàng*, như được cho thấy trong sơ đồ sau:

![](/files/b45e17f6b2723b88eb08658fd459d94f20480e54)

Một **`\valign`** bảng với $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ chỉ định $$\mathrm{K}$$ ô và một $$\langle$$⁠`phần thân`⁠$$\rangle$$ chứa $$\mathrm{N}$$ $$\langle$$⁠`các dòng thân`⁠$$\rangle$$ sẽ tạo ra một bảng với $$\mathrm{K}$$ *hàng* và $$\mathrm{N}$$ *cột*, như được cho thấy trong sơ đồ sau:

![](/files/bc5c9d68634ce44f32118fff7e99b1471ccfd899)

### Đủ lý thuyết rồi, đến vài ví dụ nhé!

Như chúng ta sẽ thấy chi tiết hơn sau này, khi TeX xử lý nội dung của một bảng—các ô bảng chứa trong [$$\langle$$⁠`phần thân`⁠$$\rangle$$](#body)—nó kiểm tra xem có mẫu ô nào hay không, vốn đã được định nghĩa trong $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$, vì TeX đang tìm bất kỳ token mẫu nào để chèn trước và/hoặc sau nội dung của người dùng. Các ví dụ tối thiểu sau minh họa việc sử dụng mẫu ô $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ trong một `\halign` và `\valign` bảng.

#### Một bảng \halign sử dụng mẫu ô

Ví dụ sau minh họa một `\halign` bảng dùng một mẫu ô để tự động chèn dấu ngoặc kép quanh nội dung của ô đầu tiên trong mỗi hàng: tức là một mẫu ảnh hưởng đến mọi ô trong cột đầu tiên:

```latex
\documentclass{article}
\usepackage{parskip} % Đặt \parindent thành 0pt
% Chọn cỡ trang đủ nhỏ một cách tiện lợi
\usepackage[paperheight=10cm,paperwidth=12cm,textwidth=8cm]{geometry}
\setlength{\tabskip}{20pt} % Tạo khoảng cách giữa các cột của \halign
\begin{document}
\pagestyle{empty}

Đây là một bảng \verb|\halign| \textit{không có} mẫu ô:

\halign{
% Không có gì trước hoặc sau mỗi '#' trong the <preamble>
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}

Đây là cùng một bảng \verb|\halign| nhưng với dấu ngoặc kép tự động được thêm vào ô đầu tiên trong mỗi hàng; tức là nó ảnh hưởng đến mọi ô trong cột đầu tiên:

\halign{
% Các mẫu dấu ngoặc kép trong phần tiền đề:
``#''&#&#\cr % Dấu ngoặc kép trước và sau # đầu tiên
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=halign+example+of+cell+templates\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D10cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D8cm%5D%7Bgeometry%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B20pt%7D+%25+Space+out+the+%5Chalign+columns%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%0AHere+is+an+%5Cverb%7C%5Chalign%7C+table+%5Ctextit%7Bwithout%7D+cell+templates%3A+%0A%0A%5Chalign%7B%0A%25+Nothing+before+or+after+each+%27%23%27+in+the+%3Cpreamble%3E%0A%23%26%23%26%23%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%0AHere+is+the+same+%5Cverb%7C%5Chalign%7C+table+but+with+double+quotes+automatically+added+to+the+first+cell+in+each+row%3B+i.e.%2C+it+affects+every+cell+in+the+first+column%3A+%0A%0A%5Chalign%7B%0A%25+Quotation+templates+in+the+preamble%3A%0A%60%60%23%27%27%26%23%26%23%5Ccr+%25+Double+quote+marks+before+and+after+first+%23%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/3bfed1c7c3df2133be824283207644710775333c)

Hình minh họa sau là phiên bản có chú thích của `\halign` bảng được tạo bởi ví dụ ở trên; ở đây, chúng ta so sánh cấu trúc “hình thức” của một $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$`**\cr**`

ba ô với dạng thực tế $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ của ` ``#''&#&#**\cr** `, làm nổi bật sự hiện diện hoặc vắng mặt của các mẫu ô:

![](/files/bd7840fceca763df6c31f07a40286f530770da59)

#### Một bảng \valign sử dụng mẫu ô

Ví dụ sau minh họa một `\valign` bảng dùng một mẫu cho mọi ô để tự động chèn các chữ số bao quanh nội dung của người dùng.

```latex
\documentclass{article}
\usepackage{parskip} % Đặt \parindent thành 0pt
% Chọn cỡ trang đủ nhỏ một cách tiện lợi
\usepackage[paperheight=14cm,paperwidth=12cm,textwidth=10cm]{geometry}
\setlength{\tabskip}{8pt} % Tạo khoảng cách giữa các hàng của \valign
\begin{document}
\pagestyle{empty}

Đây là một bảng \verb|\valign| \textit{không có} mẫu ô:

\begingroup
\hsize=25pt
\valign{
% Không có gì trước hoặc sau mỗi '#' trong
% phần tiền đề
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup

Đây là cùng một bảng \verb|\valign| nhưng dùng mẫu ô để tự động chèn các chữ số vào mọi ô:

\begingroup
\hsize=25pt
\valign{
% Các chữ số được chèn trước và sau mọi '#' trong
% phần tiền đề
1#2&3#4&5#6\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+of+valign+cell+templates\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D14cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B8pt%7D+%25+Space+out+the+%5Cvalign+rows%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table+%5Ctextit%7Bwithout%7D+cell+templates%3A%0A%0A%5Cbegingroup%0A%5Chsize%3D25pt%0A%5Cvalign%7B%0A%25+Nothing+before+or+after+each+%27%23%27+in+%0A%25+the+%3Cpreamble%3E%0A%23%26%23%26%23%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cendgroup%0A%0AHere+is+the+same+%5Cverb%7C%5Cvalign%7C+table+but+using+cell+templates+to+automatically+insert+digits+into+every+cell%3A+%0A%0A%5Cbegingroup%0A%5Chsize%3D25pt%0A%5Cvalign%7B%0A%25+Digits+inserted+before+and+after+every+%27%23%27+in%0A%25+the+%3Cpreamble%3E%0A1%232%263%234%265%236%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/1306aac2abe713c3c226bc34ca034922db63f673)

Hình minh họa sau là phiên bản có chú thích của `\valign` bảng được tạo bởi ví dụ ở trên; ở đây, chúng ta so sánh cấu trúc “hình thức” của một $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$`**\cr**`

ba ô với dạng thực tế $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ của `1#2&3#4&5#6**\cr**`, làm nổi bật việc sử dụng mẫu ô $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$:

![](/files/a4f7daf4957de6ba2d2a4962a98e508408188b97)

Lưu ý cách mẫu cho ô $$i$$ ($$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$) được áp dụng cho $$i$$ô thứ `\valign` cột, khiến tất cả các ô của $$i$$thứ *hàng* đều bị ảnh hưởng.

#### Định kiểu văn bản bằng mẫu ô

Ví dụ tiếp theo sử dụng các $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ (mẫu ô) sau để định kiểu văn bản chứa trong mỗi hàng hoặc cột:

`\textbf{#}&\textit{#}&\texttt{#}\cr`

Nếu chúng ta so sánh điều này $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ với cấu trúc “hình thức” của một $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$`**\cr**`

chúng ta có thể thấy rằng:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$=`\textbf{`

$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$=`}`

$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$=`\textit{`

$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$=`}`

$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$=`\texttt{`

$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$=`}`

Hãy chú ý cách các mẫu ô này, chẳng hạn như `\textbf{#}` trông giống các macro với một tham số duy nhất (nội dung ô).

```latex
Một bảng \verb|\valign| với văn bản được định dạng bằng các mẫu ô:

\begingroup
\hsize=25pt
\valign{
\textbf{#}&\textit{#}&\texttt{#}\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup

Một bảng \verb|\halign| với văn bản được định dạng bằng các mẫu ô:

\halign{
\textbf{#}&\textit{#}&\texttt{#}\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Styling+with+cell+templates\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D14cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%25+Space+out+the+%5Chalign+columns+or+%5Cvalign+rows%0A%5Csetlength%7B%5Ctabskip%7D%7B8pt%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0AA+%5Cverb%7C%5Cvalign%7C+table+with+text+styled+using+cell+templates%3A%0A%0A%5Cbegingroup%0A%5Chsize%3D25pt%0A%5Cvalign%7B%0A%5Ctextbf%7B%23%7D%26%5Ctextit%7B%23%7D%26%5Ctexttt%7B%23%7D%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cendgroup%0A%0AAn+%5Cverb%7C%5Chalign%7C+table+with+text+styled+using+cell+templates%3A%0A%0A%5Chalign%7B%0A%5Ctextbf%7B%23%7D%26%5Ctextit%7B%23%7D%26%5Ctexttt%7B%23%7D%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/f617019ec6dd91221a8d5e26f66795da1aed414d)

## Chi tiết hơn về bảng $$\langle$$⁠phần thân⁠$$\rangle$$

Trong phần [Giới thiệu về bảng $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ và $$\langle$$⁠`phần thân`⁠$$\rangle$$](#preamble) chúng ta đã thấy rằng, nếu tạm thời bỏ qua `\noalign`, còn $$\langle$$⁠`phần thân`⁠$$\rangle$$ của một `\halign` hoặc `\valign` bảng gồm nhiều dòng, mỗi dòng được xác định $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$, trong đó:

* mỗi $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$ được kết thúc bởi `\cr` lệnh
* mỗi $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$ của một `\halign` là một hàng của bảng
* mỗi $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$ của một `\valign` là một cột của bảng

Chuỗi các dòng, $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$, trong đó $$j=1\ldots\mathrm{N}$$, tạo ra $$\mathrm{N}$$ các hàng của một `\halign` hoặc $$\mathrm{N}$$ các cột cho một `\valign`. Như được tóm tắt trong sơ đồ sau, một general $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ như

$$\langle$$⁠`phần mở đầu`⁠$$\rangle$$=$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}*3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*3$$⁠$$\rangle$$$$\cdots$$$$\langle$$⁠$$\texttt{U}*\mathrm{K}$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*\mathrm{K}$$⁠$$\rangle$$`**\cr**`

xác định các mẫu ô cho tối đa $$\mathrm{K}$$ ô trong mỗi của $$\mathrm{N}$$ $$\langle$$⁠`dòng thân`⁠$$\rangle$$ mục nhập trong $$\langle$$⁠`phần thân`⁠$$\rangle$$:

![](/files/a638aed264ab93df7dec734107a4517eb632c264)

### Cấu trúc của mỗi $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$

Mỗi dòng $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$ của bảng $$\langle$$⁠phần thân⁠$$\rangle$$ chứa nội dung cho tối đa $$\mathrm{K}$$ ô—như được xác định bởi $$\langle$$⁠phần tiền đề⁠$$\rangle$$—và có dạng tổng quát:

$$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$=$$\langle$$Ô$${}\_1$$⁠$$\rangle$$$$\texttt{&}$$$$\langle$$Ô$${}\_2$$⁠$$\rangle$$$$\texttt{&}$$$$\langle$$Ô$${}*3$$⁠$$\rangle$$$$\texttt{&}$$$$\cdots$$$$\texttt{&}$$$$\langle$$Ô$${}*\mathrm{K}$$⁠$$\rangle$$`**\cr**`

trong đó:

* $$\langle$$Ô$${}\_i$$⁠$$\rangle$$ đại diện cho nội dung của người dùng cho $$i$$ô thứ trong một $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$
* trang **`&`** ký tự được gọi là *tab căn chỉnh* (giống như dùng trong $$\langle$$⁠phần tiền đề⁠$$\rangle$$) để báo hiệu kết thúc của một ô và bắt đầu ô tiếp theo. Một lần nữa, việc dùng **`&`** chỉ là một truyền thống (quy ước) vì bất kỳ ký tự nào với [mã loại](/latex/vi/chu-de-khac/43-table-of-tex-category-codes.md) 4 cũng có thể được dùng thay thế.

Mặc dù mỗi $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$ có thể chứa tối đa $$\mathrm{K}$$ ô (được xác định bởi $$\langle$$⁠phần tiền đề⁠$$\rangle$$) chúng có thể chứa *ít hơn* hơn $$\mathrm{K}$$ ô và bất kỳ $$\langle$$Ô$${}\_i$$⁠$$\rangle$$ trong $$\langle$$⁠dòng thân$${}\_j$$⁠$$\rangle$$ có thể để trống.

Ví dụ sau minh họa một $$\langle$$⁠phần tiền đề⁠$$\rangle$$ của `#&#&#&#&#\cr` điều này cho phép tối đa 5 ô cho mỗi $$\langle$$dòng thân$$\rangle$$; tuy nhiên, các bảng được dàn trang chứa các dòng với ít hơn 5 ô:

```latex
Một bảng \verb|\valign| với từ 1 đến 5 ô cho mỗi \textit{cột}:

\begingroup
% \hsize điều khiển độ rộng cột của \valign (kích thước các dòng được dàn trang).
\hsize=40pt
\fbox{\valign{
% Dùng phần mở đầu cho phép 5 ô mỗi cột
% Hầu hết các cột không cung cấp nội dung cho 5 ô
#&#&#&#&#\cr% 5 ô mỗi cột
\(\mathrm{Cell}{}_1\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)&\(\mathrm{Cell}{}_5\)\cr
}}
\endgroup

% Lưu ý: vì những lý do sẽ được giải thích sau
% \halign phải được đặt trong một \vbox
Một bảng \verb|\halign| với từ 1 đến 5 ô cho mỗi \textit{hàng}:

\fbox{
\vbox{\halign{
% Dùng phần mở đầu cho phép 5 ô mỗi hàng
% Hầu hết các hàng không cung cấp nội dung cho 5 ô
#&#&#&#&#\cr % 5 ô mỗi hàng
\(\mathrm{Cell}{}_1\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)&\(\mathrm{Cell}{}_5\)\cr
}}}
```

[Mở ví dụ này trong Overleaf](/latex/vi/bai-viet-chuyen-sau/15-how-do-tex-engines-typeset-tables-2.md)

Ví dụ này tạo ra kết quả sau:

![](/files/2bf748c52264c8648014de02e31fd0c979c362c7)

Tiếp theo, `\halign` ví dụ minh họa số lượng ô thay đổi trên mỗi hàng và khả năng để ô trống—hãy chú ý ô trống được tạo ra bởi các **`&`** ký tự liên tiếp trong bảng:

```latex
Một bảng \verb|\halign| với một số ô trống---lưu ý có các ký tự \texttt{\&} liên tiếp trong bảng \(\langle\texttt{body}\rangle\):

\fbox{
\vbox{\halign{
% Dùng phần mở đầu cho phép 5 ô mỗi hàng
% Hầu hết các hàng không cung cấp nội dung cho 5 ô
#&#&#&#&#\cr % 5 ô mỗi hàng
\(\mathrm{Cell}{}_1\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)\cr
\(\mathrm{Cell}{}_1\)&&\(\mathrm{Cell}{}_3\)\cr
&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&&&\(\mathrm{Cell}{}_5\)\cr
}}}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Empty+cells+Number+of+cells+per+row\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D8cm%5D%7Bgeometry%7D%0A%25+Space+out+the+%5Chalign+columns+and+%5Cvalign+rows%0A%5Csetlength%7B%5Ctabskip%7D%7B8pt%7D+%0A%25+Close-fitting+box+borders+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%5Cbegin%7Bdocument%7D%0AAn+%5Cverb%7C%5Chalign%7C+table+with+some+empty+cells---note+there+are+consecutive+%5Ctexttt%7B%5C%26%7D+characters+in+the+table+%5C%28%5Clangle%5Ctexttt%7Bbody%7D%5Crangle%5C%29%3A%0A%0A%5Cfbox%7B%25%0A%5Cvbox%7B%5Chalign%7B%0A%25+Use+a+preamble+that+allows+for+5+cells+per+row%0A%25+Most+rows+don%27t+provide+content+for+5+cells%0A%23%26%23%26%23%26%23%26%23%5Ccr+%25+5+cells+per+row%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%5Ccr+%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_2%5C%29%5Ccr%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%26%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_3%5C%29%5Ccr%0A%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_2%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_3%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_4%5C%29%5Ccr%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_2%5C%29%26%26%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_5%5C%29%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/5c549606718e7576e2c3a400673b58681a890023)

### Không có gì đặc biệt về & và # trong dàn trang bảng

Việc TeX sử dụng các ký tự `&` và `#` trong quá trình dàn trang `\halign`- hoặc `\valign`-dựa trên là một truyền thống bắt nguồn từ các macro plain TeX gốc của Knuth. Hoàn toàn có thể dùng các ký tự khác ngoài `&` và `#` bằng cách gán mã phân loại thích hợp cho các ký tự thay thế bạn chọn, như ví dụ sau minh họa:

* thay thế `&` với `@` bằng cách gán `@` cho mã phân loại 4
* thay thế `#` với `|` bằng cách gán `|` cho mã phân loại 6 (được dùng cho tham số macro)

Các thay đổi mã phân loại được giữ cục bộ bằng cách dùng `\begingroup` và `\endgroup`:

```latex
\documentclass{article}
\begin{document}
\begingroup
\catcode`@=4
\catcode`|=6
\halign{
|@|@|\cr
A@B@C\cr
D@E@F\cr
}
\endgroup
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Tables+and+category+codes\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cbegingroup%0A%5Ccatcode%60%40%3D4%0A%5Ccatcode%60%7C%3D6%0A%5Chalign%7B%0A%7C%40%7C%40%7C%5Ccr%0AA%40B%40C%5Ccr%0AD%40E%40F%5Ccr%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

## Giới thiệu lại lệnh \noalign

Các bộ máy TeX cung cấp sẵn (nguyên thủy) `\noalign` lệnh:

`\noalign{`$$\langle$$⁠`token`⁠$$\rangle$$`}`

trong đó $$\langle$$⁠`token`⁠$$\rangle$$ là các ký tự và/hoặc lệnh TeX/LaTeX. Lệnh `\noalign` chỉ dành để dùng bên trong một `\halign` hoặc `\valign` bảng: dùng nó bên ngoài những ngữ cảnh này sẽ tạo ra lỗi.

Mục đích của `\noalign` là cho phép "chèn" văn bản và các lệnh TeX/LaTeX *giữa* các hàng của một `\halign` bảng hoặc các cột của một `\valign` bảng. Cách dùng phổ biến nhất của `\noalign` là tạo các đường kẻ bảng (đường thẳng):

* *ngang* đường kẻ giữa `\halign` các hàng của bảng
* *dọc* đường kẻ giữa `\valign` các cột của bảng

Lưu ý những điều sau:

* trang `\noalign` lệnh là ***không được kết thúc bởi\*\*\*\*****&#x20;****`\cr`****&#x20;****\*\*\*\*lệnh***
* bộ lệnh được phép bên trong `\noalign{...}` phụ thuộc vào việc nó được dùng trong $$\langle$$⁠`phần thân`⁠$$\rangle$$ của một `\halign` hoặc `\valign` bảng (tức là ở chế độ dọc hoặc ngang).

Bây giờ ta có thể nói rằng bảng $$\langle$$⁠`phần thân`⁠$$\rangle$$ của `\halign` hoặc `\valign` có thể gồm các dòng riêng lẻ $$\langle$$⁠dòng thân$${}\_i$$⁠$$\rangle$$`\cr` đan xen với `\noalign` các lệnh; một trong nhiều khả năng/kết hợp có thể là:

`\noalign{`$$\langle$$⁠`token`⁠$$\rangle$$`}` $$\langle$$⁠dòng thân$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠dòng thân$${}\_2$$⁠$$\rangle$$\cr `\noalign{`$$\langle$$⁠`nhiều token hơn`⁠$$\rangle$$`}` $$\langle$$⁠dòng thân$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠dòng thân$${}*\mathrm{N}$$⁠$$\rangle$$\cr `\noalign{`$$\langle$$⁠`các token khác`⁠$$\rangle$$`}`

### Ví dụ dùng \noalign

Chúng ta sẽ xem các trường hợp sử dụng khác sau trong loạt bài này, nhưng đây là một ví dụ cơ bản để minh họa việc tạo đường kẻ bảng qua `\noalign`:

```latex
\setlength{\tabskip}{5pt}

Dùng \verb|\noalign| để đặt các đường kẻ ngang giữa các hàng của một bảng \verb|\halign|:
\vspace{6pt}

\halign{%
#&#&#&#&#\cr
\noalign{\hrule\kern2pt}
1&2&3&4&5\cr
\noalign{\kern2pt\hrule\kern2pt}
6&7&8&9&10\cr
\noalign{\kern2pt\hrule}
}

Dùng \verb|\noalign| để đặt các đường kẻ dọc giữa các cột của một bảng \verb|\valign|:
\vspace{6pt}

\begingroup % giữ các thay đổi đối với \parindent và \hsize ở phạm vi cục bộ
\parindent=0pt
\hsize=50pt
\valign{%
#&#&#&#&#\cr
\noalign{\vrule\kern2pt}
1&2&3&4&5\cr
\noalign{\kern2pt\vrule\kern2pt}
6&7&8&9&10\cr
\noalign{\kern2pt\vrule}
}
\endgroup
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+of+the+noalign+command\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D%0A%0AUsing+%5Cverb%7C%5Cnoalign%7C+to+place+horizontal+rules+between+rows+of+an+%5Cverb%7C%5Chalign%7C+table%3A%0A%5Cvspace%7B6pt%7D%0A%0A%5Chalign%7B%25%0A%23%26%23%26%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Chrule%5Ckern2pt%7D%0A1%262%263%264%265%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%5Ckern2pt%7D%0A6%267%268%269%2610%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%7D%0A%7D%0A%0AUsing+%5Cverb%7C%5Cnoalign%7C+to+place+vertical+rules+between+columns+of+a+%5Cverb%7C%5Cvalign%7C+table%3A%0A%5Cvspace%7B6pt%7D%0A%0A%5Cbegingroup+%25+keep+changes+to+%5Cparindent+and+%5Chsize+local%0A%5Cparindent%3D0pt%0A%5Chsize%3D50pt%0A%5Cvalign%7B%25%0A%23%26%23%26%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Cvrule%5Ckern2pt%7D%0A1%262%263%264%265%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%5Ckern2pt%7D%0A6%267%268%269%2610%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%7D%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/7185eedc6da3f86f9eaf80e9ec115807a6653ca1)

## Xem lại \tabskip

Chúng ta sẽ xem kỹ hơn `\tabskip` lệnh, dựa trên phần [giới thiệu ở phần trước](#tabskip).

Tính năng `\tabskip` lệnh đặt giá trị của một dạng đặc biệt của "khoảng cách" (glue) được dùng *chỉ* trong dàn trang bảng: mục đích của nó là tạo khoảng cách giữa các hàng hoặc các cột của bảng:

* cho `\halign` các bảng: `\tabskip` glue được chèn trước và sau bảng (tức là bên trái và bên phải) và giữa các cột của bảng
* cho `\valign` các bảng: `\tabskip` glue được chèn trước và sau bảng (tức là ở trên và dưới) và giữa các hàng của bảng

Giá trị của `\tabskip` có thể được đặt bằng lệnh LaTeX `\setlength` lệnh:

`\setlength{\tabskip}{`$$\langle$$⁠`giá trị glue`⁠$$\rangle$$`}`

trong đó $$\langle$$⁠`giá trị glue`⁠$$\rangle$$ có thể là:

* một độ dài cố định như `5pt`, `3mm`, hoặc
* một glue co giãn hữu hạn như `3pt plus 2pt minus 1pt`, hoặc
* một glue co giãn vô hạn như `0pt plus1fill`.

Bạn cũng có thể đặt trực tiếp `\tabskip` (bỏ qua `\setlength`) bằng cách viết

`\tabskip`=$$\langle$$⁠`giá trị glue`⁠$$\rangle$$

Tuy nhiên, mọi thay đổi đối với giá trị của `\tabskip` glue chỉ ảnh hưởng đến khoảng cách trong bảng khi thay đổi đó được:

* thực hiện *trước khi* trang `\halign` hoặc `\valign` lệnh được xử lý, hoặc
* thực hiện bên trong bảng $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$

Các nỗ lực đặt `\tabskip` các giá trị bên trong nội dung bảng (các ô trong bảng $$\langle$$⁠`phần thân`⁠$$\rangle$$) *sẽ không* thay đổi khoảng cách của `\halign` các cột của bảng hoặc `\valign` các hàng của bảng. Lý do cho hành vi này của `\tabskip` có thể truy về vai trò của $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ trong quá trình dàn trang bảng—các quá trình mà sau này chúng ta sẽ khám phá chi tiết hơn.

### Thấy là tin

Để giúp hình dung sự hiện diện của nhiều loại khoảng cách/glue được dùng trong dàn trang bảng, đặc biệt là

* `\tabskip` keo
* `\baselineskip` keo
* kerning thủ công (`\kern`)

Overleaf đã chuẩn bị một dự án dựa trên LuaTeX để tô màu các thành phần của một bảng. LuaTeX được chọn vì nó cho phép xử lý lại ở mức thấp các dữ liệu/cấu trúc nội bộ của các bảng đã dàn trang, nhưng chúng ta sẽ không đi sâu vào các chi tiết đó ở đây.

Dưới đây là một số ví dụ cho thấy nhiều ứng dụng của `\tabskip`. Với mỗi ví dụ, chúng ta sẽ hiển thị đầu ra thực tế và phiên bản được tô màu do LuaTeX tạo ra.

### \tabskip ví dụ 1

Hãy xem xét việc dùng `\tabskip` trong một `\halign` và `\valign` bảng. Chúng ta sẽ hiển thị các bảng được dàn trang thực tế, với một viền để trực quan hóa kích thước và khoảng cách của chúng, cùng với các hình minh họa có chú thích chứa các phiên bản được tô màu, cho thấy rõ kích thước của các loại glue/khoảng cách trong mỗi bảng.

Trước hết, `\halign`:

```latex
% Để trực quan hóa phạm vi của bảng, chúng ta sẽ đặt một đường viền quanh nó
\setlength{\fboxsep}{0pt} % Dùng đường viền ôm sát

% Ở đây chúng ta đặt \tabskip "trực tiếp"
\tabskip5pt % Đặt giá trị \tabskip ban đầu ở bên ngoài bảng

% Để đặt một đường viền quanh bảng, nó phải được lưu vào một hộp TeX.
% Một \halign phải được đặt trong một \vbox vì \halign phải được
% xử lý ở "chế độ dọc": một \hbox sẽ không hoạt động vì
% nó được xử lý ở "chế độ ngang"

\fbox{\vbox{\halign{
\tabskip10pt#&
\tabskip15pt#&
\tabskip20pt#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Tabskip+glue+in+an+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D+%25+sets+%5Cparindent+to+0pt%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%25+To+visualize+the+table%27s+extent+we%27ll+put+a+border+around+it+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D+%25+Use+close-fitting+borders%0A%0A%25+Here+we+set+%5Ctabskip+%22directly%22%0A%5Ctabskip5pt+%25+Set+the+initial+%5Ctabskip+value+outside+the+table%0A%0A%25+To+put+a+border+around+the+table+it+has+to+be+saved+to+a+TeX+box.%0A%25+An+%5Chalign+has+to+be+placed+in+a+%5Cvbox+because+%5Chalign+must+be+%0A%25+processed+in+a+%22vertical+mode%22%3A+an+%5Chbox+will+not+work+because%0A%25+that+is+processed+in+a+%22horizontal+mode%22%0A%0A%5Cfbox%7B%5Cvbox%7B%5Chalign%7B%0A%5Ctabskip10pt%23%26%0A%5Ctabskip15pt%23%26%0A%5Ctabskip20pt%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/ee55b7e2163ee79ee3144b99664a2c60a0723bd9)

Hình minh họa tiếp theo là phiên bản lớn hơn, được tô màu và có chú thích của bảng do ví dụ trước tạo ra:

![](/files/efcd9ae1cd2c38337c1ca0f1cb0168799e49b8c7)

Có 4 lần xuất hiện của `\tabskip` lệnh, mỗi lần tương ứng với một vị trí khoảng cách cụ thể trong bảng:

1. `\tabskip5pt` được dùng bên ngoài bảng và đặt `\tabskip` giá trị áp dụng trước (bên trái) ô đầu tiên trong mỗi hàng.
2. `\tabskip10pt` được đặt trong mẫu ô đầu tiên của $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ điều này ảnh hưởng đến khoảng cách giữa $$\langle$$Ô$${}\_1$$⁠$$\rangle$$ và $$\langle$$Ô$${}\_2$$⁠$$\rangle$$ của mọi hàng.
3. `\tabskip15pt` được đặt trong mẫu ô thứ hai của $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ điều này ảnh hưởng đến khoảng cách giữa $$\langle$$Ô$${}\_2$$⁠$$\rangle$$ và $$\langle$$Ô$${}\_3$$⁠$$\rangle$$ của mọi hàng.
4. `\tabskip20pt` được đặt trong mẫu ô thứ ba, và cuối cùng, của $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ điều này ảnh hưởng đến khoảng cách được thêm sau $$\langle$$Ô$${}\_3$$⁠$$\rangle$$, ô cuối cùng của mọi hàng.

Tiếp theo, `\valign`

```latex
\setlength{\fboxsep}{0pt} % Dùng đường viền ôm sát
\tabskip5pt % Đặt giá trị \tabskip ban đầu ở bên ngoài bảng

% Giữ các thay đổi đối với \hsize ở phạm vi cục bộ (trong một nhóm)
\begingroup
% \hsize xác định độ rộng các cột của \valign
\setlength{\hsize}{50pt}
% Vì \valign có thể được đặt trong một \vbox hoặc \hbox, ta có thể dùng
% trực tiếp \fbox
\fbox{\valign{
\tabskip10pt#&
\tabskip15pt#&
\tabskip20pt#\cr
A&B&C\cr
E&E&F\cr
G&H&I\cr
}}
\endgroup
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D+%25+sets+%5Cparindent+to+0pt%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D+%25+Use+close-fitting+borders%0A%5Ctabskip5pt+%25+Set+the+initial+%5Ctabskip+value+outside+the+table%0A%0A%25+Keep+changes+to+%5Chsize+local+%28in+a+group%29%0A%5Cbegingroup%0A%25+%5Chsize+determines+the+%5Cvalign+column+widths%0A%5Csetlength%7B%5Chsize%7D%7B50pt%7D+%0A%25+Because+%5Cvalign+can+be+placed+in+a+%5Cvbox+or+%5Chbox+we+can+use+%0A%25+%5Cfbox+directly%0A%5Cfbox%7B%5Cvalign%7B%0A%5Ctabskip10pt%23%26%0A%5Ctabskip15pt%23%26%0A%5Ctabskip20pt%23%5Ccr%0AA%26B%26C%5Ccr%0AE%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

![](/files/7c02a5b57082e3d6b342232cde4337706dfe1fd3)

Một lần nữa, hình minh họa tiếp theo là phiên bản lớn hơn, được tô màu và có chú thích của bảng do ví dụ trước tạo ra:

![](/files/e66f0bad03aef01ae6836a1026f9d789000a082e)

Giống như với `\halign` ví dụ, có 4 lần xuất hiện của `\tabskip` lệnh. Tuy nhiên, với một `\valign` bảng `\tabskip` được chèn giữa các hàng của bảng:

1. `\tabskip5pt` được dùng bên ngoài bảng và đặt `\tabskip` giá trị áp dụng trước (ở phía trên) ô đầu tiên trong mỗi cột.
2. `\tabskip10pt` được đặt trong mẫu ô đầu tiên của $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ điều này ảnh hưởng đến khoảng cách giữa $$\langle$$Ô$${}\_1$$⁠$$\rangle$$ và $$\langle$$Ô$${}\_2$$⁠$$\rangle$$ của mỗi cột.
3. `\tabskip15pt` được đặt trong mẫu ô thứ hai của $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ điều này ảnh hưởng đến khoảng cách giữa $$\langle$$Ô$${}\_2$$⁠$$\rangle$$ và $$\langle$$Ô$${}\_3$$⁠$$\rangle$$ của mỗi cột.
4. `\tabskip20pt` được đặt trong mẫu ô thứ ba, và cuối cùng, của $$\langle$$⁠`phần mở đầu`⁠$$\rangle$$ điều này ảnh hưởng đến khoảng cách được thêm sau $$\langle$$Ô$${}\_3$$⁠$$\rangle$$, ô cuối cùng của mỗi cột.

**Tóm tắt/kết luận**

* Trong một `\halign` bảng `\tabskip` glue được đặt bên trái và bên phải mỗi ô trong một hàng, từ đó tạo khoảng cách giữa các cột của bảng.
* Trong một tệp `\valign` bảng `\tabskip` glue được đặt ở trên và dưới mỗi ô trong một cột, từ đó tạo khoảng cách giữa các hàng của bảng.

### \tabskip và \noalign

#### Dùng một \halign

Ví dụ sau `\halign` ví dụ dùng `\tabskip` các glue và cũng minh họa `\noalign` lệnh, dùng nó để đặt các đường kẻ có khoảng cách ở trên và dưới các hàng của một `\halign` bảng. Các đường kẻ đó được dàn trang bằng `\hrule` lệnh (nguyên thủy) cùng với khoảng trống được tạo bởi `\kern`:

```latex
\setlength{\tabskip}{5pt} % Đặt \tabskip ở bên ngoài bảng

\halign{
#&#&#&#&#\cr % Phần <preamble>
\noalign{\hrule\kern2pt} % Đường kẻ có khoảng cách trước hàng 1
1&2&3&4&5\cr % Hàng 1
\noalign{\kern2pt\hrule\kern2pt} % Đường kẻ có khoảng cách giữa các hàng 1/2
6&7&8&9&10\cr % Hàng 2
\noalign{\kern2pt\hrule\kern2pt} % Đường kẻ có khoảng cách giữa các hàng 2/3
11&12&13&14&15\cr % Hàng 3
16&17&18&19&20\cr % Hàng 4---không có đường kẻ giữa các hàng 3/4
\noalign{\kern2pt\hrule} % Đường kẻ có khoảng cách ở cuối bảng
}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D+%25+Set+%5Ctabskip+outside+of+the+table%0A%0A%5Chalign%7B%0A%23%26%23%26%23%26%23%26%23%5Ccr+%25+The+%3Cpreamble%3E%0A%5Cnoalign%7B%5Chrule%5Ckern2pt%7D+%25+Spaced+rule+before+row+1%0A1%262%263%264%265%5Ccr+%25+Row+1%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%5Ckern2pt%7D+%25+Spaced+rule+between+rows+1%2F2+%0A6%267%268%269%2610%5Ccr+%25+Row+2%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%5Ckern2pt%7D+%25+Spaced+rule+between+rows+2%2F3+%0A11%2612%2613%2614%2615%5Ccr+%25+Row+3%0A16%2617%2618%2619%2620%5Ccr+%25+Row+4---no+rules+between+rows+3%2F4%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%7D+%25+Space+rule+at+table+end%0A%7D%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra bảng hiển thị bên dưới, đã được chú thích thêm để tái hiện mã (La)TeX và các số (1) đến (4) để đánh số các `\noalign` lệnh, chứa các đường kẻ và kern, cùng với đầu ra dàn trang tương ứng của chúng:

![](/files/84d383e3274d8bf1e7890116444c7ab43c19b786)

Hình minh họa sau cho thấy phiên bản được tô màu của bảng, được gắn nhãn để hiển thị các khoảng cách/glue khác nhau trong bảng:

![](/files/46a527301f7bcb15724e19dc1e8489500c7d0103)

Lưu ý những điều sau:

* việc dùng `\noalign` để chèn các đường kẻ giữa một số hàng nhất định và việc dùng thủ công `\kern` các giá trị để thêm một ít khoảng trống trước/sau các đường kẻ. Các bộ máy TeX không chèn `\baselineskip` glue sau một đường kẻ đã dàn trang, vì vậy khoảng trống được chèn thủ công bằng `\kern` (có thể dùng các lệnh khoảng cách khác);
* `\baselineskip` glue đã được chèn tự động giữa các hàng 3 và 4.

#### Dùng một \valign

Ví dụ sau `\valign` ví dụ dùng cùng dữ liệu như ví dụ trước `\halign`:

```latex
\begingroup
\setlength{\parindent}{10pt}
\setlength{\hsize}{50pt}
\setlength{\tabskip}{5pt}
\valign{
#&#&#&#&#\cr
\noalign{\vrule\kern2pt}
1&2&3&4&5\cr
\noalign{\kern2pt\vrule\kern2pt}
6&7&8&9&10\cr
\noalign{\kern2pt\vrule\kern2pt}
11&12&13&14&15\cr
16&17&18&19&20\cr
\noalign{\kern2pt\vrule}
}
\endgroup
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Cbegingroup%0A%5Csetlength%7B%5Cparindent%7D%7B10pt%7D%0A%5Csetlength%7B%5Chsize%7D%7B50pt%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D%0A%5Cvalign%7B%0A%23%26%23%26%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Cvrule%5Ckern2pt%7D%0A1%262%263%264%265%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%5Ckern2pt%7D%0A6%267%268%269%2610%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%5Ckern2pt%7D%0A11%2612%2613%2614%2615%5Ccr%0A16%2617%2618%2619%2620%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%7D%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra bảng hiển thị bên dưới, đã được chú thích thêm để tái hiện mã (La)TeX và các số (1) đến (4) để đánh số các `\noalign` lệnh, chứa các đường kẻ và kern, cùng với đầu ra dàn trang tương ứng của chúng:

![](/files/cbfbe7e47df5010de233c57dada16bfc2ef20d3d)

![](/files/4ab4b3a26ba59de9ec00d512e7748ed9c535e133)

### Một bảng \valign với các dòng văn bản

Ví dụ tiếp theo

```latex
\setlength{\tabskip}{5pt}
\begingroup % Giữ các thay đổi đối với \parindent và \hsize ở phạm vi cục bộ
\setlength{\parindent}{10pt}
\setlength{\hsize}{75pt}
\valign{
#&#&#\cr
\noalign{\vrule\kern5pt}
\TeX{} có thể dàn trang rất phức tạp
bảng.&Đây là một chút
văn bản thêm.&Và, cuối cùng, một dòng bổ sung
trong cột này.\cr
\noalign{\kern5pt\vrule\kern5pt}
A&B&C\cr
\noalign{\kern5pt\vrule\kern5pt}
D&E&F\cr
G&H&I\cr
\noalign{\kern5pt\vrule}
}
\endgroup
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+valign+command\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D16cm%2Ctextwidth%3D12cm%5D%7Bgeometry%7D%0A%5Cbegin%7Bdocument%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D%0A%5Cbegingroup+%25+Keep+changes+to+%5Cparindent+and+%5Chsize+local%0A%5Csetlength%7B%5Cparindent%7D%7B10pt%7D%0A%5Csetlength%7B%5Chsize%7D%7B75pt%7D%0A%5Cvalign%7B%0A%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Cvrule%5Ckern5pt%7D%0A%5CTeX%7B%7D+can+typeset+very+complex%0Atables.%26Here%27s+a+bit+of+extra+%0Atext.%26And%2C+finally%2C+an+extra+line%0Ain+this+column.%5Ccr%0A%5Cnoalign%7B%5Ckern5pt%5Cvrule%5Ckern5pt%7D%0AA%26B%26C%5Ccr%0A%5Cnoalign%7B%5Ckern5pt%5Cvrule%5Ckern5pt%7D%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%5Cnoalign%7B%5Ckern5pt%5Cvrule%7D%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

Ví dụ này tạo ra kết quả sau:

## Thiết lập độ rộng hàng và chiều cao cột

## Thêm về bảng $$\langle$$⁠phần tiền đề⁠$$\rangle$$


---

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