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.

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

share|improve this question

3 Answers 3

up vote 25 down vote accepted

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

share|improve this answer
    
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
    
Thanks lockstep, solved my issue. –  Ali Aug 4 '12 at 16:24

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

share|improve this answer
    
I removed the second \noindent and used \ignorespaces instead. –  Marco Daniel Jun 16 '12 at 17:38
    
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 '12 at 20:34
    
@egreg: ExplSyntaxOn is needed. Please see my sentence under the example. Otherwise I must work with % –  Marco Daniel Jun 16 '12 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 '12 at 22:57
    
@egreg: In this way? –  Marco Daniel Jun 16 '12 at 23:05

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}
share|improve this answer
    
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 9:36
    
OK. Thank you :-) –  Tobi Jun 17 '12 at 13:10

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.