16

I'm trying to create a command with an optional argument using

\newcommand{\Af}[1]{{\mathbf{A}_{(#1)}}

where the argument is a number.

However, I'd like that if no argument is given the bracket were dropped.

Question

How could I define a command which decides whether or not write the brackets?

22

Another solution using xparse.

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{ \Af }{ o }{%
    A\IfValueT{#1}{_{(#1)}}%
}
\NewDocumentCommand{ \Bf }{ d() }{%
    A\IfValueT{#1}{_{(#1)}}%
}

\begin{document}
no argument: $\Af$

with argument: $\Af[x]$

no argument: $\Bf$

with argument: $\Bf(x)$
\end{document}

result

xparse uses a different (an in my eyes easier and more flexible) syntax to define a command. The second argument of \NewDocumentCommand takes a list defining the arguments, e.g. o for an optional an m for a mandatory argument. With \If(No)Value(TF) you can test whether the argument has a value. (TF) can be T or F to test only one case or TF to differentiate between both the latter case has there arguments, e.g. {#1}{true code}{false code}. With d as argument specifier (see \Bf definition) you can even define the delimiting symbols, () in this case, so the code equals the output even more.

As daleif said you can add a \smash to the subscript to prevent it form affecting the line spacing.

\NewDocumentCommand{ \Afs }{ o }{%
    A\IfValueT{#1}{_{\smash{(#1)}}}%
}

without \smash (exaggerating example using \sum and \left…\right to get flexible parens).
without smash

with \smash
with smash

  • It might be an idea to add \smash to the ()'s because they have a tendency to affect line spacing when used in sub- and superscript. – daleif Aug 19 '13 at 14:18
  • There is also \IfValueT that's perhaps more intuitive than \IfNoValueF, in this case. – egreg Aug 19 '13 at 15:05
  • @egreg: O … that’s right :-). – Tobi Aug 19 '13 at 15:35
  • @daleif: I’ll add this. – Tobi Aug 19 '13 at 15:40
  • 1
    I would not add the left/right part, too much risk of them ending too large. I would only smash the () not the contents – daleif Aug 19 '13 at 17:35
16

Since you want an optional argument I think you should use the presence of the argument (rather than it being empty) as the test so

\makeatletter

\newcommand\Af{\@ifnextchar[\@Af\@@Af}

\def\@@Af{\mathbf{A}}
\def\@Af[#1]{\@@Af_{(#1)}}

\makeatother

...

\Af ... \Af[x] ...
13

I usually use etoolbox

Something like (note your example does not use an optional argument)

 \newcommand\Af[1][]{\mathbf{A}\ifblank{#1}{}{_{(#1))}}}

ought to do the trick (untested)

  • 4
    I recommend to add some usage examples as well. – Martin Scharrer Aug 19 '13 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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