2

The document that I am working with has a macro with 1 parameter:

\newcommand{\emailTo}[1]{The email address that #1 is sent to.}

I have to add another parameter with a default value of email address to remain backwards-compatible. I tried:

\newcommand{\emailTo}2][][email address]{The #2 that #1 is sent to.}

But I am getting this error:

You can't use `macro parameter character #' in horizontal mode. ...\emailToNew}[2][qeee][email address] {The #

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}

\newcommand{\emailTo}[1] {The email address that #1 is sent to.}

\newcommand{\emailToNew}[2][][email address] {The #2 that #1 is sent to.}

\begin{document}
    \emailTo{notification}
    
    \emailToNew{notification}%{email address}
\end{document}

Is there any way to stay backwards-compatible and not have to change hundreds of instances where the existing macro is used with 1 parameter?

......

1
  • 2
    there should be only one bracketed default, you are adding two. Nov 15 '20 at 16:49
1

I'm not sure this is what you're looking for:

\documentclass[10pt,a4paper]{article}

\NewDocumentCommand{\emailTo}{mO{email address}}{%
  The #2 that #1 is sent to.
}

\begin{document}

\emailTo{somebody}

\emailTo{somebody}[parcel]

\end{document}

enter image description here

The first argument is mandatory, the second argument is optional with default value email address.

1

Using old-style \newcommand, this might be an approach.

\documentclass[10pt,a4paper]{article}

\newcommand{\emailTo}[1]{\def\tmp{#1}\emailToAux}
\newcommand\emailToAux[1][email address]{%
  The #1 that \tmp{} is sent to.
}

\begin{document}

\emailTo{somebody}

\emailTo{somebody}[parcel]

\end{document}

enter image description here

1

So you wrote:

\newcommand{\emailTo}2][][email address]{The #2 that #1 is sent to.}

This is very close to what you want, but you managed to get your brackets out of place. You wanted to put the 2 inside the first set of brackets (there's also a random closing bracket hiding in there as well).

Except that with \newcommand, the optional argument must be the first argument and not the second, so what you actually wanted to write was:

\newcommand{\emailTo}[2][email address]{The #1 that #2 is sent to.}

and you would then write

\emailTo[postal address]{the notice}

All that said, \newcommand is at least a little deprecated and you should prefer to use \NewDocumentCommand in its place.¹ This gives greater flexibility for creating commands with optional arguments (among other things²). In that instance, you could write (your choice)

\NewDocumentCommand{\emailTo}{O{email address} m}{The #1 that #2 is sent to.}

for the optional argument before the required argument or

\NewDocumentCommand{\emailTo}{m O{email address}}{The #2 that #1 is sent to.}

for the optional argument at the end.


  1. I mention \newcommand et al. in a sidebar in my LaTeX book, but the primary discussion on creating new commands focuses solely on \NewDocumentCommand.

  2. Arguably, the simple \NewDocumentCommand{\myverb}{v}{\texttt{#1}} is actually superior to the native \verb command.³

  3. Because why? Because it allows writing \myverb{\something} if you don't have unbalanced braces in your argument and it gives a more understandable error message if you write, e.g., \section{\myverb+\foo+}, among other things.⁴

  4. Although \verb\foo\ does the predictable, albeit surprising thing while \myverb\foo\ gives an incorrect error message.⁵

  5. David Carlisle, something for you to dig into.⁶

  6. And I'm pretty sure this is the real reason why DEK decided not to allow footnotes inside footnotes (something which I've only seen enabled in Waterloo Script, an archaic text formatting system that ran on VM/CMS systems and what I used to get footnotes at the bottom of the page before I started using TeX).

1
  • 2
    I'm not David, but 4 is a bug. A v argument starts by looking for a begin-group character (thus looks at \foo and TeX freezes it as a control sequence), then proceeds checking if the next token is a character, which is not, then assumes that the input was already tokenized (which is somewhat true) and yells at the user thinking the command was wrongly used in an argument. Something should be rearranged there to avoid that... Jul 14 at 2:28

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.