\newcommand: Using one parameter as the default for the other
Good news: you can do it very easily with xparse
:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\foo}{O{#2}m}{%
Optional=``#1'', mandatory=``#2''\par
}
\NewDocumentCommand{\oof}{mO{#1}}{%
Mandatory=``#1'', optional=``#2''\par
}
\begin{document}
\foo{x}
\foo[y]{x}
\oof{x}
\oof{x}[y]
\end{document}
The argument specifier O{...}
takes as argument what to substitute as default when the argument itself doesn't appear at call time. This can well be a parameter token referring to another argument.
You can use xparse
to easily condition on whether or not an optional argument was present or not, and supply the appropriate combination to another (auxiliary) function. Here's an example:
\documentclass{article}
\usepackage{xparse}
\newcommand{\printthis}[2]{%
Optional: #1; Mandatory: #2%
}
\NewDocumentCommand{\mycommand}{o m}{%
\IfValueTF{#1}
{\printthis{#1}{#2}}% \mycommand[..]{...}
{\printthis{#2}{#2}}% \mycommand{...}
}
\begin{document}
\mycommand{first}
\mycommand[first]{second}
\end{document}
A slightly different version of this stems from the use of \caption
, where you can supply an optional argument for the LoT/LoF, but if you don't, the mandatory arguments is sent instead (similarly for sectional units with optional arguments destined for the ToC). This uses the kernel's \@dblarg
:
\documentclass{article}
\newcommand{\printthis}[2][]{%
Optional: #1; Mandatory: #2%
}
\makeatletter
\newcommand{\mycommand}{%
\@dblarg\printthis
}
\makeatother
\begin{document}
\mycommand{first}
\mycommand[first]{second}
\end{document}
This is an attempt to add protection as with other macros that process optional arguments:
%%\errorcontextlines=1000
\documentclass[a4paper]{article}
\makeatletter
\newcommand\makefirstmandatorytheoptional[1]{%
\expandafter\innermakefirstmandatorytheoptional
\expandafter{\csname\string#1\endcsname}{#1}%
}%
\newcommand\innermakefirstmandatorytheoptional[2]{%
\def#2{%
\ifx\protect\@typeset@protect
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\kernel@ifnextchar[{#1}{\@dblarg{#1}}}%
{\protect#2}%
}%
}%
\newcommand\mycommand[2][dummyoptional]{%
This is taken for the optional argument: #1.\\
This is taken for the mandatory argument: #2.
}%
\makefirstmandatorytheoptional{\mycommand}%
\makeatother
\parindent=0ex
\parskip=\medskipamount
\begin{document}
No optional argument given---\verb|\mycommand{A}|:
\mycommand{A}
Optional argument "B" given---\verb|\mycommand[B]{A}|:
\mycommand[B]{A}
\end{document}