Свои команды: newcommand

Урок учит создавать свои команды-сокращения, чтобы не повторяться и легко менять обозначения.

\newcommand — объявление собственного макроса: вы даёте имя последовательности команд, и дальше пишете короткое имя вместо длинной записи.

Принцип DRY (Don't Repeat Yourself) работает и в вёрстке. Если вы сто раз пишете одно и то же сложное обозначение, заведите для него команду — короче, единообразнее и меняется в одном месте.

Простой макрос

Объявление в преамбуле, использование в тексте:

\newcommand{\R}{\mathbb{R}}        % множество вещественных
\newcommand{\eps}{\varepsilon}     % красивый эпсилон
...
Функция $f \colon \R \to \R$ непрерывна для любого $\eps \gt 0$.

$$f \colon \mathbb{R} \to \mathbb{R}, \quad \varepsilon \gt 0$$

Теперь вместо \mathbb{R} вы пишете \R. Если завтра захотите другое обозначение множества, поменяете одну строку в преамбуле — и весь документ обновится.

Макрос с аргументами

В квадратных скобках указывают число аргументов; в теле они доступны как #1, #2:

\newcommand{\norm}[1]{\left\| #1 \right\|}
\newcommand{\dd}[2]{\frac{d #1}{d #2}}
...
$\norm{x}$ и производная $\dd{y}{x}$

$$\left\| x \right\| \qquad \frac{d y}{d x}$$

Команда \norm{v} теперь даёт норму вектора в растягиваемых двойных чертах, а \dd{y}{x} — производную. Это и читаемее в исходнике, и единообразнее в выводе.

Аргумент по умолчанию

Первый аргумент можно сделать необязательным, задав значение по умолчанию вторым параметром в скобках:

\newcommand{\vect}[2][n]{(#2_1, \dots, #2_{#1})}
...
$\vect{x}$ даёт (x_1, ..., x_n), а $\vect[m]{y}$ — до m

Зачем это в формулах

Особенно полезны макросы для повторяющихся математических конструкций. Если в статье сто раз встречается оператор математического ожидания, вы заводите \newcommand{\E}{\operatorname{\mathbb{E}}} и пишете \E[X]. Бонус: если рецензент попросит сменить обозначение, правка делается в одном месте, а не поиском-заменой по всему тексту (что рискованно).

Как работает под капотом

\newcommand регистрирует в памяти движка новый управляющий токен и его «тело» — последовательность команд, в которую он разворачивается при встрече. Аргументы #1, #2 — это позиционные подстановки: при вызове \dd{y}{x} движок текстуально подставляет y на место #1 и x на место #2, а затем набирает результат. \newcommand намеренно отказывается переопределять существующую команду (выдаёт ошибку) — это защита от случайной поломки встроенных команд; для осознанного переопределения есть \renewcommand.

Три родственные команды

Вокруг \newcommand есть целое семейство, и разница между ними касается одного вопроса — что делать, если имя уже занято. \newcommand объявляет команду и падает с ошибкой, если такая уже существует, — это страховка. \renewcommand, наоборот, требует, чтобы команда уже была, и переопределяет её — так меняют поведение встроенных команд, например \renewcommand{\baselinestretch}{1.5} для полуторного интервала. А \providecommand объявляет команду только если её ещё нет, иначе тихо ничего не делает — это удобно в общих файлах преамбул и в пакетах, чтобы не конфликтовать с тем, что мог объявить пользователь. Понимание этой тройки спасает от самой частой загадки новичка — почему «команда уже определена» или, наоборот, «команда не определена».

Устойчивые команды и продвинутые аргументы

Команды, созданные через \newcommand, по умолчанию «хрупкие» (fragile): они могут ломаться, попав в так называемые подвижные аргументы — заголовки разделов, подписи к рисункам, оглавление, колонтитулы. Для таких случаев есть \DeclareRobustCommand — он объявляет «устойчивую» (robust) версию, которая переживёт запись в оглавление и обратное чтение. Когда же макросу нужны хитрые аргументы — несколько необязательных, звёздочка-вариант, разделители — на смену приходит современный пакет xparse с командой \NewDocumentCommand. Её мини-язык спецификаторов (m — обязательный, o — необязательный, s — звёздочка) описывает гораздо более гибкий интерфейс, чем единственный необязательный аргумент классического \newcommand.

Зачем это на практике

Главная ценность макросов проявляется не в экономии нажатий, а в единообразии и управляемости большого документа. Заведя \newcommand{\dataset}{\textsc{CodeChick-2026}} для названия набора данных, вы гарантируете, что оно везде написано одинаково, а если редактор журнала попросит сменить название, правка делается в одной строке преамбулы — никакого рискованного поиска-замены по всему тексту, который случайно заденет похожие слова. Точно так же макрос для обозначения, термина или единицы измерения становится «единым источником истины»: при доработке статьи по замечаниям рецензента (rebuttal) вы спокойно меняете обозначение во всём документе, не боясь пропустить вхождение. Именно поэтому опытные авторы заводят небольшой личный файл макросов и подключают его во все свои работы.

Частые ошибки

  • Переопределить существующую команду через \newcommand — ошибка «already defined». Нужен \renewcommand.
  • Слишком «умные» макросы усложняют чтение чужого исходника — заводите их с умом.
  • Забыть {} вокруг тела с несколькими токенами — развернётся не так.

Итоги

  • \newcommand{\имя}{тело} заводит сокращение; меняется в одном месте.
  • [N] задаёт число аргументов, доступных как #1...#N; первый можно сделать необязательным.
  • Для переопределения существующей команды — \renewcommand.
Проверьте себя
1. Что делает \newcommand{\R}{\mathbb{R}}?
AПечатает букву R
BЗаводит сокращение \R, разворачивающееся в \mathbb{R}
CПереопределяет встроенную команду
DСоздаёт новый раздел
2. Как обратиться к первому аргументу внутри тела макроса?
A$1
B#1
C\arg1
D@1
3. Что делать, если нужно переопределить уже существующую команду?
AИспользовать \newcommand повторно
BИспользовать \renewcommand
CЭто невозможно
DУдалить пакет