> 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/ru/faily-klassov/04-writing-your-own-class.md).

# Написание собственного класса

Иногда лучший способ настроить документ — написать новый класс с нуля. В этой статье объясняются основная структура и команды, необходимые в новом классе.

## Введение

Первое, что нужно сделать перед написанием нового класса, — определить, действительно ли вам нужен новый класс или нет. Рекомендуется [искать на CTAN (Comprehensive TeX Archive Network)](http://www.ctan.org/ctan-portal/search/) и посмотреть, не создал ли кто-то уже что-то похожее на нужный вам класс документа.

Ещё один важный момент, который следует иметь в виду, — это [разница между пакетами и классами](/latex/ru/faily-klassov/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}` загружает класс `статью` с дополнительным параметром `twocolumn`. Поэтому все команды стандартного `статью` класса будут автоматически доступны в **example** классе, за исключением того, что документ будет напечатан в двухколоночном формате.

`\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{}{}`. Передаёт опцию из первой пары фигурных скобок классу документа, указанному во второй паре фигурных скобок. В примере все неизвестные опции будут переданы **статью** классу документа.

`\CurrentOption` сохраняет имя опции класса, которая в данный момент обрабатывается.

Команда `\ProcessOptions\relax` выполняет код для каждой опции и должна быть вставлена после того, как будут записаны все команды обработки опций. У этой команды есть звёздная версия, которая будет выполнять опции в точном порядке, указанном вызывающими командами.

В примере, если опции `red` или `зелёный` будут переданы в документ, шрифт, используемый для заголовка и разделов, будет установлен в соответствующий цвет. Цвет с названием `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/ru/shrifty/01-font-sizes-families-and-styles.md).
* Значение по умолчанию для [`textwidth`](/latex/ru/formatirovanie/07-page-size-and-margins.md)
* Значение по умолчанию для [`textheight`](/latex/ru/formatirovanie/07-page-size-and-margins.md)
* Параметры для [нумерации страниц](/latex/ru/formatirovanie/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{Команда Learn ShareLaTeX}
\date{August 2014}

\begin{document}

\maketitle

\noindent
Начнём с простого рабочего примера.

\blindtext

\section{Introduction}

Задача Монтy Холла...

\section{The same thing}

Монти...
```

![WrittingClassesEx1.png](/files/ad921dd18e74c7a653e385dbf6ceb92e32d828a4)

Обратите внимание, что первая команда здесь —

```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*}`. В этом случае информация во втором параметре будет выведена только в файл протокола, включая номер строки.

[Откройте пример того, как написать класс в 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/ru/komandy/01-commands.md#defining-a-new-command), первый параметр — это имя новой команды, второй — то, что будет делать команда.
* `\renewcommand{}{}`. То же самое, что и `\newcommand` но переопределяет существующую команду.
* `\providecommand{}{}`. Работает так же, как `\newcommand` но если команда уже определена, эта команда будет молча проигнорирована.
* `\CheckCommand{}{}`. Синтаксис такой же, как у `\newcommand`, но вместо этого он проверит, существует ли команда и имеет ли она ожидаемое определение; LaTeX покажет предупреждение, если команда не такая, как `\CheckCommand` ожидалось.
* `\setlength{}{}`. Устанавливает длину элемента, переданного в первом параметре, в значение, указанное во втором параметре.
* `\mbox{}`. Создаёт коробку, содержащую элементы, записанные внутри фигурных скобок.
* `\fbox{}`. То же самое, что и `\mbox`, но вокруг содержимого действительно печатается рамка.

## Дополнительное чтение

Для получения дополнительной информации см.

* [Понимание пакетов и файлов классов](/latex/ru/faily-klassov/01-understanding-packages-and-class-files.md)
* [Создание собственного пакета](/latex/ru/faily-klassov/03-writing-your-own-package.md)
* [Команды](/latex/ru/komandy/01-commands.md) и [Окружения](/latex/ru/komandy/02-environments.md)
* [Длины в LaTeX](/latex/ru/formatirovanie/01-lengths-in-latex.md)
* [Использование цветов в LaTeX](/latex/ru/formatirovanie/13-using-colors-in-latex.md)
* [Управление в большом проекте](/latex/ru/struktura-dokumenta/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/ru/faily-klassov/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.
