Подтвердить что ты не робот

\newcommand/\newenvironment - необязательные параметры

Я экспериментирую с собственными командами и средами, и теперь я сталкиваюсь с такими проблемами:

  • Как создать команду \foo{parameter}[optional] или среду под названием \begin{bar}{parameter}[optional]?
  • Как создать команду \foo[optional_1]...[optional_n]{parameter}

Я пробовал

\newcommand{\foo}[3][][]{#1#2#3}    - failed
\newcommand{\foo}[3][2][][]{#1#2#3} - failed

Кто-нибудь знает какой-то намек? Большое спасибо.

4b9b3361

Ответ 1

Использование пакета xparse (часть усилий по разработке LaTeX3):

\usepackage{xparse}
\NewDocumentCommand\foo{O{}O{}m}{%
  % Code with optional #1 and #2 with empty defaults
}
\NewDocumentCommand\foo{mO{}}{%
  % Code with optional #2 with empty default
}
\NewDocumentEnvironment{foo}{O{}}{%
% Start code with optional #1
}{%
%  End code with optional #1
}

Дополнительные аргументы немного отличаются в xparse с \newcommand. Вы можете определить, предоставлен ли он или нет:

\NewDocumentCommand\foo{mo}{%
  \IfNoValueTF{#2}
   {Code without #2}
   {Code with #2}%
}

Вы увидите, что это работает, используя нижний регистр "o", тогда как в верхнем регистре "O" требуется значение по умолчанию (которое я сделал пустым, включив пустую группу).

Ответ 2

  • Вы не можете просто создать команду \foo{parameter}[optional]; однако вы можете создать команду \foo[optional]{parameter} с помощью

    \newcommand{\foo}[2][def]{Mandatory: #2; optional: #1}
    

    Если вы назовете его \foo{given}, он произведет Mandatory: given, optional: def; если вы назовете его \foo[optional]{given}, он произведет Mandatory: given, optional: optional. Вероятно, вы должны это сделать, что будет выглядеть лучше с остальной частью вашего кода LaTeX. Создание новой среды с дополнительными параметрами выполняется аналогично

    \newenvironment{env}[2][def]{(#1,#2)\begingroup}{\endgroup}
    

    где # снова необязательный аргумент; это снова записывается как \begin{env}[opt]{req}...\end{env}. Если вам действительно нужна команда в другой форме, см. Конец моего ответа.

  • В TeX FAQ есть ответ о написании команд с более одного необязательного аргумента. Есть два варианта, как это сделать. Основная идея состоит в том, чтобы определить команду, которая принимает необязательный аргумент, а затем запускает другую команду, которая сама принимает необязательный аргумент и т.д.; пакет twoopt инкапсулирует это.


Если вам действительно нужна команда типа \reversed{mandatory}[optional], вы можете сделать это так. Сначала вы определяете команду, которая принимает требуемый аргумент, сохраняет его в макросе и затем перенаправляет на другую команду. Эта вторая команда принимает необязательный аргумент и использует определенную команду и необязательный аргумент. Объединяя все это, получим

\makeatletter
\newcommand{\reversed}[1]{\def\[email protected]{#1}\[email protected]}
\newcommand{\[email protected]}[1][def]{Required: \[email protected]; optional: #1}
\makeatother

Затем вы можете использовать \reversed{mandatory}[optional] или просто \reversed{mandatory}, и все должно работать.

Ответ 3

Рассмотрим также пакет xargs. Ниже приведен пример из документации.

Установите его обычным способом,

\usepackage{xargs}

а затем, если вы определяете

\newcommandx*\coord[3][1=1, 3=n]{(#2_{#1},\ldots,#2_{#3})}

(что означает использование "1" для первого аргумента, если оно не указано, и использовать "n" для третьего). Тогда

$\coord{x}$

yields (sans subscript)

(x1,..., xn)

и

$\coord[0]{y}$

дает (опять же, без индексов)

(x0,..., xn)