> 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/03-writing-your-own-package.md).

# Viết gói của riêng bạn

Đôi khi lựa chọn tốt nhất để sử dụng các lệnh và macro của riêng bạn trong một tài liệu là viết một gói mới từ đầu. Bài viết này giải thích cấu trúc chính của một gói mới.

## Giới thiệu

Điều đầu tiên cần làm trước khi lập trình một gói mới là xác định xem bạn thực sự có cần một gói 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 thứ 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 gói có thể được mô tả khái quát trong bốn phần sau:

* ***Định danh***. Tệp này tự khai báo là một gói được viết bằng cú pháp LaTeX2ε.
* ***Các khai báo sơ bộ***. Ở đây các gói 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 mã hóa.
* ***Tùy chọn***. Gói 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 gói. Hầu như mọi thứ mà một gói 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, *examplepackage.sty*, sẽ được trình bày.

### Định danh

Có hai lệnh đơn giản mà mọi gói đều phải có:

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/24 Gói LaTeX ví dụ]
```

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

Lệnh `ProvidesPackage{examplepackage}[...]` xác định gói này là *examplepackage* 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 gói trong Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

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

Phần lớn các gói mở rộng và tùy biến các gói hiện có, đồng thời cũng cần một số gói bên ngoài để hoạt động. Dưới đây, một số mã bổ sung được thêm vào gói mẫu "examplepackage.sty".

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/21 Gói ví dụ]

\RequirePackage{imakeidx}
\RequirePackage{xstring}
\RequirePackage{xcolor}
\definecolor{greycolour}{HTML}{525252}
\definecolor{sharelatexcolour}{HTML}{882B21}
\definecolor{mybluecolour}{HTML}{394773}
\newcommand{\wordcolour}{greycolour}
```

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 `\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 gói hoặc lớp mới.

[Mở một ví dụ về cách viết một gói trong Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

### Tùy chọn

Để tạo sự linh hoạt cho các gói, một vài tùy chọn bổ sung là rất hữu ích. Phần tiếp theo trong tệp "examplepackage.sty" xử lý các tham số được truyền cho câu lệnh nhập gói.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/21 Gói ví dụ]

\RequirePackage{imakeidx}
\RequirePackage{xstring}
\RequirePackage{xcolor}
\definecolor{greycolour}{HTML}{525252}
\definecolor{sharelatexcolour}{HTML}{882B21}
\definecolor{mybluecolour}{HTML}{394773}
\newcommand{\wordcolour}{greycolour}

\DeclareOption{red}{\renewcommand{\wordcolour}{sharelatexcolour}}
\DeclareOption{blue}{\renewcommand{\wordcolour}{mybluecolour}}
\DeclareOption*{\PackageWarning{examplepackage}{Unknown ‘\CurrentOption’}}
\ProcessOptions\relax
```

Dưới đây là mô tả các lệnh chính có thể xử lý các tùy chọn được truyền cho gói.

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 sử dụng.

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ố, là 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ẽ in ra một cảnh báo bằng lệnh tiếp theo:

`\PackageWarning{}{}`. Xem [xử lý lỗi](#handling-errors) để xem mô tả về chức năng của lệnh này.

`\CurrentOption` lưu tên của tùy chọn gói đ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 nhập. 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ự do các lệnh gọi chỉ định.

Trong ví dụ, nếu các tùy chọn *red* hoặc *blue* được truyền vào `\usepackage` lệnh trong tài liệu, lệnh `\wordcolor` được định nghĩa lại. Cả hai màu này và màu xám mặc định đều đã được định nghĩa trong phần [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 gói trong Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

### Khai báo thêm

Trong phần này hầu hết các lệnh sẽ xuất hiện. Trong "examplepackage.sty". Bên dưới bạn có thể xem toàn bộ tệp gói.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/21 Gói ví dụ]

\RequirePackage{imakeidx}
\RequirePackage{xstring}
\RequirePackage{xcolor}
\definecolor{greycolour}{HTML}{525252}
\definecolor{sharelatexcolour}{HTML}{882B21}
\definecolor{mybluecolour}{HTML}{394773}
\newcommand{\wordcolour}{greycolour}

\DeclareOption{red}{\renewcommand{\wordcolour}{sharelatexcolour}}
\DeclareOption{blue}{\renewcommand{\wordcolour}{mybluecolour}}
\DeclareOption*{\PackageWarning{examplepackage}{Unknown ‘\CurrentOption’}}
\ProcessOptions\relax

%%Môi trường được đánh số
\newcounter{example}[section]
\newenvironment{example}[1][]{\refstepcounter{example}\par\medskip
\noindent \textbf{Môi~trường~của~tôi~\theexample. #1} \rmfamily}{\medskip}

%%Các từ quan trọng được thêm vào mục lục và được in bằng màu khác
\newcommand{\important}[1]
{\IfSubStr{#1}{!}
    {\textcolor{\wordcolour}{\textbf{\StrBefore{#1}{!}~\StrBehind{#1}{!}}}\index{#1}}
    {\textcolor{\wordcolour}{\textbf{#1}}\index{#1}\kern-1pt}
}
```

Gói này định nghĩa môi trường mới `ví dụ`, và một lệnh mới `\important`, lệnh này in các từ bằng một màu đặc biệt và thêm chúng vào mục lục.

Để hiểu đầy đủ từng lệnh, 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).

Dưới đây là một tài liệu sử dụng gói *examplepackage.sty*.

```latex
\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage[red]{examplepackage}

\makeindex

\title{Ví dụ về gói}
\author{Nhóm Learn ShareLaTeX}
\date{ }

\begin{document}

\maketitle

\section{Giới thiệu}
Trong tài liệu này, một gói mới được kiểm thử. Gói này cho phép các môi trường được đánh số đặc biệt
các môi trường

\begin{example}
Văn bản này nằm trong một môi trường đặc biệt, một số văn bản in đậm được in
ở đầu và một thụt đầu dòng mới được đặt.
\end{example}

Ngoài ra, có một lệnh đặc biệt cho \important{important!words} sẽ được
in bằng một \important{màu} đặc biệt tùy thuộc vào tham số được dùng trong câu lệnh
nhập \important{gói}. Bởi vì nó \important{quan trọng}.

\printindex

\end{document}
```

![WrittingPackagesEx1.png](/files/d4c1dc1dde4b2257c539dae124e95b07612e802a)

Lưu ý lệnh

```latex
\usepackage[red]{examplepackage}
```

[Mở một ví dụ về cách viết một gói trong Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

## Xử lý lỗi

Khi phát triển các gói 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ì đó đã xảy ra sai. Có bốn lệnh chính để báo lỗi trong trình biên dịch.

* `\PackageError{*package-name*}{*error-text*}{*help-text*}`. Nhận ba tham số, mỗi tham số nằm trong dấu ngoặc nhọn: tên gói, 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 tạm dừng vì lỗi.
* `\PackageWarning{*package-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.
* `\PackageWarningNoLine{*package-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.
* `\PackageInfo{*package-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 gói Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

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

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

* `\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à như `\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)
* [Tự viết lớp của riêng bạn](/latex/vi/tep-lop/04-writing-your-own-class.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 các gói và người viết 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/03-writing-your-own-package.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.
