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.

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.

share|improve this question
1  
Yes you can, but it is generally not well advised. –  A.Ellett Aug 10 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 at 17:57

2 Answers 2

up vote 13 down vote accepted

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}
share|improve this answer
    
The package ltxcmds provides \ltx@ifnextchar@nospace –  cgnieder Aug 10 at 18:01
    
why \def\my@command#1 and not \newcommand*\my@command[1] ? –  cgnieder Aug 10 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 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 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 at 3:06

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²

share|improve this answer
    
Thanks, I'll put it in my reading list of package docs. And good implementation! –  Naitree Aug 12 at 1:31

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.