15

Is it possible to define new commands having the following form:

\command{<marg>}[<oarg>]

I have seen commands of this form in the fontspec package. But not sure how to achieve this.

3
  • 1
    Yes you can, but it is generally not well advised.
    – A.Ellett
    Aug 10 '14 at 17:33
  • 2
    fontspec uses a trailing optional argument for commands that should go in the preamble; in general, a trailing optional argument after mandatory ones is not really recommended.
    – egreg
    Aug 10 '14 at 17:57
  • 5
    Does this answer your question? How to specify an optional final argument with \newcommand?
    – user202729
    Dec 17 '21 at 6:03
16

There are several approaches you can take.

The easiest approach is to use xparse

Then you can define a command as

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\mycommand}{ mO{a} }{#2 \rightarrow #1}
\pagestyle{empty}
\begin{document}

$\mycommand{A}$ vs $\mycommand{A}[b]$

\end{document}

Alternatively you can use \def and \@ifnextchar[ to create your own command with trailing optional argument. But this will be rife with problems. For example, any [ following such a macro, regardless of intervening white space, will be picked up. xparse very nicely avoids this by not allowing white space between the last mandatory argument and a trailing optional argument.

I would recommend the xparse approach. However, for the sake of completeness, I will show you at least one way to do this via \def and \@ifnextchar.

\documentclass{article}
\makeatletter

\newcommand\mycommand{\my@command}
\def\my@command#1{%%
  \@ifnextchar[%]
  {\@my@command{#1}}{\@my@command{#1}[a]}}
\def\@my@command#1[#2]{#2 \rightarrow #1}

\makeatother

\begin{document}

$\mycommand{A}$ vs $\mycommand{A}[b]$

\end{document}
5
  • The package ltxcmds provides \ltx@ifnextchar@nospace
    – cgnieder
    Aug 10 '14 at 18:01
  • why \def\my@command#1 and not \newcommand*\my@command[1] ?
    – cgnieder
    Aug 10 '14 at 18:08
  • @cgnieder no particular reason. It seems that there are any number of ways to go about this. I'm not sure if there's is a preferred or recommended approach.
    – A.Ellett
    Aug 10 '14 at 18:11
  • 1
    Since this is LaTeX personally I'd use \newcommand instead of \def. I'd also add \newcommand\@my@command{} before \def\@my@command#1[#2] (this way no macros are accidentally redefined).
    – cgnieder
    Aug 10 '14 at 18:15
  • Thanks, both of the solutions work fine. But I think I won't use the second one until some appropriate digging into The Companion. :-)
    – Naitree
    Aug 11 '14 at 3:06
7

I've used a package by the name of xargs (non-disclaimer: just a satisfied user) that seems like a perfect fit here - in particular, the command \newcommandx:

\newcommandx{\command}[argcount][arg, arg=default]{#1(#2)}

\newcommandx works just like \newcommand, except that the second optional argument is not the default value for the command's first argument (making it optional); instead, it is a comma-separated list of (numbered) arguments that are to be optional. A default value for an argument can be specified by following a number with = and the desired default; if not given, the default is blank. Here's an MWE:

\documentclass{article}
\pagestyle{empty}

\usepackage{xargs}
\newcommandx{\mycommand}[2][2=a]{#2 \rightarrow #1}

\begin{document}

$\mycommand{A}$ vs $\mycommand{A}[b]$

\end{document}

Here's a command I've actually used, for typesetting derivatives in Leibniz notation:

\newcommandx{\dd}[4][1, 2=\mathrm{d}, 4]{\ensuremath{\frac{#2^{#4}#1}{#2#3^{#4}}}}
  • \dd x

    d/dx

  • \dd[y]x

    dy/dx

  • \dd[][\partial]x

    ∂/∂x

  • \dd x[2]

    d²/dx²

  • \dd[y][\Delta]{x}[2]

    Δ²y/Δx²

1
  • Thanks, I'll put it in my reading list of package docs. And good implementation!
    – Naitree
    Aug 12 '14 at 1:31

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