68

I want to create a new environment with one optional argument in LaTeX. Here is what I used:

\newenvironment{argument}[1][]{%
\par
\noindent
\textbf{Argument#1:}
\noindent}
{}

When there is no argument, it typesets the ':' right after the word 'Argument', which is how it should be.

However, when the optional argument is used, LaTeX doesn't add a space between the word 'Argument' and the optional argument provided.

In other words, what I want to achieve is that if the optional argument is provided (e.g. A), then LaTeX should add a space after the word 'Argument', like:

Argument A: some text

and when there is no optional argument, it should be like (without the space):

Argument: some text

lockstep
  • 250,273
Ali
  • 1,331

3 Answers3

72

Add a space before #1 in the environment's definition, and specify \unskip (which will remove the space) as the optional argument's default value.

\documentclass{article}

\newenvironment{argument}[1][\unskip]{%
\par
\noindent
\textbf{Argument #1:}
\noindent}
{}

\begin{document}

\begin{argument}
Some text.
\end{argument}

\begin{argument}[A]
Some text.
\end{argument}

\end{document}

enter image description here

lockstep
  • 250,273
  • Nice :-) I always used an if clause but this is shorter. It doesn’t work with {argument}[] right? This can cause problems when I need to optional arguments like in \cite[cf.][]{key} – Tobi Jun 16 '12 at 23:09
16

The definition of a new environment can be done by the basic LaTeX command \newenvironment. But I'd like to recommend the package xparse which provides also commands and utilities to define new environments; for instance, it provides a simple test to check if the optional argument is empty or not.

\documentclass{scrreprt}
\usepackage{xparse}
\ExplSyntaxOn
    \NewDocumentEnvironment{argument} { o }
     {
      \par\noindent
      \IfNoValueTF{#1} { \textbf{Argument:~} }{ \textbf{Argument~#1:~} }
       \ignorespaces
     }
     {}
\ExplSyntaxOff

\begin{document}
\begin{argument}
some text
\end{argument}
\begin{argument}[A]
some text
\end{argument}
\end{document}

The commands ExplSyntaxOn & ExplSyntaxOff are used to ignore some unwanted spaces inside the definition.


The command ExplSyntaxOn is the activation of the expl3 syntax. You can compare it with makeatletter for the @-symbol. Besides some other definitions, ExplSyntaxOn will ignore every space. So Hello World would print "HelloWorld". To get a space you must use a tilde ~. In this way Hello~World prints "Hello World". This is the reason why I wrote \textbf{Argument~#1:~}.

As egreg pointed out you can also use:

\ExplSyntaxOn
    \NewDocumentEnvironment{argument} { o }
     {
      \par\noindent
       \textbf{Argument \IfValueT { #1 } { ~ #1 } : ~ }
       \ignorespaces
     }
     {}
\ExplSyntaxOff

enter image description here

egreg
  • 1,121,712
Marco Daniel
  • 95,681
7

I would just put in the space if the optional argument is empty (or not used). Also I removed the second \noindent since it can do nothing useful in that position, as the paragraph has already started.

\documentclass{article}

\newenvironment{argument}[1][]{%
\par
\noindent
\textbf{Argument\ifx\newenvironment#1\newenvironment\else\space\fi#1:} }
{}

\begin{document}

\begin{argument}
Some text.
\end{argument}

\begin{argument}[A]
Some text.
\end{argument}

\end{document}
egreg
  • 1,121,712
David Carlisle
  • 757,742
  • For the case where the optional parameter is not provided this produces an extra space before the colon. – Peter Grill Jun 16 '12 at 18:11
  • @PeterGrill apparently \ifx doesn'yt include typo-correction:( \newenvrionment isn't the same as \newenvironment (fixed thanks:-) – David Carlisle Jun 16 '12 at 20:06
  • Is there a special reason to use \newenvironment in \ifx or is it just a dummy and could it be \tableofcontentsto? – Tobi Jun 16 '12 at 23:12
  • 1
    @Tobi no any command will do, but it needs to be a command that will never be the first token of the optional argument. But you do need to spell it the same way both times:-) – David Carlisle Jun 17 '12 at 09:36
  • 1
    +1 what a dirty \ifx trick! – yo' Aug 20 '12 at 06:54