> 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/zh-tw/lei-bie-dang/04-writing-your-own-class.md).

# 撰寫你自己的類別

有時，要自訂文件的最佳選擇是從頭撰寫一個新的類別。本文說明新類別所需的主要結構與指令。

## 簡介

在開始編寫新類別之前，首先要做的是判斷你是否真的需要一個新類別。建議先 [在 CTAN（Comprehensive TeX Archive Network）上搜尋](http://www.ctan.org/ctan-portal/search/) ，看看是否已有人做出與你所需的文件類別相似的東西。

另一件需要記住的重要事情是 [套件與類別之間的差異](/latex/zh-tw/lei-bie-dang/01-understanding-packages-and-class-files.md)。選錯會影響最終成品的彈性。

## 一般結構

所有類別檔的結構大致可分為下列四個部分：

* ***識別***。此檔案宣告自己是一個以 LaTeX2ε 語法撰寫的類別。
* ***前置宣告***。這裡會匯入所需的外部套件與類別。此外，檔案中這一部分也會撰寫所宣告選項所需的指令與定義。
* ***選項***。此類別會宣告並處理這些選項。
* ***更多宣告***。類別的主要內容。類別所做的大部分事情都在這裡定義。

在接下來的小節中，將會介紹更詳細的結構說明與一個可運作的範例， *exampleclass.cls*。

### 識別

所有類別都必須具備兩個簡單指令：

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

指令 `\NeedsTeXFormat{LaTeX2e}` 將此類別要運作的 LaTeX 版本設定好。此外，也可以在方括號內加入日期，用來指定所需的最小發布日期。

指令 `ProvidesClass{exampleclass}[...]` 將此類別識別為 *exampleclass* ，而方括號內則包含發布日期與一些附加資訊。日期應採用 YYYY/MM/DD 的格式

[在 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=)

### 前置宣告

大多數類別都會延伸並自訂既有類別，也需要一些外部套件才能運作。下面再為範例類別加入一些程式碼 `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}
```

此部分中的指令，要不是初始化一些之後會用來管理選項的參數，就是匯入外部檔案。

指令 `\LoadClass[twocolumn]{article}` 載入類別 `article` 並附加參數 `twocolumn`。因此，標準 `article` 類別中的所有指令都會自動在 **範例** 類別中可用，只是文件會以雙欄格式列印。

`\RequirePackage` 與眾所皆知的 `\usepackage`相當類似，於方括號內加入可選參數也同樣可行。唯一的差別是 `\usepackage` 在 `\documentclass` 指令之前不能使用。強烈建議在撰寫新類別或套件時使用 `\RequirePackage` 。

[在 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=)

### 選項

為了讓類別更有彈性，幾個額外的選項非常有用。檔案中的下一部分 `exampleclass.cls` 處理傳遞給文件類別指令的參數。我們也已將 `\LoadClass` 到 *之後* 的選項在此處處理，因此 .tex 檔中設定的選項可以傳遞給基底類別。

```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}
```

這裡有四個主要指令用來處理傳給此類別的選項。

指令 `\DeclareOption{}{}` 會處理給定的選項。它接受兩個參數，第一個是選項名稱，第二個是在該選項被傳入時要執行的程式碼。

指令 `\OptionNotUsed` 會在編譯器與日誌中印出訊息，而該選項不會被使用。在這種情況下，文件會被設為雙欄；如果使用者試圖將其改為單欄也不會生效，該選項將被忽略。

指令 `\Declareoption*{}` 會處理所有未明確定義的選項。它只接受一個參數，也就是在傳入未知選項時要執行的程式碼。在這種情況下，它會執行下一個指令：

`\PassOptionsToClass{}{}`。將第一組大括號內的選項傳遞給第二組大括號中設定的文件類別。在範例中，所有未知選項都會傳遞給 **article** 文件類別。

`\CurrentOption` 會儲存當下正在處理的類別選項名稱。

指令 `\ProcessOptions\relax` 會執行每個選項的程式碼，且必須在輸入完所有選項處理指令後插入。這個指令還有一個帶星號的版本，會依呼叫指令指定的確切順序執行各項選項。

在範例中，如果選項 `紅色` 或 `green` 被傳給文件，標題與各節所使用的字型將設為對應的顏色。名為 `slcolor` 的顏色是定義於 [前置宣告](#preliminary-declaration) 之後，並在匯入 `xcolor` 套件。

[在 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=)

### 更多宣告

在這一部分，大多數指令都會出現。在 "exampleclass.cls" 中，頁面尺寸以及標題、內文和各節的字體大小都已設定。下方可看到完整的類別檔。

```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}
```

要了解其餘指令，請參閱 [參考指南](#reference-guide) 以及 [進一步閱讀章節中的連結](#further-reading).

範例中的最後四個指令顯示了所有類別都必須包含的四項內容：

* 定義 `normalsize`。設定預設的 [字型大小](/latex/zh-tw/zi-xing/01-font-sizes-families-and-styles.md).
* 一個預設值 [`textwidth`](/latex/zh-tw/ge-shi-hua/07-page-size-and-margins.md)
* 一個預設值 [`textheight`](/latex/zh-tw/ge-shi-hua/07-page-size-and-margins.md)
* 頁碼編號的規格 [頁碼編號](/latex/zh-tw/ge-shi-hua/03-page-numbering.md).

下方是一份使用此類別的文件， *exampleclass.cls*.

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

\usepackage{blindtext}

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

\begin{document}

\maketitle

\noindent
我們先從這裡的一個簡單可運作範例開始。

\blindtext

\section{簡介}

蒙提霍爾問題...

\section{The same thing}

蒙提...
```

![WrittingClassesEx1.png](/files/8565fd2bbf5800ccfa59142572b55478c352b0c1)

請注意這裡的第一個指令是

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

[在 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=)

## 處理錯誤

在開發新類別時，處理可能發生的錯誤很重要，好讓使用者知道哪裡出了問題。編譯器中有四個主要指令可用來回報錯誤。

* `\ClassError{*class-name*}{*error-text*}{*help-text*}`。它接受三個參數，各自置於大括號內：類別名稱、將要顯示的錯誤文字（編譯流程會暫停），以及當使用者在因錯誤而暫停編譯時按下 "h" 所會印出的說明文字。
* `\ClassWarning{*class-name*}{*warning-text*}`。在這種情況下，文字會顯示出來，但編譯流程不會停止。它會顯示發生警告時的行號。
* `\ClassWarningNoLine{*class-name*}{*warning-text*}`。其作用與前一個指令相同，但不會顯示發生警告時的行號。
* `\ClassInfo{*class name*}{*info-text*}`。在這種情況下，第二個參數中的資訊只會印在 transcript 檔中，包括行號。

[在 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=)

## 參考指南

**類別與套件中常用指令清單**

* `\newcommand{*name*}{*definition*}`。定義一個 [新指令](/latex/zh-tw/zhi-ling/01-commands.md#defining-a-new-command)，第一個參數是新指令的名稱，第二個參數是該指令要做的事。
* `\renewcommand{}{}`與 `\newcommand` 相同，但會覆寫既有指令。
* `\providecommand{}{}`的作用與 `\newcommand` 相同，但若該指令已經定義，這個指令會靜默忽略。
* `\CheckCommand{}{}`。語法與 `\newcommand`相同，但它會檢查該指令是否存在且具有預期的定義；如果該指令不是 `\CheckCommand` 所預期的，LaTeX 會顯示警告。
* `\setlength{}{}`。將第一個參數所傳入元素的長度設為第二個參數所寫的值。
* `\mbox{}`。建立一個包含大括號內所寫元素的盒子。
* `\fbox{}`與 `\mbox`類似，但會在內容周圍實際印出一個框。

## 延伸閱讀

更多資訊請參見

* [了解套件與類別檔案](/latex/zh-tw/lei-bie-dang/01-understanding-packages-and-class-files.md)
* [撰寫你自己的套件](/latex/zh-tw/lei-bie-dang/03-writing-your-own-package.md)
* [命令](/latex/zh-tw/zhi-ling/01-commands.md) 以及 [環境](/latex/zh-tw/zhi-ling/02-environments.md)
* [LaTeX 中的長度](/latex/zh-tw/ge-shi-hua/01-lengths-in-latex.md)
* [在 LaTeX 中使用顏色](/latex/zh-tw/ge-shi-hua/13-using-colors-in-latex.md)
* [大型專案中的管理](/latex/zh-tw/wen-jian-jie-gou/07-management-in-a-large-project.md)
* [供類別與套件撰寫者使用的 LaTeX2ε](http://www.latex-project.org/guides/clsguide.pdf)
* [TeX 程式設計筆記](http://pgfplots.sourceforge.net/TeX-programming-notes.pdf)
* [少於小時的分鐘：使用 LaTeX 資源](https://tug.org/pracjourn/2005-4/hefferon/hefferon.pdf)
* [《The LaTeX Companion》。第二版](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/zh-tw/lei-bie-dang/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.
