> 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/03-writing-your-own-package.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ε.
* ***Предварительные объявления***. Здесь подключаются необходимые внешние пакеты. Также в этой части файла кодируются команды и определения, необходимые для объявленных опций.
* ***Опции***. Пакет объявляет и обрабатывает опции.
* ***Дополнительные объявления***. Основная часть пакета. Почти всё, что делает пакет, определяется здесь.

В следующих подразделах будет представлено более подробное описание структуры и рабочий пример, *examplepackage.sty*, будут представлены.

### Идентификация

Существует две простые команды, которые должны быть у каждого пакета:

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/24 Пример пакета LaTeX]
```

Команда `\NeedsTeXFormat{LaTeX2e}` задаёт версию LaTeX, с которой должен работать пакет. Кроме того, в квадратных скобках можно указать дату, чтобы задать минимально требуемую дату выпуска.

Команда `\ProvidesPackage{examplepackage}[...]` идентифицирует этот пакет как *examplepackage* а внутри скобок указывается дата выпуска и некоторая дополнительная информация. Дата должна быть в формате YYYY/MM/DD

[Откройте пример написания пакета в Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

### Предварительные объявления

Большинство пакетов расширяют и настраивают существующие, а также для работы нуждаются в некоторых внешних пакетах. Ниже в примерный пакет "examplepackage.sty" добавлен ещё один фрагмент кода.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/21 Пример пакета]

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

Команды в этой части либо инициализируют некоторые параметры, которые позже будут использоваться для управления опциями, либо подключают внешние файлы.

Команда `\RequirePackage` очень похожа на хорошо известную `\usepackage`, добавление необязательных параметров в квадратных скобках тоже будет работать. Единственное отличие в том, что `\usepackage` не может использоваться перед `\documentclass` командой. Настоятельно рекомендуется использовать `\RequirePackage` при написании новых пакетов или классов.

[Откройте пример написания пакета в Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

### Опции

Чтобы обеспечить некоторую гибкость в пакетах, несколько дополнительных опций очень полезны. Следующая часть файла "examplepackage.sty" обрабатывает параметры, переданные оператору подключения пакета.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/21 Пример пакета]

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

Ниже приводится описание основных команд, которые могут обрабатывать опции, переданные пакету.

Команда `\DeclareOption{}{}` обрабатывает заданную опцию. Она принимает два параметра: первый — имя опции, а второй — код, который нужно выполнить, если опция была передана.

Команда `\OptionNotUsed` выведет сообщение в компиляторе и в журналах, опция использоваться не будет.

Команда `\Declareoption*{}` обрабатывает каждую опцию, не определённую явно. Она принимает только один параметр — код, который нужно выполнить, когда передаётся неизвестная опция. В этом случае она выведет предупреждение с помощью следующей команды:

`\PackageWarning{}{}`. См. [обработка ошибок](#handling-errors) чтобы узнать, что делает эта команда.

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

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

В примере, если опции *red* или *blue* передаются в `\usepackage` команду в документе, команда `\wordcolor` переопределяется. И цвета, и цвет по умолчанию — серый — были определены в [предварительных объявлениях](#preliminary-declaration) после подключения *xcolor* пакет.

[Откройте пример написания пакета в Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

### Дополнительные объявления

Именно в этой части появится большинство команд. В "examplepackage.sty" ниже можно увидеть полный файл пакета.

```latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{examplepackage}[2014/08/21 Пример пакета]

\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

%%Нумерованная среда
\newcounter{example}[section]
\newenvironment{example}[1][]{\refstepcounter{example}\par\medskip
\noindent \textbf{My~environment~\theexample. #1} \rmfamily}{\medskip}

%%Важные слова добавляются в предметный указатель и печатаются другим цветом
\newcommand{\important}[1]
{\IfSubStr{#1}{!}
    {\textcolor{\wordcolour}{\textbf{\StrBefore{#1}{!}~\StrBehind{#1}{!}}}\index{#1}}
    {\textcolor{\wordcolour}{\textbf{#1}}\index{#1}\kern-1pt}
}
```

Этот пакет определяет новую среду `example`, а также новую команду `\important`, которая печатает слова особым цветом и добавляет их в указатель.

Чтобы полностью понять каждую команду, см. [справочное руководство](#reference-guide) и ссылки в [разделе дополнительного чтения](#further-reading).

Ниже приведён документ, использующий пакет *examplepackage.sty*.

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

\usepackage[red]{examplepackage}

\makeindex

\title{Пример пакета}
\author{Команда Learn ShareLaTeX}
\date{ }

\begin{document}

\maketitle

\section{Introduction}
В этом документе тестируется новый пакет. Этот пакет позволяет создавать специальные нумерованные
окружения

\begin{example}
Этот текст находится внутри специальной среды, некоторая часть текста выделяется полужирным шрифтом
в начале, и задаётся новый отступ.
\end{example}

Кроме того, существует специальная команда для \important{важные!слова}, которая будет
напечатана особым \important{цветом} в зависимости от параметра, использованного в
\important{пакет} при подключении. Потому что это \important{важно}.

\printindex

\end{document}
```

![WrittingPackagesEx1.png](/files/4e00bd3f746a417a3b83348f9e742c0779b23610)

Обратите внимание на команду

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

[Откройте пример написания пакета в Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

## Обработка ошибок

Когда дело доходит до разработки новых пакетов, важно обрабатывать возможные ошибки, чтобы сообщить пользователю, что что-то пошло не так. Существует четыре основные команды для сообщения об ошибках в компиляторе.

* `\PackageError{*package-name*}{*error-text*}{*help-text*}`. Принимает три параметра, каждый в фигурных скобках: имя пакета, текст ошибки, который будет отображаться (процесс компиляции будет приостановлен), и текст помощи, который будет выведен, если пользователь нажмёт "h" при остановке компиляции из-за ошибки.
* `\PackageWarning{*package-name*}{*warning-text*}`. В этом случае текст будет показан, но процесс компиляции не остановится. Будет указана строка, в которой возникло предупреждение.
* `\PackageWarningNoLine{*package-name*}{*warning-text*}`. Работает так же, как предыдущая команда, но не показывает строку, в которой возникло предупреждение.
* `\PackageInfo{*package-name*}{*info-text*}`. В этом случае информация во втором параметре будет выведена только в файл протокола, включая номер строки.

[Откройте пример написания пакета в Overleaf](https://www.sharelatex.com/project/new/template?zipUrl=/project/53f11ec1eceb82a67658cb02/download/zip\&templateName=PackageExample\&compiler=pdflatex)

## справочнике

**Список команд, обычно используемых в пакетах и классах**

* `\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/04-writing-your-own-class.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/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.
