\newcommand / \newenvironment - optional parameters

  1. You can't create a \foo{parameter}[optional] command simply; you can, however, create a \foo[optional]{parameter} command with

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

    If you call it as \foo{given}, it will produce Mandatory: given, optional: default; if you call it as \foo[bonus]{given}, it will produce Mandatory: given, optional: bonus. This is probably how you should do it—that will look better with the rest of your LaTeX code. Creating a new environment with optional parameters is done similarly with

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

    where #1 is again the optional argument; this is again written as \begin{env}[opt]{req}...\end{env}. If you really want a command in the other form, see the end of my answer.

  2. The TeX FAQ has an answer about writing commands with more than one optional argument. There are two options to how to do it. The underlying idea is to define a command which takes an optional argument, and then runs another command which itself takes an optional argument, etc.; the twoopt package encapsulates this.


If you really want a command like \reversed{mandatory}[optional], you can do it like so. First, you define a command which takes a required argument, stores it in a macro, and then forward it onto another command. This second command takes an optional argument, and uses the defined command and the optional argument. Putting this all together, we get

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

You can then use \reversed{mandatory}[optional] or just \reversed{mandatory}, and everything should work.


Using the xparse package (part of the LaTeX3 development efforts):

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

Optional arguments are a bit different in xparse to with \newcommand. You can detect whether one is given or not:

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

You'll see that this works by using a lower case 'o', whereas the upper case 'O' then requires a default value (which I've made empty by including an empty group).


Consider also the xargs package. The following is an example from its documentation.

Set it up in the usual way,

\usepackage{xargs}

and then if you define

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

(which means to use "1" for the first argument, if it is not specified, and to use "n" for the third). Then

$\coord{x}$

yields (sans subscripts)

(x1, . . . , xn)

and

$\coord[0]{y}$

yields (again, sans subscripts, and y replaces the mandatory parameter)

(y0, ..., yn)