> 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/23-how-does-latex-typeset-headers-and-footers.md).

# LaTeX dàn trang đầu trang và chân trang như thế nào?

## LaTeX dàn trang đầu trang và chân trang như thế nào?

### Giới thiệu

Nếu bạn đang tìm một hướng dẫn cách thay đổi đầu trang và chân trang, vui lòng [truy cập trang trợ giúp của chúng tôi](/latex/vi/dinh-dang/02-headers-and-footers.md) vì bài viết này tập trung giải thích các cơ chế cấp thấp được các bộ máy TeX và LaTeX sử dụng để tạo đầu trang và chân trang.

* **Lưu ý (cập nhật)**: Bài viết này khám phá cơ chế mark cốt lõi của LaTeX được dùng trước tháng 6 năm 2022, thời điểm một cách triển khai mới và linh hoạt hơn cho việc xử lý mark của LaTeX đã được giới thiệu. Xem [Tổng quan về cơ chế mark mới của LaTeX](https://www.latex-project.org/help/documentation/ltmarks-doc.pdf) để biết thêm chi tiết. Vì lý do tương thích ngược, LaTeX vẫn tiếp tục hỗ trợ cơ chế mark cũ của mình. Nội dung bài viết thảo luận về hành vi của các bộ máy TeX không bị ảnh hưởng bởi những thay đổi này của LaTeX.
* **Lưu ý**: các thuật ngữ “LaTeX”, “TeX” và “bộ máy TeX” được dùng xuyên suốt các thảo luận này nên sẽ hữu ích nếu hiểu ý nghĩa của chúng—xem bài viết Overleaf [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) để biết thêm thông tin.

Để cung cấp bối cảnh nền hữu ích, chúng ta bắt đầu với tổng quan về một số khía cạnh cấp thấp liên quan của dàn trang dựa trên TeX—bao gồm lưu trữ nội dung tạm thời (nội bộ), ngắt trang và dựng trang. Các thảo luận đã được tinh giản/đơn giản hóa bằng cách xem xét một trang đã dàn trang chứa “phần thân” văn bản cùng với một số đầu trang và chân trang. Các phần tử của trang như hình (float) và chú thích cuối trang không được đề cập vì chúng liên quan đến một cơ chế TeX phức tạp gọi là *chèn*, điều này nằm hoàn toàn ngoài phạm vi của bài viết này.

Chúng ta sẽ bắt đầu với khái niệm cơ bản về *nút*: các khối xây dựng cơ bản được các bộ máy TeX dùng để lưu trữ nội dung tạm thời (nội bộ).

### Một số lưu ý về việc lưu trữ nội dung: các node TeX

Khi bộ máy TeX nền tảng xử lý mã LaTeX của bạn để tạo ra nội dung đã dàn trang—như đoạn văn, bảng và công thức toán—nó cần tạm thời lưu trữ nội dung đó trong bộ nhớ của bộ máy TeX đang được dùng để xử lý mã LaTeX của bạn. Để lưu nội dung đã dàn trang, các bộ máy TeX sử dụng một chuỗi các *nút*mà bạn có thể xem như các “mảnh” bộ nhớ máy tính (thiết bị) có kích thước thay đổi, được liên kết với nhau để tạo thành một danh sách (xem [bài viết trên Wikipedia về cấu trúc dữ liệu liên kết](https://en.wikipedia.org/wiki/Linked_data_structure)).

![Biểu diễn sơ đồ cách các bộ máy TeX lưu trữ nội dung bằng các node liên kết](/files/f85adc02497af0e508cebc2593e81506632093e9)

Để biểu diễn các phần tử cơ bản của dàn trang dựa trên TeX—chẳng hạn như ký tự, glue, hộp, penalties, kerns và [*mark*](#why-were-here-understanding-mark-nodes) (chỉ kể vài thứ)—các bộ máy TeX sử dụng các *kiểu* loại node khác nhau. Một số node, như node cho hộp, cần lưu nhiều dữ liệu hơn so với các kiểu node đơn giản hơn như node ký tự; do đó, một số node lớn hơn những node khác—đòi hỏi nhiều byte hơn để lưu chúng trong bộ nhớ. Khi đọc về TeX, bạn có thể gặp các thuật ngữ như *node ký tự*, *node glue*, [*node mark*](#why-were-here-understanding-mark-nodes) và tương tự: giờ bạn biết rằng đó chỉ là những tên gọi được đặt cho các mảnh bộ nhớ được cấp phát để lưu dữ liệu đại diện cho một phần tử của quá trình dàn trang TeX.

#### Lý do chúng ta ở đây: hiểu node mark

Trong số nhiều kiểu node, kiểu chúng ta cần bàn đến được gọi là một *node mark* được tạo bởi `\mark` lệnh:

```latex
\mark{stuff to store}
```

Tính năng `\mark` lệnh này không trực tiếp tạo ra nội dung đã dàn trang nào: đối số của nó `*stuff to store*` được lưu vào bộ nhớ để dùng sau và một *node mark* được tạo ra để chứa vị trí bộ nhớ của *stuff to store*. Như chúng ta sẽ thấy, lệnh `\mark` đã được tạo ra *đặc biệt* để hỗ trợ tạo đầu trang và chân trang.

Các node mark được tạo bởi `\mark` các lệnh được “nhúng” vào nội dung trang, sẵn sàng để dùng trong các giai đoạn cuối của việc bố cục trang khi bộ máy TeX sẵn sàng thêm đầu trang và chân trang vào trang đã dàn trang (phần thân). Thông thường, `*stuff to store*` sẽ chứa nội dung như số trang và tiêu đề/số chương hoặc mục—những thành phần cơ bản của đầu trang và chân trang.

#### ε-TeX bổ sung lệnh \marks

[Phiên bản 2 của ε-TeX](https://texdoc.org/serve/e-TeX/0), một mở rộng của TeX gốc do Knuth tạo ra, đã được phát hành năm 1998 và cung cấp các khả năng mới cùng với cải tiến cho các tính năng hiện có. Ngày nay, phần lớn cải tiến của ε-TeX đã được tích hợp vào các bộ máy TeX phổ biến: pdfTeX, LuaTeX và XeTeX—xem tùy chọn dòng lệnh [**`-etex`** của các bộ máy TeX](/latex/vi/chu-de-khac/44-tex-engine-command-line-options-for-pdftex-xetex-and-luatex.md) cho phép sử dụng các phần mở rộng ε-TeX.

Phần mềm TeX gốc của Knuth cung cấp lệnh \mark, lệnh này chỉ tạo ra 1 “lớp” hoặc “kiểu” node mark. Tài liệu của bạn có thể chứa nhiều lệnh \mark nhưng tất cả chúng đều tạo ra các node mark cùng một “kiểu” hoặc “lớp”—không có cơ chế tích hợp sẵn để nhóm hay phân loại chúng. Hạn chế này đã được loại bỏ bởi một cải tiến của ε-TeX: lệnh \marks, được hỗ trợ bởi pdfTeX, LuaTeX và XeTeX:

```latex
\marks n {stuff to store}
```

trong đó `n` là một số nguyên (`0` <= `n` < `32768`) quyết định node mark *lớp*.

Lưu ý:

* viết `\marks 0` (tức là, `n`=`0`) đồng nghĩa với việc dùng lệnh gốc của TeX `\mark` lệnh
* ε-TeX cũng giới thiệu các biến mark ([xem bên dưới](#pre-output-checks-looking-for-mark-nodes)) cho mỗi lớp (`n`) của mark: `\firstmarks n`, `\topmarks n` và `\botmarks n`. Các lớp biến mark được chọn có thể được dùng để cung cấp dữ liệu mark cho các tác vụ dàn trang cụ thể.
* LuaTeX đã tăng giá trị tối đa của `n` sang `65535`, cho phép $$2^{16}$$ các lớp mark

### Lý do TeX sử dụng mark

Để hiểu *vì sao* (và cách) các bộ máy TeX sử dụng `\mark` (hoặc `\marks`) để tạo đầu trang và chân trang, chúng ta cần hiểu một vài “đặc điểm riêng” của các cơ chế dựng trang của bộ máy TeX—tìm điểm ngắt trang và xuất các trang đã hoàn thành sang một tệp PDF. Trên thực tế, các quá trình dựng trang đó rất phức tạp nhưng các nguyên lý/khái niệm cốt lõi có thể được đơn giản hóa để cung cấp đủ lời giải thích nền tảng giúp ta hiểu mark.

Khi một bộ máy TeX hoàn tất việc dàn trang từng mục nội dung như đoạn văn, bảng hoặc toán, nó gọi một thủ tục nội bộ (một hàm có tên là `build_page(...)`) nhằm cố gắng thêm các mục vừa được dàn trang đó vào trang hiện đang được dựng trong bộ nhớ. Khi nội dung mới đó được thêm vào trang đang xây dựng, TeX cũng kiểm tra xem nội dung vừa thêm có làm trang hiện tại trở nên “đủ đầy” hay chưa. Nếu trang đã đầy, TeX có thể tạo ra một *ngắt trang*—gửi lượng nội dung của trang đó để xử lý cuối cùng (“đóng gói”) rồi sau đó xuất ra tệp PDF.

Một đặc điểm then chốt của giai đoạn cuối cùng của việc đóng gói trang (dàn bố cục) là thứ được gọi là một *output routine* , về thực chất là một chuỗi lệnh do người dùng định nghĩa dùng để đóng gói trang nội dung cho sẵn sàng gửi tới tệp PDF. Một hoạt động ví dụ của việc “đóng gói” là thêm đầu trang và chân trang, nhưng có nhiều cách sử dụng output routine—for example, see [bài viết này trên TUGboat](https://tug.org/TUGboat/tb11-1/tb27salomon.pdf). Output routine là một lĩnh vực khá phức tạp của TeX nên chúng ta sẽ không đi sâu ở đây: trong phạm vi hiện tại chỉ cần nhớ rằng giai đoạn cuối của việc bố cục trang liên quan đến việc dùng một chuỗi lệnh do người dùng định nghĩa (gọi chung là một *output routine*).

Nhưng hãy xem điều gì có thể xảy ra khi TeX hoàn tất việc dàn trang một đoạn văn bản dài, tách nó thành một chuỗi các dòng đã dàn trang riêng lẻ. TeX sẽ muốn thêm đoạn văn vừa được dàn trang đó—từng dòng một—vào trang hiện đang được xây dựng nhưng, có lẽ, chỉ *một số* trong số các dòng đó có thể vừa trên trang hiện tại. Lưu ý, khi nói “trang” ở đây chúng ta đang đề cập đến vùng văn bản chính (phần thân trang) mà *không* bao gồm các thành phần trang khác như đầu trang và chân trang sẽ được thêm sau (bởi output routine).

Sau khi vài dòng của đoạn văn đã được thêm vào trang hiện tại, nó có thể trở nên “đủ đầy” và đến lúc TeX tạo ngắt trang. Tuy nhiên, chúng ta vẫn còn một số nội dung “dư” vì chỉ *part* của đoạn văn đã được đưa vào trang hiện tại: “nội dung đoạn văn dư” được lưu lại để dùng sau, sẵn sàng cho việc tạo ra *trang* tiếp theo. Hình minh họa sau đây cho thấy ý này: một phần của đoạn văn nằm trên *hiện tại* trang và một phần được giữ lại cho *trang* trang

![Biểu diễn sơ đồ một đoạn văn trải qua một ngắt trang](/files/c88f543b2625a3ba1b8d0a4857676cdf0b9155cc)

Ví dụ đoạn văn này cho thấy rằng một bộ máy TeX thường sẽ xử lý (dàn trang) những mẩu nội dung mà không thể, *toàn bộ*, vừa khít trên trang hiện tại—vì nội dung đó vượt quá điểm tại đó việc ngắt trang trở nên cần thiết. Hãy nhớ rằng các bộ máy TeX tìm điểm ngắt dòng bằng cách nhập vào rồi dàn trang *toàn bộ các đoạn văn* và, không như một số ứng dụng, không áp dụng cách tiếp cận từng dòng một để dàn trang các đoạn văn. Nói cách khác, TeX dàn trang *toàn bộ* đoạn văn cho dù nó có vừa trang hiện tại hay không (điều đó sẽ được xác định sau). Nhân tiện, nguyên tắc “dàn trang đầy đủ rồi mới thêm vào trang hiện tại” cũng đúng với các loại nội dung TeX khác, bao gồm cả bảng, vốn được đọc đầy đủ từ tệp .tex và được dàn trang toàn bộ trước khi thử thêm chúng vào trang hiện tại.

Với ví dụ đoạn văn của chúng ta, toàn bộ văn bản của đoạn văn đó, *bao gồm mọi lệnh bên trong văn bản đó*, đã được xử lý đầy đủ—nghĩa là việc dàn trang của TeX đã đi đến một vị trí nhất định trong tệp `.tex` tệp của bạn. “Trạng thái nội bộ hiện tại” của bộ máy TeX, như giá trị của các biến hoặc các thiết lập tham số đã lưu, sẽ phản ánh nội dung, bao gồm mọi lệnh, đã được xử lý đến vị trí hiện tại—cuối đoạn văn.

Mặc dù toàn bộ đoạn văn đã được dàn trang, một phần của nó không thể được chứa trên trang hiện tại, dẫn đến việc “nội dung đoạn văn dư” được lưu cho *trang* trang. Trong mã LaTeX (văn bản cộng lệnh) đã tạo ra “nội dung đoạn văn dư”, bộ máy TeX *có thể* đã gọi bất kỳ số lượng lệnh và macro nào làm thay đổi giá trị và các biến được lưu bên trong bộ máy TeX—tức là thay đổi “trạng thái hiện tại” của TeX.

Sơ đồ sau đây minh họa một “đặc điểm riêng” cực kỳ quan trọng của TeX, một điều ảnh hưởng đến nhiều khía cạnh của dàn trang dựa trên TeX. Nhìn vào phía bên phải của sơ đồ, bạn sẽ thấy một biểu diễn các node cấu thành toàn bộ nội dung hiện đang được lưu trong bộ nhớ: vùng xám nhạt chứa các node tạo thành *hiện tại* trang và vùng xám đậm là nội dung đã dàn trang dành cho *trang* trang. Tình huống này phản ánh ví dụ đoạn văn của chúng ta: vùng xám đậm đại diện cho “nội dung đoạn văn dư”: các dòng văn bản được giữ lại vì chúng không vừa trên trang hiện tại.

![Biểu diễn sơ đồ vị trí node nơi TeX tìm thấy một ngắt trang, đồng thời cho thấy nội dung được giữ lại cho trang tiếp theo](/files/a894bef52754bb593860e9c0d2af68687d96af86)

Hãy nhớ rằng khi TeX có một trang (phần thân) “đủ đầy”, nó chuyển nội dung đó cho thứ gọi là một *output routine* , là một chuỗi lệnh do người dùng định nghĩa. Trong số các việc khác, output routine thêm đầu trang và chân trang vào phần thân trang, hoàn thiện trang để sẵn sàng xuất nó ra tệp PDF.

Hình minh họa của chúng ta (ở trên) biểu diễn trường hợp TeX đã chọn ngắt trang tại một node cụ thể nào đó, chẳng hạn như `\baselineskip` glue giữa các dòng đã dàn trang, và sẵn sàng bắt đầu đóng gói trang hiện tại bằng output routine—một chuỗi gồm các lệnh tích hợp sẵn và các macro do người dùng định nghĩa. *Tuy nhiên*, ngoài nội dung cấu thành trang hiện tại (được lưu trong bộ nhớ), TeX còn đã xử lý và lưu (trong bộ nhớ) *thêm nội dung*, từ `.tex` tệp của bạn. Nội dung bổ sung đó kéo dài *vượt quá điểm ngắt trang* và *có thể* có thể đã bao gồm các lệnh đã thay đổi những giá trị hoặc biến quan trọng liên quan đến trang, ảnh hưởng đến “trạng thái nội bộ hiện tại” của TeX—bao gồm các giá trị của tham số nội bộ hoặc dữ liệu được lưu bởi các macro.

Khi TeX bắt đầu đóng gói trang hiện tại, “trạng thái nội bộ hiện tại” của nó là *không* được xác định bởi mọi thứ đã được dàn trang đến vị trí ngắt trang vì TeX đã *đi qua điểm đó* trong tệp của bạn và đã xử lý thêm nội dung bổ sung. Nếu bạn xét vị trí trong tệp của bạn tương ứng với nơi ngắt trang xảy ra, và vị trí mà TeX thực sự đã đạt tới trong `.tex` tệp, thì hai trạng thái nội bộ tương ứng của TeX, bao gồm dữ liệu đã lưu và giá trị của các biến, có thể rất khác nhau. Trạng thái hiện tại của việc dàn trang TeX thường đi trước vị trí xảy ra ngắt trang; tức là, các hoạt động dàn trang của TeX *không được đồng bộ* với quá trình xuất các trang đã dàn trang thông qua output routine.

#### Ví dụ giả định: cách tạo ra đầu trang sai

Sơ đồ sau đây minh họa các lệnh giả định `\myheader` và `\myfooter` được dùng để lưu văn bản mong muốn của đầu trang và chân trang; chẳng hạn, dùng

```latex
\newtoks\headertoks% một biến danh sách token mới cho văn bản đầu trang
\newtoks\footertoks% một biến danh sách token mới cho văn bản chân trang
% Dùng \global để bảo đảm dữ liệu đầu trang hoặc chân trang đã lưu được
% truy cập được ở mọi nơi, kể cả các lệnh trong
% output routine
\newcommand{\myheader}[1]{\global\headertoks={#1}}
\newcommand{\myfooter}[1]{\global\footertoks={#1}}
```

trong đó `\headertoks` và `\footertoks` là các danh sách token dùng để lưu văn bản của đầu trang và chân trang.

Ngoài ra, ví dụ giả định của chúng ta còn có một output routine lấy văn bản đầu trang và chân trang từ các giá trị hiện tại của `\myheader` và `\myfooter`. Như minh họa trong sơ đồ, trong nội dung dành cho trang hiện tại, `\myheader` và `\myfooter` đặt các giá trị thích hợp (đúng). Tuy nhiên, có thể `\myheader` và/hoặc `\myfooter` được gọi trong một đoạn văn trải qua ngắt trang. Vì TeX phải xử lý toàn bộ đoạn văn, `\myheader` và `\myfooter` sẽ được gọi lại để đặt lại văn bản đầu trang/chân trang đã lưu trong “trạng thái nội bộ của TeX”, tạo ra các giá trị không đúng cho trang hiện tại. Khi output routine tạo đầu trang và chân trang, chúng sẽ chứa văn bản dành cho trang tiếp theo.

![Hình minh họa cho thấy đầu trang và chân trang sai được tạo ra nếu output routine chỉ dùng macro TeX để truy xuất văn bản đầu trang và chân trang](/files/243880cde9fa4f4f69b7bb00c5ab5f11854d017f)

#### Hành vi không đồng bộ của TeX: lệnh \mark cứu nguy

Các hoạt động dàn trang (xây dựng nội dung) của TeX là *không đồng bộ* với quá trình cuối cùng là xuất một trang đã dàn trang thông qua các lệnh nằm trong output routine. Khi đến lúc xuất một trang, trạng thái nội bộ thực sự của TeX đi trước bất kỳ trạng thái nào mà nó có thể đã có tại vị trí ngắt trang—nơi nó đã dàn trang phần nội dung cuối cùng trên trang hiện đang được xuất.

Trong [The TeXbook](https://www.amazon.co.uk/TeXbook-Donald-Knuth/dp/0201134489), Donald Knuth, người tạo ra TeX, mô tả tình huống này là

> ... output routine của TeX bị tụt lại so với các hoạt động dựng trang của nó

Vì mối quan hệ không đồng bộ này, các “cơ chế đặc biệt” dưới dạng *cơ chế marks*, được áp dụng thông qua `\mark` (hoặc `\marks n`) là cần thiết để bảo đảm đầu trang và chân trang chứa nội dung liên quan đến trang thực sự đang được xuất. Lệnh `\mark` nhúng các node mark vào nội dung trang, lưu vị trí bộ nhớ của nội dung có thể dùng cho đầu trang và chân trang của trang chứa nó.

Tác giả của cuốn sách nổi tiếng và được kính trọng [TeX by Topic](https://www.eijkhout.net/tex/tex-by-topic.html) mô tả `\mark` cơ chế này là

> ... cơ chế chính mà qua đó output routine có thể lấy thông tin về nội dung của trang vừa bị ngắt, đặc biệt là phần đầu và phần cuối của nó.

Tính năng `\mark` lệnh là một cơ chế được thiết kế để vượt qua tính không đồng bộ của thuật toán ngắt trang và output routine của TeX.

![Biểu diễn sơ đồ dữ liệu mark (các node) được nhúng trong nội dung phần thân trang](/files/9267550cdefdf914a3061762e7a923a42e2610ef)

### Kiểm tra trước khi xuất: tìm các node mark

Sau khi bộ máy TeX xác định vị trí ngắt trang, nó gọi một thủ tục nội bộ (gọi là `fire_up()`) thực hiện nhiều bước tiền xử lý trước khi output routine hoàn tất việc bố cục trang và ghi trang hoàn chỉnh vào tệp PDF. Một phần quan trọng của các bước tiền xử lý đó là đặt giá trị cho ba *biến mark toàn cục*: `\botmark`, `\topmark` và `\firstmark` được dùng để cung cấp dữ liệu cho việc dựng đầu trang và chân trang. Tất nhiên, một trang có thể chứa nhiều node mark nhưng chúng được lọc để tạo ra ba biến mark hoạt động như sau:

* **`\botmark`** là mark có hiệu lực tại ngắt trang hiện tại; tức là mark cuối cùng được thấy trên *hiện tại* page
* **`\topmark`** là giá trị của `\botmark` từ gói *trước đó* page
* **`\firstmark`** là mark đầu tiên trên *hiện tại* trang—mark đầu tiên giữa `\topmark` và `\botmark`

Sơ đồ sau đây cho thấy các nguyên tắc cơ bản của việc tiền xử lý nội dung trang đã dàn trang để xác định giá trị cho ba biến mark toàn cục `\botmark`, `\topmark` và `\firstmark`:

![Biểu diễn sơ đồ các nguyên tắc cơ bản được dùng để xác định giá trị cho ba biến mark toàn cục \botmark, \topmark và \firstmark](/files/8d018d493564a86d22b35b2a566284439cca611c)

Phần tiếp theo sử dụng một số giải thích đã nêu ở trên để phác thảo cách LaTeX dàn trang đầu trang và chân trang.

### Các lớp của LaTeX: kiểu trang và đầu/chân trang

Khi bạn viết `\documentclass{*class*}` trong đó `*class*` có thể là `article`, `book`, `báo cáo` hoặc `letter`, LaTeX tải một tệp có tên `*class*.cls`; ví dụ, `book.cls`, `article.cls` và tương tự. Những `.cls` các tệp chứa mã LaTeX để triển khai các biến thể dành riêng cho lớp của nhiều lệnh và tính năng được mong đợi có mặt trong, và được cung cấp bởi, mọi lớp tài liệu—những hành vi được chia sẻ bởi tất cả các lớp tài liệu. Ví dụ có thể bao gồm lề bố cục trang riêng cho lớp cùng với các phiên bản dành riêng cho lớp của các lệnh, như `\section`, `\subsection` và tương tự.

Một thành phần quan trọng khác của `.cls` các tệp là cách triển khai dành riêng cho lớp của các kiểu trang tiêu chuẩn, những kiểu này định nghĩa đầu trang và chân trang của các tài liệu được tạo bằng một lớp và kiểu trang cụ thể. Ví dụ:

* **`book.cls`** và **`article.cls`** mỗi tệp đều chứa các triển khai của các kiểu trang `headings` và `myheadings`
* **`letter.cls`** chứa định nghĩa cho các kiểu trang `headings`, `empty`, `plain` và một kiểu có tên là `firstpage`
* **`report.cls`** chứa định nghĩa cho các kiểu trang `headings` và `myheadings`

Việc triển khai các kiểu trang thường phụ thuộc vào `twoside` tùy chọn `\documentclass`—liệu tài liệu là một mặt hay hai mặt—để đầu trang và chân trang được định nghĩa phù hợp cho các trang bên trái (chẵn) và bên phải (lẻ).

Các lớp tài liệu có thể dựa vào các định nghĩa mặc định của `plain` hoặc `empty` các kiểu trang được cung cấp ở nơi khác trong LaTeX—bên ngoài `.cls` tệp đang được dùng.

#### Thêm về các kiểu trang

Khi bạn thay đổi kiểu của một trang bằng `\pagestyle{*somestyle*}` hoặc `\thispagestyle{*somestyle*}` LaTeX mong đợi tìm thấy một lệnh nội bộ có tên `ps@*somestyle*`—thường được cung cấp bởi lớp tài liệu `.cls` tệp hoặc có lẽ bởi một gói như `fancyhdr`. Nhân tiện, “lệnh nội bộ” ở đây nghĩa là một lệnh là một phần của mã nguồn LaTeX và có tên chứa một `@` ký hiệu, vốn thông thường ngăn việc sử dụng trực tiếp (do [mã loại](/latex/vi/chu-de-khac/43-table-of-tex-category-codes.md)).

Định nghĩa của `\ps@*somestyle*` chịu trách nhiệm triển khai các tính năng/hành vi của kiểu trang đó, bao gồm cung cấp định nghĩa cho:

* các lệnh được dùng trong các giai đoạn cuối của việc bố cục trang (để thêm đầu trang và chân trang, xem [sau này trong bài viết](#commands-for-the-output-routine)):
  * `\@oddhead`
  * `\@oddfoot`
  * `\@evenhead`
  * `\@evenfoot`
* các lệnh chèn dữ liệu mark liên quan đến mục để dùng trong việc tạo đầu trang và chân trang của tài liệu có chứa tiêu đề mục, số mục và những thứ tương tự. Ví dụ, `headings` kiểu trang (trong `book.cls`) định nghĩa các lệnh tạo mark sau:
  * `\chaptermark`
  * `\sectionmark`

Chúng ta sẽ [tiếp tục tìm hiểu các lệnh tạo mark](#mark-commands-and-mark-data), chẳng hạn như `\chaptermark`, nhưng chỉ để làm ví dụ: khi bạn viết `\chapter{chapter title}` trang `\chaptermark` lệnh cũng được thực thi để chèn dữ liệu mark liên quan đến chương cho việc tạo đầu trang sau đó.

#### Cấu trúc giải phẫu của các lệnh đầu trang và chân trang dựa trên kiểu trang

Phần này khám phá một số lệnh/quy trình cốt lõi của LaTeX được dùng để tạo đầu trang và chân trang—dựa trên các giải thích hoặc khái niệm đã trình bày trước đó trong bài viết này.

**“Mô hình” đầu trang và chân trang của LaTeX**

Nội dung của đầu trang và chân trang (mặc định) của LaTeX dựa trên một hệ phân cấp hai tầng của các phần trong tài liệu: một phần “cấp cao hơn” chứa nhiều phần “cấp thấp hơn”. Với các lớp book và article, điều này tương ứng như sau:

* `**book**` **lớp**: các phần “cấp cao hơn” được tạo bởi `\chapter` các lệnh và các phần “cấp thấp hơn” thông qua `\section`, phản ánh các chương chứa nhiều mục.
* `**article**` **lớp** (giả sử tài liệu hai mặt): các phần “cấp cao hơn” được tạo bằng `\section` các lệnh và các phần “cấp thấp hơn” thông qua `\subsection`, phản ánh nhiều tiểu mục xuất hiện trong cùng một mục.

LaTeX áp dụng “mô hình” đầu trang và chân trang của mình thông qua các lệnh chia mục, những lệnh này “chèn” các node mark (qua `\mark` lệnh) để lưu dữ liệu liên quan đến phần tài liệu đang được tạo. Ví dụ, mỗi khi bạn viết `\section{*some section title*}` một node mark sẽ được tạo, chứa dữ liệu phản ánh `*some section title*` và số mục.

LaTeX sử dụng một hệ thống mark chứa dữ liệu có dạng `{left}{right}`, cuối cùng được tạo ra thông qua `\mark` lệnh

```latex
\mark{{left}{right}}
```

được bao bọc trong nhiều lớp macro được thiết kế để che giấu người dùng khỏi các chi tiết cấp thấp—những chi tiết này sẽ được khám phá trong các phần tiếp theo của bài viết này.

#### Khám phá lớp book

Khi `book.cls` tệp được nạp, một trong những thao tác cuối cùng của nó là thực thi `\pagestyle{headings}` lệnh này đặt kiểu trang mặc định thành `headings`, nên chúng ta sẽ xem kiểu trang đó chi tiết hơn.

Như [đã lưu ý ở trên](#more-on-page-styles), các tính năng/thuộc tính của `headings` kiểu trang, như được triển khai bởi lớp `book` , sẽ được định nghĩa bởi lệnh (nội bộ) `\ps@headings` có trong tệp `book.cls`. Định nghĩa chính xác của `\ps@headings` phụ thuộc vào việc tài liệu là một mặt hay hai mặt (mặc định của lớp `book` ).

**“Lệnh mark” và “dữ liệu mark”**

Đối với các tài liệu hai mặt do lớp `book` tạo ra, định nghĩa của `\ps@headings` tạo (định nghĩa) hai “lệnh mark”: `\chaptermark` và `\sectionmark` những lệnh tạo ra “dữ liệu mark”, có dạng `{left}{right}`, để dùng trong đầu trang và chân trang. Những lệnh mark đó phản ánh mô hình đầu trang và chân trang của LaTeX—dựa trên hệ phân cấp các phần của tài liệu:

* lệnh phần “cấp cao hơn” (ở đây, `\chapter`) được dùng để cung cấp “dữ liệu mark” cho đầu trang của các trang bên trái (số chẵn). Khi bạn bắt đầu một chương mới, bằng cách viết `\chapter{*chapter title*}`, `\chaptermark` lệnh được gọi để tạo “dữ liệu mark” phản ánh chương mới đó—chứa `*chapter title*` và số của nó.
* lệnh phần “cấp thấp hơn” (ở đây, `\section`) được dùng để cung cấp “dữ liệu đánh dấu” cho các trang lẻ (đánh số lẻ) quay phải. Khi bạn viết `\section{*section title*}` trang `\sectionmark` lệnh sẽ được gọi để tạo “dữ liệu đánh dấu” phản ánh phần mới—chứa `*section title*` tiêu đề và số của nó. Mọi dữ liệu đánh dấu do lệnh trước đó cung cấp `\chapter` không bị ảnh hưởng bởi bất kỳ lệnh \section nào sau đó.

**\markboth và \markright**

Các lệnh đánh dấu theo từng phần của LaTeX, chẳng hạn như `\chaptermark` và `\sectionmark`, sử dụng thêm hai lệnh gọi là `\markboth` và `\markright` cung cấp dữ liệu đánh dấu thực tế cho đầu trang và chân trang. `\markboth` và/hoặc `\markright` có thể bao gồm các lệnh định dạng văn bản đầu trang hoặc chân trang, chẳng hạn như viết hoa.

Đối với các tài liệu được tạo bằng `book` mặc định của lớp (hai mặt, `headings` kiểu trang), các lệnh tạo dấu hoạt động như sau:

* `\chaptermark` tạo dữ liệu đánh dấu bằng `\markboth`
* `\sectionmark` tạo dữ liệu đánh dấu `\markright`

`\markboth` và `\markright` là các macro mà, xét cho cùng, sử dụng lệnh nguyên thủy (tích hợp sẵn, mức thấp) `\mark` để thực sự chèn các dấu được tạo ra từ bên trong các lệnh phân đoạn.

`\markboth` có dạng

* **`\markboth{left}{right}`**: chèn một dấu (nút) bằng `\mark{{left}{right}}` kết quả là một nút dấu chứa một cặp giá trị trong ngoặc nhọn `{left}{right}`.

`\markright` có dạng

* **`\markright{newright}`**: chèn một dấu (nút) bằng `\mark{{currentleft}{newright}}`; tức là, nó thay đổi giá trị hiện tại của `phải` sang `newright` nhưng giá trị hiện tại của `trái` (tức là, `currentleft`) không thay đổi, kết quả là một nút dấu chứa một cặp giá trị trong ngoặc nhọn `{currentleft}{newright}`.

Cách hoạt động của `\markboth` và `\markright` hỗ trợ cấu trúc phân cấp hai tầng của các phần, chẳng hạn như một tài liệu chứa nhiều mục trong mỗi chương.

Ví dụ đối với `book` lớp tài liệu (sử dụng kiểu trang headings):

* `\chaptermark` sử dụng `\markboth` để đặt:
  * a `{left}` trường sẽ dàn CHAPTER . thành chữ hoa.
  * một trường {right} để trống (`{}`)
* `\sectionmark` sử dụng `\markright` để đặt `{right}` trường đánh dấu để dàn chữ., cũng bằng chữ hoa.

Để hiểu tại sao `\sectionmark` sử dụng `\markright` ta có thể thấy rằng mỗi `\section` lệnh mới nên:

* chèn một dấu mới chứa dữ liệu cho `\section` (chẳng hạn như tiêu đề và số của nó).
* nhưng *không* ảnh hưởng đến các giá trị dữ liệu đánh dấu của `\chapter` trong đó lệnh cụ thể đó `\section` xuất hiện

Vì những lý do này, lệnh `\section` gọi `\sectionmark` lệnh này sử dụng `\markright` để tạo một `\section`-liên quan: nó cập nhật `{right}` trường dữ liệu đánh dấu nhưng không ảnh hưởng đến `{left}` giá trị của trường dữ liệu đánh dấu đã được đặt bởi `\chapter`.

Lưu ý: mã nguồn LaTeX có chứa lời khuyên sau:

> Các lệnh đánh dấu hoạt động khá tốt đối với các dấu bên phải ‘đánh số bên trong’ các dấu bên trái—ví dụ, dấu bên trái được thay đổi bởi lệnh \chapter và dấu bên phải được thay đổi bởi lệnh \section. Tuy nhiên, nó cho ra kết quả hơi bất thường nếu có 2 lệnh \markboth trên cùng một trang.

**Các lệnh cho quy trình xuất**

Tính năng `\ps@headings` lệnh triển khai các định nghĩa của các lệnh sau

* `\@oddhead`
* `\@oddfoot`
* `\@evenhead`
* `\@evenfoot`

được quy trình xuất dùng để thêm đầu trang và chân trang trong giai đoạn cuối của việc dàn trang. Ví dụ, `book.cls` đặt `\@oddfoot` và `\@evenfoot` thành giá trị `\@empty`, vốn được định nghĩa là `\def\@empty{}`, do đó `\ps@headings` tạo ra chân trang trống trên các trang trái và phải:

```latex
\let\@oddfoot\@empty
\let\@evenfoot\@empty
```

Đầu trang được định nghĩa như sau:

```latex
\def\@evenhead{\thepage\hfil\slshape\leftmark}%
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
```

trong đó

* `\leftmark` trích xuất `{left}` giá trị từ một `{left}{right}` cặp dấu
* `\rightmark` trích xuất `{right}` giá trị từ một `{left}{right}` cặp dấu
* \thepage xuất ra số trang hiện tại

Về cơ bản, các cách triển khai này của `\@evenhead` và `\@oddhead` cho ra các kết quả sau:

* `\@evenhead`: số trang xuất hiện ở bên trái đầu trang và nội dung của `\leftmark`, được định kiểu bằng lệnh phông chữ `\slshape`, được xuất ở bên phải đầu trang—khoảng trắng xen giữa được tạo bởi lệnh rất linh hoạt `\hfil` glue.
* `\@oddhead`: nội dung của `\rightmark`, được định kiểu bằng lệnh phông chữ `\slshape`, xuất hiện ở bên trái đầu trang và số trang hiện tại được xuất ở bên phải đầu trang—một lần nữa, khoảng trắng xen giữa được tạo bởi `\hfil` glue.

Tuy nhiên, vẫn còn một câu hỏi then chốt: *nào* `{left}{right}` cặp dấu nào được dùng bởi `\leftmark` và `\rightmark`: nói cách khác, họ lấy các giá trị dữ liệu đánh dấu của mình từ đâu?

Như [đã lưu ý ở trên](#filtering) nhưng [được giải thích bên dưới](#explainfiltering), trong giai đoạn cuối của việc dàn trang, mọi dấu có trong các trang tài liệu đều được “lọc” và dùng để đặt giá trị của ba biến dấu toàn cục: `\botmark`, `\topmark` và `\firstmark`. Do [cấu trúc của các dấu trong LaTeX](#latexs-model-of-headers-and-footers), mỗi biến trong 3 biến dấu đó cuối cùng sẽ chứa một giá trị của `{left}{right}` cho một cặp giá trị nào đó `{left}` và `{right}` và chính những giá trị này cung cấp `{left}{right}` cặp dấu (trường) thực tế cho `\leftmark` và `\rightmark`:

* `\leftmark` trích xuất `trái` giá trị từ `{left}{right}` cặp dấu (trường) do `\botmark`
* `\rightmark` trích xuất `phải` giá trị từ `{left}{right}` cặp dấu do cung cấp `\firstmark`

Lưu ý `\markboth` và `\markright` có thể chứa các lệnh định kiểu văn bản đầu trang và chân trang—chẳng hạn như chuyển thành chữ hoa.

### Ví dụ sử dụng các lệnh LaTeX mức thấp hơn

Các ví dụ sau minh họa việc thay đổi kiểu trang hoặc đầu trang và chân trang bằng cách định nghĩa lại một số lệnh LaTeX mức thấp (nội bộ) được thảo luận trong bài viết này (những lệnh có chứa ký hiệu @). Chúng tôi không khuyến khích phương pháp này để thay đổi đầu trang và chân trang, nhưng nó có sẵn cho những ai cần nó (ví dụ, tác giả gói). Giải pháp được ưu tiên để thay đổi đầu trang và chân trang là dùng [`fancyhdr` gói](https://ctan.org/pkg/fancyhdr?lang=en), được thảo luận trong một [bài trợ giúp Overleaf này](/latex/vi/dinh-dang/02-headers-and-footers.md).

#### Định nghĩa một kiểu trang tối thiểu

Ví dụ sau định nghĩa một kiểu trang mới, cực kỳ tối thiểu, có tên là `demostyle` kiểu này dùng văn bản tĩnh để định nghĩa đầu trang và chân trang và không dựa vào các lệnh chia mục (`\chapter`, `\section` v.v.) để đặt nội dung đầu trang và chân trang.

Ví dụ bắt đầu bằng cách thay đổi mã loại của `@` ký tự thành 11 để nó có thể được dùng trong tên macro. The `\ps@demostyle` lệnh triển khai kiểu trang tối thiểu của chúng ta bằng cách định nghĩa lại các lệnh được dùng (trong quy trình xuất) để tạo đầu trang và chân trang: `\@oddhead`, `\@oddfoot`, `\@evenhead` và `\@evenfoot`. Lưu ý `twoside` tùy chọn trong `\documentclass` khai báo của chúng ta—khai báo này dùng lớp `article` .

```latex
\documentclass[twoside]{article}
\catcode`@=11
\newcommand{\ps@demostyle}{%
\renewcommand\@oddfoot{\hfil Chân trang của trang lẻ\hfil}%
\renewcommand\@evenfoot{\hfil Chân trang của trang chẵn\hfil}%
\renewcommand\@evenhead{\thepage\hfil Đầu trang của trang chẵn}%
\renewcommand\@oddhead{Đầu trang của trang lẻ\hfil\thepage}}
\catcode`@=12
\title{Minh họa một kiểu trang}
\author{Overleaf}
\date{Tháng 8 năm 2022}
\begin{document}
\pagestyle{demostyle}
\maketitle
\newpage
\section{Giới thiệu}
\newpage
\section{Thêm nội dung}
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Creating+a+new+page+style\&snip=%5Cdocumentclass%5Btwoside%5D%7Barticle%7D%0A%5Ccatcode%60%40%3D11%0A%5Cnewcommand%7B%5Cps%40demostyle%7D%7B%25%0A%5Crenewcommand%5C%40oddfoot%7B%5Chfil+The+odd-page+footer%5Chfil%7D%25%0A%5Crenewcommand%5C%40evenfoot%7B%5Chfil+The+even-page+footer%5Chfil%7D%25%0A%5Crenewcommand%5C%40evenhead%7B%5Cthepage%5Chfil+The+even-page+header%7D%25%0A%5Crenewcommand%5C%40oddhead%7BThe+odd-page+header%5Chfil%5Cthepage%7D%7D%0A%5Ccatcode%60%40%3D12%0A%5Ctitle%7BDemonstrating+a+page+style%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cdate%7BAugust+2022%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bdemostyle%7D%0A%5Cmaketitle%0A%5Cnewpage%0A%5Csection%7BIntroduction%7D%0A%5Cnewpage%0A%5Csection%7BMore+material%7D%0A%5Cend%7Bdocument%7D)

#### Thay đổi đầu trang cho lớp book

Ví dụ sau thay đổi đầu trang cho lớp book bằng cách định nghĩa lại `\@oddhead` và `\@evenhead` để đầu trang của các trang trái và phải chứa số trang hiện tại và tiêu đề chương. Lưu ý cách lệnh thứ hai `\chapter` sử dụng tiêu đề chương dạng ngắn tùy chọn `[Tiêu đề ngắn]` giờ cung cấp văn bản đầu trang, thay vì tiêu đề dài.

`\section` các lệnh không ảnh hưởng đến nội dung đầu trang vì các định nghĩa lại đầu trang của chúng ta chỉ dùng `\leftmark` lệnh này lấy thông tin của chương hiện tại. Để truy cập thông tin của mục hiện tại, ta cần dùng `\rightmark` trong định nghĩa của `\@oddhead` và/hoặc `\evenhead`.

```latex
\documentclass{book}
% Lưu ý: mã loại của '@' tạm thời được đổi thành 11
% để cho phép dùng nó trong tên lệnh
\catcode `@=11
% Đặt \@oddfoot và \evenfoot tương đương với \@empty
% để làm chúng trống (rỗng)
\let\@oddfoot\empty\let\evenfoot\empty
% Định nghĩa lại \@oddhead và \@evenhead
\renewcommand{\@oddhead}{\leftmark\hfil\thepage}
\renewcommand{\@evenhead}{\thepage\hfil\leftmark}
\catcode `@=12
% Dùng kích thước trang nhỏ tiện lợi
\usepackage[paperheight=16cm,paperwidth=12cm,textwidth=10cm]{geometry}
\title{Hồi ký của một người dùng \TeX{}}
\author{Overleaf}
\begin{document}
\frontmatter
\maketitle
Đây là phần đầu sách sử dụng chữ số La Mã.
\mainmatter
\chapter{Tôi bắt đầu từ đâu?}
Chương 1: Một chương ngắn.
\newpage
\section{Lúc bắt đầu...}
Một mục.
\chapter[Tiêu đề ngắn]{Một chương có tiêu đề rất dài, khiến nó không phù hợp cho đầu trang}
\newpage
\section{Một mục khác}
Với rất ít nội dung.
\newpage
\section{Gì cơ, lại một mục nữa?}
Cũng có rất ít nội dung.
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Changing+headers+for+the+book+class\&snip=%5Cdocumentclass%7Bbook%7D%0A%25+NB%3A+category+code+of+%27%40%27+temporarily+changed+to+11%0A%25+to+enable+its+use+in+command+names%0A%5Ccatcode+%60%40%3D11%0A%25+Let+%5C%40oddfoot+and+%5Cevenfoot+be+equivalent+to+%5C%40empty%0A%25+to+make+them+blank+%28empty%29%0A%5Clet%5C%40oddfoot%5Cempty%5Clet%5Cevenfoot%5Cempty%0A%25+Redefine+%5C%40oddhead+and+%5C%40evenhead%0A%5Crenewcommand%7B%5C%40oddhead%7D%7B%5Cleftmark%5Chfil%5Cthepage%7D%0A%5Crenewcommand%7B%5C%40evenhead%7D%7B%5Cthepage%5Chfil%5Cleftmark%7D%0A%5Ccatcode+%60%40%3D12%0A%25+Use+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Ctitle%7BMemoirs+of+a+%5CTeX%7B%7D+user%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cfrontmatter%0A%5Cmaketitle%0AThis+is+frontmatter+which+uses+Roman+numerals.%0A%5Cmainmatter%0A%5Cchapter%7BWhere+do+I+start%3F%7D%0AChapter+1%3A+A+short+chapter.%0A%5Cnewpage%0A%5Csection%7BIn+the+beginning...%7D%0AA+section.%0A%5Cchapter%5BThe+short+title%5D%7BA+chapter+with+a+very+long+title%2C+making+it+unsuitable+for+headers%7D%0A%5Cnewpage%0A%5Csection%7BAnother+section%7D%0AWith+little+content.%0A%5Cnewpage%0A%5Csection%7BWhat%2C+another+section%3F%7D%0AAlso+with+little+content.%0A%5Cend%7Bdocument%7D)

#### Sử dụng các lệnh dấu mở rộng của ε-TeX

Tính năng `book` lớp dùng các định nghĩa sau của `\@evenhead` và `\@oddhead` để tạo đầu trang:

```latex
\def\@evenhead{\thepage\hfil\slshape\leftmark}
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}
```

trong đó các lệnh `\leftmark` và `\rightmark` được định nghĩa là

```latex
\def\leftmark{\expandafter\@leftmark\botmark\@empty\@empty}
\def\rightmark{\expandafter\@rightmark\firstmark\@empty\@empty}
```

Sử dụng các lệnh mở rộng của ε-TeX, và sự tương đương giữa lớp dấu 0 của ε-TeX và các lệnh gốc của TeX, ta có thể:

* viết lại `\leftmark` để thay thế `\botmark` với `\botmarks0` tương đương, và
* viết lại `\rightmark` để thay thế `\firstmark` với `\firstmarks0` tương đương

Những định nghĩa lại này tạo ra

```latex
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks0\relax\@empty\@empty}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks0\relax\@empty\@empty}
```

Lưu ý việc dùng `\relax` để kết thúc việc TeX tìm kiếm các chữ số tiếp theo—bạn cũng có thể thay `\relax` bằng một khoảng trắng để làm dấu kết thúc.

Ví dụ sau tạo ra đầu ra giống hệt các định nghĩa gốc của `\leftmark` và `\rightmark`.

```latex
\documentclass{book}
% Định nghĩa lại \leftmark và \rightmark để dùng
% \botmarks0 và \firstmarks0 tương ứng
% Lưu ý: mã loại của '@' tạm thời được đổi thành 11
% để cho phép dùng nó trong tên lệnh
\catcode `@=11
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks0\relax\@empty\@empty}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks0\relax\@empty\@empty}
\catcode `@=12
% Dùng kích thước trang nhỏ tiện lợi
\usepackage[paperheight=16cm,paperwidth=12cm,textwidth=10cm]{geometry}
\title{Hồi ký của một người dùng \TeX{}}
\author{Overleaf}
\begin{document}
\frontmatter
\maketitle
Đây là phần đầu sách sử dụng chữ số La Mã.
\mainmatter
\chapter{Tôi bắt đầu từ đâu?}
Chương 1: Một chương ngắn.
\newpage
\section{Lúc bắt đầu...}
Một mục.
\newpage
Một mục khác.
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Using+%CE%B5-TeX%E2%80%99s+extended+marks+command\&snip=%5Cdocumentclass%7Bbook%7D%0A%25+Redefine+%5Cleftmark+and+%5Crightmark+to+use+%0A%25+%5Cbotmarks0+and+%5Cfirstmarks0+respectively%0A%25+NB%3A+category+code+of+%27%40%27+temporarily+changed+to+11%0A%25+to+enable+its+use+in+command+names%0A%5Ccatcode+%60%40%3D11%0A%5Crenewcommand%7B%5Cleftmark%7D%7B%5Cexpandafter%5C%40leftmark%5Cbotmarks0%5Crelax%5C%40empty%5C%40empty%7D%0A%5Crenewcommand%7B%5Crightmark%7D%7B%5Cexpandafter%5C%40rightmark%5Cfirstmarks0%5Crelax%5C%40empty%5C%40empty%7D%0A%5Ccatcode+%60%40%3D12%0A%25+Use+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Ctitle%7BMemoirs+of+a+%5CTeX%7B%7D+user%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cfrontmatter%0A%5Cmaketitle%0AThis+is+frontmatter+which+uses+Roman+numerals.%0A%5Cmainmatter%0A%5Cchapter%7BWhere+do+I+start%3F%7D%0AChapter+1%3A+A+short+chapter.%0A%5Cnewpage%0A%5Csection%7BIn+the+beginning...%7D%0AA+section.%0A%5Cnewpage%0AAnother+section.%0A%5Cend%7Bdocument%7D)

**Ghi chú về ε-TeX**

Như [như đã lưu ý ở trên](#etex), ε-TeX giới thiệu `\marks` lệnh:

```latex
\marks n {stuff to store}
```

lệnh này mở rộng `\mark` tính năng gốc của bộ máy TeX của Knuth và có sẵn trong cả ba bộ máy TeX phổ biến: pdfTeX, LuaTeX và XeTeX.

việc triển khai của ε-TeX cũng giới thiệu các biến dấu toàn cục mới `\firstmarks n`, `\botmarks n` và `\topmarks n`: mỗi lớp một biến `n`. Các biến dấu dựa trên lớp này được xác định [bằng các cơ chế nêu ở trên](#pre-output-checks-looking-for-mark-nodes), và tất cả đều có thể được dùng để tạo đầu trang và chân trang.

Bạn có thể dùng bất kỳ $$2^{15}$$ = 32768 lớp dấu, từ 0 đến 32767, trong các định nghĩa lại của `\leftmark` hoặc `\rightmark`. Điều đó giả định rằng bạn đã cung cấp (chèn) dữ liệu đánh dấu phù hợp cho lớp dấu bạn chọn, `n`, thông qua `\marks n{{left}{right}}`.

Lưu ý rằng LuaTeX cung cấp $$2^{16}$$ = 65536 lớp dấu, với `n` trải từ 0 đến 65535.

**Ví dụ dùng lớp dấu 10**

Ví dụ này minh họa việc dùng lớp dấu 10 (được chọn ngẫu nhiên) để tạo đầu trang tài liệu. Tài liệu mẫu dàn 6 trang chứa chuỗi dấu được trình bày trong [ví dụ minh họa ở cuối bài viết này](#a-worked-example-to-show-how-tex-engines-determine-values-for-botmark-topmark-and-firstmark). Nghiên cứu ví dụ đó sẽ cho thấy vì sao bộ máy TeX đã chọn một dấu cụ thể, $$\alpha$$, $$\beta$$, $$\gamma$$ và $$\delta$$, để dùng trong từng đầu trang.

Ta bắt đầu bằng cách định nghĩa một macro tiện dụng, `\domark`, dùng `\marks 10` để chèn dữ liệu đánh dấu tuân theo quy ước của LaTeX `{left}{right}` :

```latex
\newcommand{\domark}[2]{\marks 10{{#1}{#2}}}
```

Các dấu của lớp 10 được làm cho cơ chế đầu trang và chân trang của LaTeX truy cập được bằng cách định nghĩa lại `\leftmark` và `\rightmark`—với một ít thông tin bổ sung:

```latex
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks10 \@empty\@empty{} (qua \texttt{\string\botmarks10})}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks10 \@empty\@empty{} (qua \texttt{\string\firstmarks10})}
```

Sau khi chèn một số dấu (lớp 10), bộ máy TeX (ở đây là pdfTeX) tạo ra các biến dấu toàn cục cho lớp 10 một cách tự động—`\botmarks10`, `\topmarks10` và `\firstsmarks10` nào `\leftmark` và `\rightmark` được dùng để tạo đầu trang.

```latex
\documentclass{book}
% Một lệnh ngắn để dùng dấu với lớp 10
% và theo cấu trúc dấu của LaTeX {left}{right}
\newcommand{\domark}[2]{\marks 10{{#1}{#2}}}
% Định nghĩa lại \leftmark và \rightmark để dùng
% \botmarks10 và \firstmarks10 tương ứng
\catcode`@=11
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks10 \@empty\@empty{} (qua \texttt{\string\botmarks10})}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks10 \@empty\@empty{} (qua \texttt{\string\firstmarks10})}
\catcode`@=12
\title{Minh họa các dấu nâng cao của \(\varepsilon\)-\TeX}
\author{Overleaf}
\date{Tháng 8 năm 2022}
\begin{document}

Trang 1: Không có dấu nào được thêm nên tất cả các biến dấu vẫn ở trạng thái khởi tạo: rỗng (NULL).

\newpage
Trang 2: Dấu $\alpha$ được thêm vào trang này thông qua

\verb|\domark{$\alpha$-left}{$\alpha$-right}|\domark{$\alpha$-left}{$\alpha$-right}

\newpage
Trang 3: Không có dấu mới nào được thêm vào trang này.

\newpage
Trang 4: Dấu $\beta$ rồi đến dấu $\gamma$ được thêm vào trang này thông qua

\verb|\domark{$\beta$-left}{$\beta$-right}|

\verb|\domark{$\gamma$-left}{$\gamma$-right}|.
\domark{$\beta$-left}{$\beta$-right}
\domark{$\gamma$-left}{$\gamma$-right}

\newpage
Trang 5: Dấu $\delta$ được thêm vào trang này thông qua

\verb|\domark{$\delta$-left}{$\delta$-right}|
\domark{$\delta$-left}{$\delta$-right}

\newpage
Trang 6: Không có dấu nào được thêm vào trang này.
\end{document}
```

[Mở ví dụ này trong Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Using+e-TeX+global+marks+variables\&snip=%5Cdocumentclass%7Bbook%7D%0A%25+A+short+command+to+use+marks+with+class+10%0A%25+and+following+LaTeX%27s+mark+structure+%7Bleft%7D%7Bright%7D%0A%5Cnewcommand%7B%5Cdomark%7D%5B2%5D%7B%5Cmarks+10%7B%7B%231%7D%7B%232%7D%7D%7D%0A%25+Redefine+%5Cleftmark+and+%5Crightmark+to+use+%0A%25+%5Cbotmarks10+and+%5Cfirstmarks10+respectively%0A%5Ccatcode%60%40%3D11%0A%5Crenewcommand%7B%5Cleftmark%7D%7B%5Cexpandafter%5C%40leftmark%5Cbotmarks10+%5C%40empty%5C%40empty%7B%7D+%28via+%5Ctexttt%7B%5Cstring%5Cbotmarks10%7D%29%7D%0A%5Crenewcommand%7B%5Crightmark%7D%7B%5Cexpandafter%5C%40rightmark%5Cfirstmarks10+%5C%40empty%5C%40empty%7B%7D+%28via+%5Ctexttt%7B%5Cstring%5Cfirstmarks10%7D%29%7D%0A%5Ccatcode%60%40%3D12%0A%5Ctitle%7BDemonstrating+%5C%28%5Cvarepsilon%5C%29-%5CTeX%E2%80%99s+enhanced+marks%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cdate%7BAugust+2022%7D%0A%5Cbegin%7Bdocument%7D%0A%0APage+1%3A+No+marks+added+so+all+mark+variables+remain+in+their+initialized+state%3A+empty+%28NULL%29.%0A%0A%5Cnewpage%0APage+2%3A+%24%5Calpha%24-mark+added+to+this+page+via%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Calpha%24-left%7D%7B%24%5Calpha%24-right%7D%7C%5Cdomark%7B%24%5Calpha%24-left%7D%7B%24%5Calpha%24-right%7D%0A%0A%5Cnewpage%0APage+3%3A+No+new+marks+added+to+this+page.%0A%0A%5Cnewpage%0APage+4%3A+%24%5Cbeta%24-mark+followed+by+%24%5Cgamma%24-mark+added+to+this+page+via%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Cbeta%24-left%7D%7B%24%5Cbeta%24-right%7D%7C%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Cgamma%24-left%7D%7B%24%5Cgamma%24-right%7D%7C.%0A%5Cdomark%7B%24%5Cbeta%24-left%7D%7B%24%5Cbeta%24-right%7D%0A%5Cdomark%7B%24%5Cgamma%24-left%7D%7B%24%5Cgamma%24-right%7D%0A%0A%5Cnewpage%0APage+5%3A+%24%5Cdelta%24-mark+added+to+this+page+via%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Cdelta%24-left%7D%7B%24%5Cdelta%24-right%7D%7C%0A%5Cdomark%7B%24%5Cdelta%24-left%7D%7B%24%5Cdelta%24-right%7D%0A%0A%5Cnewpage%0APage+6%3A+No+marks+added+to+this+page.%0A%5Cend%7Bdocument%7D)

Hình sau cho thấy các đầu trang được tạo bởi ví dụ này:

![Hình minh họa đầu ra từ mã LaTeX sử dụng các lệnh dấu mở rộng của ε-TeX](/files/13e566514f17986da0b54ab234b0841039a39ec9)

* **Lưu ý**: Đầu trang trên trang 1 được tạo vào thời điểm cả ba biến dấu của lớp 10—`\botmarks10`, `\topmarks10` và `\firstsmarks10`—đều rỗng. Kết quả cuối cùng là `\rightmark` (cho trang 1) chỉ chèn mảnh đầu trang cuối cùng: `(qua \texttt{\string\firstmarks10})`, như được minh họa trong hình trên.

## Một ví dụ minh họa cho thấy cách các bộ máy TeX xác định giá trị cho \botmark, \topmark và \firstmark

![Db.gif](/files/28f5f222a369c77dd7efd194fc659493d508c827)![Db.gif](/files/28f5f222a369c77dd7efd194fc659493d508c827) Có vẻ phù hợp khi mô phỏng việc Knuth dùng các ký hiệu ngoặt nguy hiểm kép (ảnh do [trang web này](http://www.truetex.com/db.htm)) vì nội dung này có phần mức thấp và “hé mở dưới nắp máy”—dù chúng tôi hy vọng nó vẫn có thể hữu ích cho những độc giả can đảm muốn hiểu thêm vài chi tiết.

Phần thảo luận sau đây dựa sát vào ví dụ cuối cùng ở trang 258 của [The TeXbook](https://www.amazon.co.uk/TeXbook-Donald-Knuth/dp/0201134489). Ở đây, chúng tôi đã biên tập lại và dàn lại ví dụ đó cho những người không có quyền truy cập vào The TeXbook:

![Bản biên tập và dàn lại của một ví dụ từ trang 258 của The TeXbook](/files/93f854962203335eef582d782a1d6c2f27030595)

Bảng trong hình này được sao lại từ một bảng do Knuth cung cấp nhưng, giống như bản gốc, không có lời giải thích về cách nó được suy ra. Ở đây chúng tôi sẽ đề cập điều đó để cung cấp thêm chi tiết cho thấy các giá trị của `\botmark`, `\topmark` và `\firstmark` được xác định như thế nào—để có được những chi tiết này cần phải khám phá mã nguồn của một bộ máy TeX!

Quá trình đặt giá trị cho `\botmark`, `\topmark` và `\firstmark` có thể được tóm tắt bằng 3 đoạn giả mã ngắn như được thể hiện trong sơ đồ sau và các giải thích tiếp theo:

1. Kiểm tra trước nội dung
2. Vòng lặp nội dung
3. Kiểm tra sau nội dung

Lưu ý:

* Các kiểm tra ở bước 1 “Kiểm tra trước nội dung” và bước 3 “Kiểm tra sau nội dung” được thực hiện một lần cho mỗi trang.
* Bước 2 “Vòng lặp nội dung” liên quan đến việc TeX quét qua nội dung trang để tìm các nút dấu, rồi dùng chúng để đặt các giá trị biến dấu như minh họa.

![Hình cho thấy các phiên bản giả mã của mã dùng để đặt giá trị cho ba biến dấu toàn cục được các bộ máy TeX sử dụng](/files/b32cf87084bf247ed2da6a72fb869f68b9802668)

Mỗi khi TeX tìm thấy một chỗ ngắt trang phù hợp, nó gửi nội dung của trang đó để xử lý cuối cùng, thực hiện ba bước xử lý dấu này cho mỗi trang trong tài liệu của bạn. Các bước xử lý được gán nhãn 1, 2 và 3 được nhắc đến trong sơ đồ cuối cùng trong phần này.

Lưu ý rằng:

* trước khi trang đầu tiên được xử lý, cả ba biến dấu toàn cục `\botmark`, `\topmark` và `\firstmark` đã được khởi tạo là rỗng (NULL).
* các giá trị cuối cùng của `\botmark`, `\topmark` và `\firstmark` được xác định ở cuối *trước đó* trang trở thành (các) giá trị đầu vào để xử lý *hiện tại* trang—trang đang được xử lý.

Các đoạn mã sau là ***giả mã*** được suy ra (tóm tắt) từ mã nguồn thực tế của bộ máy TeX. Mục tiêu là cung cấp một bản tóm tắt ngắn gọn giúp minh họa các nguyên lý then chốt liên quan.

**Bước 1: Kiểm tra trước nội dung** Trước khi TeX xem xét nội dung thực tế của trang hiện tại, nó kiểm tra xem giá trị hiện tại `\botmark` —tức là, phát sinh từ *trước đó* trang—có rỗng (NULL) không:

```latex
if(\botmark != NULL)
{
   \topmark = \botmark;
   \firstmark= NULL;
}
```

Trong kiểm tra này, nếu `\botmark` (từ *trước đó* trang) là *không* rỗng:

* `\topmark` cho trang *hiện tại* được đặt thành *trước đó* của trang `\botmark` giá trị
* `\firstmark`, còn cho *hiện tại* trang (đang được xử lý), được đặt thành rỗng (NULL): bắt đầu trang này với giả định rằng không có `\mark` nút nào.

Lưu ý rằng kiểm tra này được thực hiện *một lần* cho mỗi trang đang được xử lý.

**Bước 2: Vòng lặp nội dung** Tiếp theo, TeX lặp qua nội dung trang; một phần của vòng lặp đó bao gồm việc tìm `\mark` các nút:

```latex
if(type(node)==mark_node)
{
   if(\firstmark==NULL)
   {
      \firstmark=node(text);
   }
   \botmark= node(text);
}
```

Phép kiểm tra này được áp dụng cho mọi nút mark nằm trong (được chứa trong) trang hiện tại. Phép kiểm tra trước đó (Bước 1, ở trên) có thể đã đặt `\firstmark` thành rỗng, vì vậy dấu đầu tiên được tìm thấy trong trang hiện tại sẽ trở thành giá trị của `\firstmark` và `\botmark`. Bất kỳ *tiếp theo* `\mark` nút được phát hiện trong khi thực thi vòng lặp này sẽ không thay đổi giá trị của `\firstmark`, vì nó không còn rỗng (NULL), mà `\botmark` được cập nhật—bởi vì đó là mục đích của `\botmark`: để lưu trữ lần cuối cùng nhìn thấy `\mark` nút cho trang này.

**Bước 3: Kiểm tra sau nội dung** Sau khi đã lặp qua nội dung trang, TeX áp dụng phép kiểm tra cuối cùng sau đây, cũng được thực hiện một lần cho mỗi trang:

```latex
if((\topmark != NULL)&&(\firstmark==NULL))
{
	\firstmark= \topmark;
}
```

* Nếu `\topmark` không rỗng (NULL), chúng ta biết từ Bước 1 rằng `\botmark` đối với trang trước không rỗng (NULL).
* Nếu `\firstmark` vẫn còn rỗng thì chúng ta chưa thấy bất kỳ `\mark` nút nào vì phép kiểm tra ở Bước 2 không được kích hoạt; do đó, `\firstmark` được đặt thành giá trị của `\topmark` mà cũng là giá trị của `\botmark` từ trang trước.

Sau khi áp dụng tuần tự ba bước này cho cả 6 trang của ví dụ của chúng ta, các giá trị của `\botmark`, `\topmark` và `\firstmark` được suy ra bằng các chuyển tiếp được minh họa trong sơ đồ dưới đây, trong đó:

* các hình chữ nhật bo tròn màu xanh nhạt là các giá trị cuối cùng của biến mark cho mỗi trang
* các hình vuông bo tròn màu xám nhạt biểu thị các giá trị tạm thời phát sinh trong quá trình xử lý
* các mũi tên có nhãn biểu thị sự thay đổi trong các giá trị của biến mark theo các bước 1, 2 hoặc 3 trong sơ đồ ở trên—hoặc một giá trị không bị thay đổi bởi bất kỳ bước nào; được gắn nhãn “không đổi”.

Sơ đồ sau đây cho thấy ba đoạn giả mã tạo ra các giá trị cuối cùng của `\botmark`, `\topmark` và `\firstmark` được liệt kê trong bảng ở trang 258 của The TeXbook.

![Một sơ đồ chuyển tiếp đi kèm ví dụ từ trang 258 của The TeXbook, cho thấy các chuyển tiếp nội bộ khi các biến mark toàn cục được gán giá trị của chúng](/files/a8471e4345f11394133183f7e9a4f03b60195d70)


---

# 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/23-how-does-latex-typeset-headers-and-footers.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.
