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.

When I create macros using \newcommand, I usually provide default variants setting some of the first arguments in a sort of partial application style

\newcommand\five[5]{#1,#2,#3,#4,#5}
\newcommand\letters{\five{a}{b}{c}}
\newcommand\numbers{\five{1}{2}{3}}

so that one could just say \numbers{8}{9} and gets 1,2,3,8,9.

Now I want to do this for a command with an optional argument, setting defaults for the first mandatory parameters. As far as I know \newcommand only takes one optional argument which always has to be the first one. So if I want to predefine some arguments with a new command, I have to move the optional argument further down to have it passed through. The following minimal working example shows how I managed to achieve this.

\documentclass{scrartcl}
\newcommand\five[5][f]{#1,#2,#3,#4,#5}
\newcommand\reordered{}
\newcommand\thirdoptional[2]{\renewcommand\reordered[3][f]{\five[##1]{##2}{##3}{#1}{#2}}\reordered}
\newcommand\letters{\thirdoptional{a}{b}}
\newcommand\numbers{\thirdoptional{1}{2}}

\begin{document}
\begin{itemize}
  \item \numbers[3]{4}{5}
  \item \letters[c]{d}{e}
  \item \thirdoptional{v}{w}[x]{y}{z}
  \item \thirdoptional{6}{7}{8}{9}
\end{itemize}
\end{document}

However, I am not satisfied that the helper \reordered is exported to the outside. On top of that, if the default argument of \five changes, this does not propagate to \thirdoptional. Is there another way to reorder arguments?

I know of packages like pgfkeys and keyval that provide more complex argument handling. But the commands I define have to work inside more complex environments than this example shows, especially some of them are defined globally through a TikZ \foreach, so I want to try to abstain from additional packages.

share|improve this question
1  
This is a job for xparse. With the standard method it would be really complicated. –  egreg Nov 15 '13 at 0:08
    
Since you have some responses below that seem to answer your question, please consider marking one of them as ‘Accepted’ by clicking on the tickmark below their vote count (see How do you accept an answer?). This shows which answer helped you most, and it assigns reputation points to the author of the answer (and to you!). It's part of this site's idea to identify good questions and answers through upvotes and acceptance of answers. –  Jubobs Dec 8 '13 at 18:52

1 Answer 1

You can test whether an optional argument is given or not (or just test whether it's empty) and condition on that. xparse provides a straight-forward interface:

enter image description here

\documentclass{article}
\newcommand\five[5][f]{#1,#2,#3,#4,#5}
\newcommand\reordered{}
\newcommand\thirdoptional[2]{\renewcommand\reordered[3][f]{\five[##1]{##2}{##3}{#1}{#2}}\reordered}
\newcommand\letters{\thirdoptional{a}{b}}
\newcommand\numbers{\thirdoptional{1}{2}}

\usepackage{xparse}% http://ctan.org/pkg/xparse
\NewDocumentCommand{\numbersA}{o m m}{%
  \IfNoValueTF{#1}% Condition on whether the optional argument is
    {\five{1}{2}{#2}{#3}}%... empty, or...
    {\five[#1]{1}{2}{#2}{#3}}%... not.
}

\begin{document}
\begin{itemize}
  \item \numbers[3]{4}{5}
  \item \letters[c]{d}{e}
  \item \thirdoptional{v}{w}[x]{y}{z}
  \item \thirdoptional{6}{7}{8}{9}
  \item \numbersA{4}{5}
  \item \numbersA[3]{4}{5}
\end{itemize}
\end{document}

The above MWE defines \numbersA[<opt>]{<stuff>}{<stuff>} that inserts the optional argument <opt> into the correct place where it's needed for \five. A similar definition for \lettersA could be made.

share|improve this answer

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.