> 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/tep-lop/04-writing-your-own-class.md).

# Tự viết lớp của riêng bạn

Đôi khi lựa chọn tốt nhất để tùy biến một tài liệu là viết một lớp mới từ đầu. Bài viết này giải thích cấu trúc chính và các lệnh cần thiết trong một lớp mới.

## Giới thiệu

Điều đầu tiên cần làm trước khi viết mã cho một lớp mới là xác định xem bạn có thực sự cần một lớp mới hay không. Bạn nên [tìm kiếm trên CTAN (Mạng Lưu trữ TeX Toàn diện)](http://www.ctan.org/ctan-portal/search/) và xem liệu đã có ai tạo ra thứ gì tương tự với lớp tài liệu bạn cần hay chưa.

Một điều quan trọng khác cần lưu ý là [sự khác nhau giữa các gói và các lớp](/latex/vi/tep-lop/01-understanding-packages-and-class-files.md). Việc chọn sai có thể ảnh hưởng đến tính linh hoạt của sản phẩm cuối cùng.

## Cấu trúc chung

Cấu trúc của tất cả các tệp lớp có thể được mô tả đại khái trong bốn phần sau:

* ***Định danh***. Tệp tự khai báo là một lớp được viết bằng cú pháp LaTeX2ε.
* ***Các khai báo sơ bộ***. Ở đây các gói và lớp bên ngoài cần thiết được nhập vào. Ngoài ra, trong phần này của tệp, các lệnh và định nghĩa cần cho các tùy chọn đã khai báo được viết.
* ***Tùy chọn***. Lớp khai báo và xử lý các tùy chọn.
* ***Khai báo thêm***. Phần thân chính của lớp. Hầu như mọi thứ mà một lớp làm đều được định nghĩa ở đây.

Ở các tiểu mục tiếp theo sẽ trình bày mô tả chi tiết hơn về cấu trúc và một ví dụ hoạt động, *exampleclass.cls*, sẽ được trình bày.

### Định danh

Có hai lệnh đơn giản mà mọi lớp phải có:

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{exampleclass}[2014/08/16 Example LaTeX class]
```

Lệnh `\NeedsTeXFormat{LaTeX2e}` đặt phiên bản LaTeX để lớp hoạt động. Ngoài ra, có thể thêm một ngày trong ngoặc vuông để chỉ định ngày phát hành tối thiểu được yêu cầu.

Lệnh `ProvidesClass{exampleclass}[...]` xác định lớp này là *exampleclass* và, bên trong dấu ngoặc vuông, ngày phát hành và một số thông tin bổ sung được bao gồm. Ngày nên ở dạng YYYY/MM/DD

[Mở một ví dụ về cách viết một lớp trong Overleaf](https://www.overleaf.com/project/new/template/19419?id=65524436\&templateName=An+example+of+writing+a+LaTeX+class\&latexEngine=\&texImage=texlive-full%3A2020.1\&mainFile=)

### Các khai báo sơ bộ

Phần lớn các lớp đều kế thừa và tùy biến những lớp hiện có, đồng thời cũng cần một số gói bên ngoài để hoạt động. Bên dưới, một ít mã nữa được thêm vào lớp mẫu `exampleclass.cls`.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{exampleclass}[2014/08/16 Example LaTeX class]

\newcommand{\headlinecolor}{\normalcolor}
\LoadClass[twocolumn]{article}
\RequirePackage{xcolor}
\definecolor{slcolor}{HTML}{882B21}
```

Các lệnh trong phần này hoặc khởi tạo một số tham số sẽ được dùng sau này để quản lý các tùy chọn, hoặc nhập các tệp bên ngoài.

Lệnh `\LoadClass[twocolumn]{article}` nạp lớp `article` với tham số bổ sung `twocolumn`. Vì vậy tất cả các lệnh trong lớp chuẩn `article` sẽ tự động có sẵn trong **ví dụ** lớp, ngoại trừ việc tài liệu sẽ được in theo định dạng hai cột.

`\RequirePackage` rất giống với lệnh quen thuộc `\usepackage`, việc thêm các tham số tùy chọn trong dấu ngoặc vuông cũng sẽ hoạt động. Điểm khác duy nhất là `\usepackage` không thể được dùng trước `\documentclass` lệnh. Bạn rất nên dùng `\RequirePackage` khi viết các lớp hoặc gói mới.

[Mở một ví dụ về cách viết một lớp trong Overleaf](https://www.overleaf.com/project/new/template/19419?id=65524436\&templateName=An+example+of+writing+a+LaTeX+class\&latexEngine=\&texImage=texlive-full%3A2020.1\&mainFile=)

### Tùy chọn

Để cho phép một chút linh hoạt trong các lớp, một vài tùy chọn bổ sung là rất hữu ích. Phần tiếp theo trong tệp `exampleclass.cls` xử lý các tham số được truyền cho lệnh lớp tài liệu. Chúng tôi cũng đã chuyển `\LoadClass` sang *sau* các tùy chọn được xử lý, sao cho các tùy chọn đặt trong tệp .tex có thể được truyền tới lớp cơ sở.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{exampleclass}[2014/08/16 Example LaTeX class]

\newcommand{\headlinecolor}{\normalcolor}
\RequirePackage{xcolor}
\definecolor{slcolor}{HTML}{882B21}

\DeclareOption{onecolumn}{\OptionNotUsed}
\DeclareOption{green}{\renewcommand{\headlinecolor}{\color{green}}}
\DeclareOption{red}{\renewcommand{\headlinecolor}{\color{slcolor}}}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions\relax
\LoadClass[twocolumn]{article}
```

Ở đây có bốn lệnh chính xử lý các tùy chọn được truyền cho lớp.

Lệnh `\DeclareOption{}{}` xử lý một tùy chọn nhất định. Nó nhận hai tham số, tham số đầu tiên là tên của tùy chọn và tham số thứ hai là mã sẽ thực thi nếu tùy chọn đó được truyền vào.

Lệnh `\OptionNotUsed` sẽ in một thông báo trong trình biên dịch và nhật ký, tùy chọn sẽ không được dùng. Trong trường hợp này tài liệu được đặt thành hai cột và nếu người dùng cố thay đổi nó thành một cột thì sẽ không được, tùy chọn sẽ bị bỏ qua.

Lệnh `\Declareoption*{}` xử lý mọi tùy chọn không được định nghĩa rõ ràng. Nó chỉ nhận một tham số, tức mã sẽ thực thi khi một tùy chọn không xác định được truyền vào. Trong trường hợp này nó sẽ chạy lệnh tiếp theo:

`\PassOptionsToClass{}{}`. Truyền tùy chọn nằm trong cặp ngoặc nhọn thứ nhất đến lớp tài liệu được đặt trong cặp ngoặc nhọn thứ hai. Trong ví dụ, tất cả các tùy chọn không xác định sẽ được truyền đến **article** lớp tài liệu.

`\CurrentOption` lưu tên của tùy chọn lớp đang được xử lý tại một thời điểm nhất định.

Lệnh `\ProcessOptions\relax` thực thi mã cho từng tùy chọn và phải được chèn sau khi tất cả các lệnh xử lý tùy chọn đã được viết. Có một phiên bản có dấu sao của lệnh này sẽ thực thi các tùy chọn theo đúng thứ tự được chỉ định bởi các lệnh gọi.

Trong ví dụ, nếu các tùy chọn `red` hoặc `green` được truyền tới tài liệu; phông chữ dùng cho tiêu đề và các phần sẽ được đặt theo màu tương ứng. Màu có tên là `slcolor` đã được định nghĩa trong [các khai báo sơ bộ](#preliminary-declaration) sau khi nhập `xcolor` gói.

[Mở một ví dụ về cách viết một lớp trong Overleaf](https://www.overleaf.com/project/new/template/19419?id=65524436\&templateName=An+example+of+writing+a+LaTeX+class\&latexEngine=\&texImage=texlive-full%3A2020.1\&mainFile=)

### Khai báo thêm

Trong phần này phần lớn các lệnh sẽ xuất hiện. Trong "exampleclass.cls", kích thước trang, cỡ chữ cho tiêu đề, phần thân và các mục được thiết lập. Bên dưới bạn có thể xem toàn bộ tệp lớp.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{exampleclass}[2014/08/16 Example LaTeX class]

\newcommand{\headlinecolor}{\normalcolor}
\RequirePackage{xcolor}
\definecolor{slcolor}{HTML}{882B21}

\DeclareOption{onecolumn}{\OptionNotUsed}
\DeclareOption{green}{\renewcommand{\headlinecolor}{\color{green}}}
\DeclareOption{red}{\renewcommand{\headlinecolor}{\color{slcolor}}}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions\relax
\LoadClass[twocolumn]{article}

\renewcommand{\maketitle}{%
    \twocolumn[%
        \fontsize{50}{60}\fontfamily{phv}\fontseries{b}%
        \fontshape{sl}\selectfont\headlinecolor
        \@title
        \medskip
        ]%
}

\renewcommand{\section}{%
    \@startsection
    {section}{1}{0pt}{-1.5ex plus -1ex minus -.2ex}%
    {1ex plus .2ex}{\large\sffamily\slshape\headlinecolor}%
}

\renewcommand{\normalsize}{\fontsize{9}{10}\selectfont}
\setlength{\textwidth}{17.5cm}
\setlength{\textheight}{22cm}
\setcounter{secnumdepth}{0}
```

Để hiểu các lệnh còn lại, hãy xem [hướng dẫn tham khảo](#reference-guide) và các liên kết trong [phần đọc thêm](#further-reading).

Bốn lệnh cuối trong ví dụ cho thấy bốn điều mà mọi lớp phải chứa:

* Định nghĩa của `normalsize`. Đặt mặc định [cỡ phông](/latex/vi/phong-chu/01-font-sizes-families-and-styles.md).
* Một giá trị mặc định cho [`textwidth`](/latex/vi/dinh-dang/07-page-size-and-margins.md)
* Một giá trị mặc định cho [`textheight`](/latex/vi/dinh-dang/07-page-size-and-margins.md)
* Các đặc tả cho [đánh số trang](/latex/vi/dinh-dang/03-page-numbering.md).

Bên dưới là một tài liệu sử dụng lớp *exampleclass.cls*.

```latex
\documentclass[red]{exampleclass}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}

\usepackage{blindtext}

\title{Example to show how classes work}
\author{Nhóm Learn ShareLaTeX}
\date{August 2014}

\begin{document}

\maketitle

\noindent
Hãy bắt đầu với một ví dụ hoạt động đơn giản ở đây.

\blindtext

\section{Giới thiệu}

Bài toán Monty Hall...

\section{The same thing}

Monty...
```

![WrittingClassesEx1.png](/files/2b464d6c58af631bc8e291198031bc3ca68073fb)

Lưu ý rằng lệnh đầu tiên ở đây là

```latex
\documentclass[red]{exampleclass}
```

[Mở một ví dụ về cách viết một lớp trong Overleaf](https://www.overleaf.com/project/new/template/19419?id=65524436\&templateName=An+example+of+writing+a+LaTeX+class\&latexEngine=\&texImage=texlive-full%3A2020.1\&mainFile=)

## Xử lý lỗi

Khi phát triển các lớp mới, điều quan trọng là phải xử lý các lỗi có thể xảy ra để cho người dùng biết rằng có điều gì đó không ổn. Có bốn lệnh chính để báo lỗi trong trình biên dịch.

* `\ClassError{*class-name*}{*error-text*}{*help-text*}`. Nhận ba tham số, mỗi tham số nằm trong ngoặc nhọn: tên lớp, văn bản lỗi sẽ được hiển thị (quá trình biên dịch sẽ bị tạm dừng), và văn bản trợ giúp sẽ được in ra nếu người dùng nhấn "h" khi quá trình biên dịch dừng vì lỗi.
* `\ClassWarning{*class-name*}{*warning-text*}`. Trong trường hợp này, văn bản sẽ được hiển thị nhưng quá trình biên dịch sẽ không dừng. Nó sẽ hiển thị số dòng nơi cảnh báo xảy ra.
* `\ClassWarningNoLine{*class-name*}{*warning-text*}`. Hoạt động giống như lệnh trước, nhưng sẽ không hiển thị dòng nơi cảnh báo xảy ra.
* `\ClassInfo{*class name*}{*info-text*}`. Trong trường hợp này, thông tin ở tham số thứ hai sẽ chỉ được in trong tệp biên bản, bao gồm cả số dòng.

[Mở một ví dụ về cách viết một lớp trong Overleaf](https://www.overleaf.com/project/new/template/19419?id=65524436\&templateName=An+example+of+writing+a+LaTeX+class\&latexEngine=\&texImage=texlive-full%3A2020.1\&mainFile=)

## Hướng dẫn tham khảo

**Danh sách các lệnh thường dùng trong các lớp và gói**

* `\newcommand{*name*}{*definition*}`. Định nghĩa một [lệnh mới](/latex/vi/cac-lenh/01-commands.md#defining-a-new-command), tham số đầu tiên là tên của lệnh mới, tham số thứ hai là điều lệnh sẽ thực hiện.
* `\renewcommand{}{}`. Tương tự như `\newcommand` nhưng sẽ ghi đè một lệnh hiện có.
* `\providecommand{}{}`. Hoạt động tương tự như `\newcommand` nhưng nếu lệnh đã được định nghĩa thì lệnh này sẽ bị bỏ qua một cách âm thầm.
* `\CheckCommand{}{}`. Cú pháp giống như `\newcommand`, nhưng thay vào đó nó sẽ kiểm tra xem lệnh có tồn tại và có định nghĩa như mong đợi hay không; LaTeX sẽ hiển thị cảnh báo nếu lệnh không phải là điều mà `\CheckCommand` mong đợi.
* `\setlength{}{}`. Đặt độ dài của phần tử được truyền ở tham số thứ nhất thành giá trị được viết ở tham số thứ hai.
* `\mbox{}`. Tạo một hộp chứa các phần tử được viết bên trong dấu ngoặc nhọn.
* `\fbox{}`. Tương tự như `\mbox`, nhưng thực sự sẽ in một khung bao quanh nội dung.

## Đọc thêm

Để biết thêm thông tin, xem

* [Hiểu về các gói và tệp lớp](/latex/vi/tep-lop/01-understanding-packages-and-class-files.md)
* [Viết gói của riêng bạn](/latex/vi/tep-lop/03-writing-your-own-package.md)
* [Các lệnh](/latex/vi/cac-lenh/01-commands.md) và [Các môi trường](/latex/vi/cac-lenh/02-environments.md)
* [Độ dài trong LaTeX](/latex/vi/dinh-dang/01-lengths-in-latex.md)
* [Sử dụng màu trong LaTeX](/latex/vi/dinh-dang/13-using-colors-in-latex.md)
* [Quản lý trong một dự án lớn](/latex/vi/cau-truc-tai-lieu/07-management-in-a-large-project.md)
* [LaTeX2ε dành cho người viết lớp và gói](http://www.latex-project.org/guides/clsguide.pdf)
* [Ghi chú về lập trình trong TeX](http://pgfplots.sourceforge.net/TeX-programming-notes.pdf)
* [Phút thay vì giờ: Sử dụng tài nguyên LaTeX](https://tug.org/pracjourn/2005-4/hefferon/hefferon.pdf)
* [The LaTeX Companion. Ấn bản thứ hai](http://ptgmedia.pearsoncmg.com/images/9780201362992/samplepages/0201362996.pdf)


---

# 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/tep-lop/04-writing-your-own-class.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.
