6

Let us say I want to define a command for typesetting (a+b)^2:

\newcommand{\sumsquare}[2]{\ensuremath{(#1+#2)^2}}

How can I modify it so that \sumsquare{a}{0} will produce a^2?

11

I would suggest you change the syntax to \sumsquare{a}{}:

This can be coded either this way:

\newcommand{\sumsquare}[2]{%
   \ifx\\#2\\%
     \ensuremath{#1^2}}%
   \else
     \ensuremath{(#1+#2)^2}}%
   \fi
}

or:

\newcommand{\sumsquare}[2]{%
   \begingroup
   \def\tempvar{#2}%
   \ifx\tempvar\empty
     \endgroup
     \ensuremath{#1^2}}%
   \else
     \endgroup
     \ensuremath{(#1+#2)^2}}%
   \fi
}

If your really want 0 as the no-operant indicator you can define it like this:

\newcommand{\sumsquare}[2]{%
   \begingroup
   \def\tempvara{#2}%
   \def\tempvarb{0}%
   \ifx\tempvara\tempvarb
     \endgroup
     \ensuremath{#1^2}}%
   \else
     \endgroup
     \ensuremath{(#1+#2)^2}}%
   \fi
}

(I named the temporary variables this way to avoid \makeatletter. Normally \@tempa and \@tempb are used.)

Explanation:

The \ifx command compares the next to tokens (e.g. macros, characters, ...) if the hold the same definition. In the last example the 0 and the #2 are both defined to a macro each, which are then compared. This requires assignments and is therefore not expandable, i.e. doesn't work inside an \edef.

In the first code \ifx\\#2\\ is used to test if #2 is empty. If #2 contains something, \ifx compares the first token in it with \\, which does not match as long #2 doesn't start with \\. All other tokens are then simply taken as part of the true part and simply discarded with it. If \\ is a valid value for #2 simply use some other macro like \relax or \@nnil instead.

However, if #2 is empty the expression is reduced to \ifx\\\\, i.e. \ifx compares two \\, which are of course defined identical.

  • Thanks! I'll stick with the third solution, I find its usage more natural in my document. – Anthony Labarre Feb 11 '11 at 9:05
  • @Anthony: Sure. I just thought I'm a little more general and explain the available options. This way it is also useful for other people which have the same or a similar problem. – Martin Scharrer Feb 11 '11 at 9:38
6

A solution using xparse

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\sumsquare{mg}{%
  \IfNoValueTF{#2}
    {\ensuremath{#1^2}}
    {\ensuremath{(#1+#2)^2}}
}
  • 2
    As I was reading this question I thought "aha, I'm sure an xparse solution would be elegant and simple." Then I thought "Ah, but I bet that pesky Joseph Wright will have beaten me to it..." And I was right. – Seamus Feb 10 '11 at 22:05
2

It can also be done with an optional second argument, but it is not really shorter than typing it

\documentclass{article}
\newcommand{\sumsquare}[2]{\ensuremath{\ifx\relax#2\relax#1\else(#1+#2)\fi^2}}
\begin{document}

\sumsquare{a}{b} \sumsquare{a}{}

\end{document} 
  • 1
    Won't this produce (a)^2 rather than a^2? – Anthony Labarre Feb 10 '11 at 20:43
  • ah yes. I edited the code – user2478 Feb 10 '11 at 21:00

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.