How can you define a macro \cmd in TeX primitives using two optional arguments (and a mandatory one) that fulfills the property that calling \cmd[opt]{mand} is equivalent to \cmd[][opt]{mand}. Yet, I only managed to create this macro with beeing \cmd[opt]{mand} an equivalent call to \cmd[opt][]{mand}. I don't really get which kind of questions I have to propose to TeX in order to achieve what I have in mind. Do you have any suggestions?
- 13,448
4 Answers
Here's a way, although it's not clear what you really would like to achieve.
\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}
\def\cmd{\futurelet\next\cmdi}
\def\cmdi{%
\ifx\next[%
\expandafter\firstoftwo
\else
\expandafter\secondoftwo
\fi
{\cmdopt}%
{\cmdx[][]}%
}
\def\cmdopt[#1]{\def\firstopt{#1}%
\futurelet\next\cmdoptii}
\def\cmdoptii{%
\ifx\next[%
\expandafter\firstoftwo
\else
\expandafter\secondoftwo
\fi
{\expandafter\cmdx\expandafter[\firstopt]}%
{\expandafter\cmdx\expandafter[\expandafter]\expandafter[\firstopt]}%
}
\def\cmdx[#1][#2]#3{%
\par\noindent{\tt\string\cmd} called with:\par
first optional argument=#1;\par
second optional argument=#2;\par
mandatory argument=#3\par}
\cmd{abc}
\cmd[opt1]{abc}
\cmd[opt1][opt2]{abc}
\bye

- 1,121,712
-
I think, he wants the second of two in
\cmdoptiito be{\expandafter\cmdx\expandafter[\expandafter]\expandafter[\firstopt]}%. – Qrrbrbirlbel Apr 24 '13 at 23:17 -
Here is a way to do what I think you desire with
the xparse package:

Notes:
- In actual usage you need to replace the
\{and\}with a{and}. I used the escaped versions in order to generate the output.
Code:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\MyCommand}{o o m}{%
\IfNoValueTF{#1}{%
Command{#3}% No optional parameters specified
}{%
% Optional parameters specified.
% Now need to check if #2 was provided.
\IfNoValueTF{#2}{%
Command[ ][#1]{#3}% #2 NOT provided
}{%
Command[#1][#2]{#3}% Both #1 and #2 provided.
}%
}%
}
\begin{document}
\MyCommand{no optional paramters}
\MyCommand[optional param1]{one optional paramater}
\MyCommand[optional param1][optional param2]{two optional paramaters}
\end{document}
- 223,288
Alright, we’ve got the asked plain-tex answer from egreg, we’ve got two rather confusing LaTeX3/xparse answers from Peter Grill and Werner; I’ll throw my LaTeX2 solution in the hat, too.
It uses \kernel@ifnextchar.
Code
\documentclass{article}
\makeatletter
% a)
%\newcommand*{\cmd}[1][]{\kernel@ifnextchar[{\cmd@@[{#1}]}{\cmd@@[][{#1}]}}
% or b)
\def\cmd{\kernel@ifnextchar[\cmd@{\cmd@[]}}
\def\cmd@[#1]{\kernel@ifnextchar[{\cmd@@[{#1}]}{\cmd@@[][{#1}]}}
% a) and b)
\def\cmd@@[#1][#2]#3{opt 1 $\to$ \texttt{#1}; opt 2 $\to$ \texttt{#2}; man $\to$ \texttt{#3}\par}
\makeatother
\begin{document}
\cmd{abc} % -> \cmd@@[][]{abc}
\cmd[opt1]{abc} % -> \cmd@@[][opt1]{abc}
\cmd[opt1][opt2]{abc} % -> \cmd@@[opt1][opt2]{abc}
\end{document}
Output

- 119,821
Here's an answer based on this great answer. Basically, you use two \newcommands with one optional argument each, and have one call the other. There is a bit of a complication in distinguishing when the second one is simply missing or is present but empty; I have stolen (rather clumsily) the LaTeX3 approach of using -NoValue- as the indicator for the former, so that the second and fourth examples below return different results.
\documentclass{article}
\usepackage{etoolbox}
\newcommand*\cmd[1][]{%
\def\argi{#1}%
\cmdA
}
% Default stolen from LaTeX3, badly
\newcommand*\cmdA[2][-NoValue-]{%
\def\argii{#1}%
\ifdefstring{\argii}{-NoValue-}{%
\let\argii\argi
\let\argi\empty
}{}%
Arg 1: \argi,
Arg 2: \argii,
Mandatory arg: #2%
}
\begin{document}
\cmd{x}
\cmd[a]{x}
\cmd[][a]{x}
\cmd[a][]{x}
\cmd[a][b]{x}
\end{document}
- 37,958
{plain-tex}but also with{etoolbox}which is a LaTeX package: do you want a plain TeX solution or are LaTeX macros or evenetoolbox' macros allowed? – cgnieder Apr 24 '13 at 22:57