6

I want to define a \newcommand with two argument, of which one is optional, which allow me to have the same output of the first input in the case I do not specify the second argument, while being the second argument if specified. Let make an example:

\newcommand{\paren}[1]{\left(#1\right)} %this is just an example command

$A = a\paren{a}$

enter image description here

I want to obtain the same by doing something like (this won't work)

\newcommand{\mypar}[2][#1]{#2\paren{#1}}
$A = \mypar{a} = \mypar[a]{a} \neq \mypab[b]{a}$

enter image description here

I thought that inserting #1 as default argument when the second argument was not specified would have done the job, but it didn't.

3 Answers 3

7

The latex format has a standard command for doubling an optional argument in this way (as used for \section[zz]{zz})

\documentclass{article}


\newcommand{\xmypar}[2][]{#2\left(#1\right)} %this is just an example command

\makeatletter
\newcommand\mypar{\@dblarg\xmypar}
\makeatother

\begin{document}

$\mypar{a}$

$\mypar[b]{a}$

\end{document}
2
  • How does the \@dblarg acts? What is it doing?
    – GiuTeX
    Nov 8, 2017 at 20:28
  • 1
    @opisthofulax it just does what you ask and nothing more, it takes a command as argument (\xmypar here) then checks if there is a [ and calls \xpypar if there is and \xmypar[#1]{#1} if there is not. Nov 8, 2017 at 20:33
7

The standard \newcommand doesn't support it. The kernel provides \@dblarg:

\makeatletter
\newcommand{\mypar}{\@dblarg\@mypar}
\def\@mypar[#1]#2{#2\paren{#1}}
\makeatletter

However, you can do it more robustly and easily with xparse:

\usepackage{xparse}

\NewDocumentCommand{\mypar}{O{#2}m}{#2\paren{#1}}

Full example:

\documentclass{article}
\usepackage{xparse}

\newcommand{\paren}[1]{\left(#1\right)} %this is just an example command

\NewDocumentCommand{\mypar}{O{#2}m}{#2\paren{#1}}

\begin{document}

$\mypar{a}$

$\mypar[b]{a}$

\end{document}

Not that I endorse that definition of \paren, of course. ;-)

enter image description here

3
  • How does the \@dblarg acts? What is it doing?
    – GiuTeX
    Nov 8, 2017 at 20:28
  • interesting edit, whatever gave you the idea:-) Nov 8, 2017 at 20:47
  • @DavidCarlisle Added before seeing your post
    – egreg
    Nov 8, 2017 at 21:21
5

You can check for an empty argument in #1 and use it to condition on displaying either #1 or #2:

enter image description here

\documentclass{article}

\usepackage{mleftright}

\newcommand{\paren}[1]{\mleft(#1\mright)} %this is just an example command
\newcommand{\mypar}[2][]{%
  \if\relax\detokenize{#1}\relax #2\else #1\fi\paren{#2}}

\begin{document}

$A = \mypar{a} = \mypar[a]{a} \neq \mypar[b]{a}$

\end{document}

The following definition is a little simpler, but also works:

\newcommand{\mypar}[2][\relax]{%
  \ifx\relax#1\relax #2\else #1\fi\paren{#2}}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .