67

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

3 Answers 3

71

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

1
  • 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, 2012 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

6
  • I removed the second \noindent and used \ignorespaces instead. Jun 16, 2012 at 17:38
  • 2
    There's no need for \ExplSyntaxOn and \ExplSyntaxOff, but it's a matter of preference. Probably \textbf{Argument\IfValueT{#1}{~#1}:~} would be more efficient and, perhaps, also clearer.
    – egreg
    Jun 16, 2012 at 20:34
  • @egreg: ExplSyntaxOn is needed. Please see my sentence under the example. Otherwise I must work with % Jun 16, 2012 at 22:52
  • Yes, of course! You might expand the note, making clear that ~ should be used for denoting wanted spaces: the syntax is probably unfamiliar to Ali.
    – egreg
    Jun 16, 2012 at 22:57
  • @egreg: In this way? Jun 16, 2012 at 23:05
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}
5
  • For the case where the optional parameter is not provided this produces an extra space before the colon. Jun 16, 2012 at 18:11
  • @PeterGrill apparently \ifx doesn'yt include typo-correction:( \newenvrionment isn't the same as \newenvironment (fixed thanks:-) Jun 16, 2012 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, 2012 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:-) Jun 17, 2012 at 9:36
  • 1
    +1 what a dirty \ifx trick!
    – yo'
    Aug 20, 2012 at 6:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .