Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In an environment, say

\newenvironment{whatever}[3]{...}{...}

you instantiante it (if that's the word for it in LaTeX) by

\begin{whatever}{first}{second}{third}
   ...
\end{whatever}

But how do you define an environment such that you instantiate it by

\begin{whatever}[some_optional]{first}{second}{third}
   ...
\end{whatever}

I'm not talking about default values for the parameters first, second or third, but an entirely optional parameter, such as in

\begin{figure}[htb]
    ...         ^--- THIS!
\end{figure}
share|improve this question
add comment

2 Answers

up vote 17 down vote accepted
\newenvironment{whatever}[4][]
  {...}
  {...}

\begin{whatever}{one}{two}{three}

is #1= {}
   #2= one
   #3= two
   #4= three

\begin{whatever}[zero]{one}{two}{three}

is #1= zero
   #2= one
   #3= two
   #4= three

\newenvironment{whatever}[4][foo]
  {...}
  {...}

\begin{whatever}{one}{two}{three}

is #1= foo
   #2= one
   #3= two
   #4= three

\begin{whatever}[bar]{one}{two}{three}

is #1= bar
   #2= one
   #3= two
   #4= three
share|improve this answer
    
I dont understand the 4th case \newenvironment{whatever}[4][foo] –  Nicholas Hamilton May 16 '13 at 4:13
    
[4][foo] defines 4 parameter in which the first one #1 is optional and replaced by foo if it is not set by the user otherwise with the user value –  Herbert May 16 '13 at 4:35
    
Got it. Thanks. –  Nicholas Hamilton May 16 '13 at 4:45
    
In the first example is #1= {} implies that an empty optional argument is replaced by an empty brace group when it actually really is empty. One would need to input \begin{whatever}[{{}}]]{...}... to actually get the empty brace group. –  cgnieder May 16 '13 at 9:53
add comment

The xparse package provides an easy user interface to specify optional arguments to environments (in various orders) including commands/macros. For this you define your environment using \NewDocumentEnvironment, while regular macros use \NewDocumentCommand. The former has the following syntax:

\NewDocumentEnvironment{<env>}{<arg spec>}{<beg env>}{<end env>}

<env>, <beg env> and <end env> act in the traditional way to define the environment <env> that executes code <beg env> when using \begin{<env>} (or \<env>) and executes <end env> when using \end{<env>} (or \end<env>). <arg spec> contains a sequence of argument specifications to the environment that can intermix optional and mandatory arguments as needed. In short, this is how they are specified (omitting some options; for more details, read the xparse package documentation):

  • m - a mandatory argument (requires { })
  • o - an optional argument (uses [ ])
  • O{<default>} - an optional argument similar to o but returns <default> if the argument is not given (uses [ ])
  • d<token1><token2> - an optional argument with special delimiters (uses <token1> <token2>)
  • D<token1><token2>{<default>} - an optional argument similar to d but returns <default> if the argument is not given (uses <token1> <token2>)

Here are some examples:

\documentclass{article}
\usepackage{xparse}% http://ctan.org/pkg/xparse
\begin{document}
\NewDocumentEnvironment{whatever}{m o O{foobar} m}{}{}
\NewDocumentEnvironment{whomever}{O{yes} D(){no}}{}{}

% #1=foo; #2=\NoValue; #3=foobar; #4=bar
\begin{whatever}{foo}{bar} foo \end{whatever}

% #1=foo; #2=bar; #3=foobar; #4=bar
\begin{whatever}{foo}[bar]{bar} foo \end{whatever}

% #1=yes; #2=no
\begin{whomever} foo \end{whomever}

% #1=no; #2=yes
\begin{whomever}[no](yes) foo \end{whomever}

\end{document}

As is obvious, this interface extends the existing "single optional argument" specification to a much wider range.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.