\ newcommand / \ newenvironment - необязательные параметры - PullRequest
16 голосов
/ 26 мая 2010

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

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

Я пробовал

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

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

Ответы [ 3 ]

16 голосов
/ 26 мая 2010
  1. Вы не можете просто создать команду \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}. Если вы действительно хотите команду в другой форме, см. Конец моего ответа.

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


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

\makeatletter
\newcommand{\reversed}[1]{\def\reversed@required{#1}\reversed@opt}
\newcommand{\reversed@opt}[1][def]{Required: \reversed@required; optional: #1}
\makeatother

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

13 голосов
/ 27 мая 2010

Использование пакета 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 от with \ newcommand. Вы можете определить, дается он или нет:

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

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

5 голосов
/ 21 июля 2010

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

Настройте его обычным способом,

\usepackage{xargs}

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

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

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

$\coord{x}$

выходов (без подписки)

(x1, ..., xn)

и

$\coord[0]{y}$

возвращает (опять же, без индексов, а у заменяет обязательный параметр)

(y0, ..., yn)

...