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.

LaTeX allows the use of optional parameters. Sometimes one wants to rewrite a command by making certain parameters optional:

\newcommand{\foo}[2]{
    #some commands
}

to:

\newcommand{\foo}[2][a]{
    #some commands
}

As far as I know, overloading is not supported in LaTeX thus making certain parameters optional cannot be done with low coupeling because calls to the method \foo{a}{b} must be converted to \foo[a]{b}. One cannot define the helper method \foo{}{} such that the package is backwards compatible.

I'm wondering what tools are available to rewrite command calls automatically, or macros to solve this problem elegantly.

share|improve this question
    
Let me try guessing: you have a command \foo and you'd like that the calls \foo{a}{b} and \foo[a]{b} do the same? –  egreg Aug 4 at 9:25
    
Indeed. So one argument is "optionalized"... –  CommuSoft Aug 4 at 9:29
4  
Then my advice is “don't”. What would \foo{b} mean? –  egreg Aug 4 at 9:31
1  
@CommuSoft: If it is not too much work, I would either search and replace or provide a new version, with a key value syntax. Of course it is possible to use \foo[]{} and \foo{}{}, but as egreg stated: foo{} is not recognized as being \foo[default value]{} and then treated as foo{}{} with an empty second argument. There might be some solution to this, but I can't provide it, I am too bad in such more sophisticated look-ahead-token - stuff ;-) –  Christian Hupfer Aug 4 at 9:57
1  
Why don't you just define \newcommand\Foo[2][a]{\foo{#1}{#2}}? Now \Foo{b} is the same as \foo{a}{b}. I'm assuming that \foo is some generic latex command and you just want a shortcut for the first argument... –  Andrew Aug 4 at 11:24

1 Answer 1

I am not sure if I understand well your question. IMHO you want to write

\foo {a}{b} ... % The macro \foo with two parameters will be invoked
\foo {a}    ... % Another variant of the macro \foo with one parameter.
                % May be the missing parameter is substituted by default here

My solution is, unfortunately, not expandable. The processing of scanning the braces is done at main processor level. But you can define the variants of \foo from zero to nine parameters:

% NormalTeXsyntaxOn

\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\sdef#1{\expandafter\def\csname#1\endcsname}

\newcount\tmpnum
\def\foo{\def\fooC{}\tmpnum=0\futurelet\next\fooA}
\def\fooA{\ifx\next\bgroup \expandafter\fooB\else
   \csname foo\the\tmpnum\expandafter\expandafter\expandafter\endcsname\expandafter\fooC\fi}
\def\fooB#1{\addto\fooC{{#1}}\advance\tmpnum by1\futurelet\next\fooA}

\sdef{foo0}{foo without parameters}
\sdef{foo1}#1{foo with one parameter "#1"}
\sdef{foo2}#1#2{foo with two parameters "#1" and "#2"}
\sdef{foo3}#1#2#3{foo with three parameters "#1", "#2" and "#3"}
\sdef{foo4}#1#2#3#4{foo with four parameters "#1", "#2", "#3" and "#4"}

\foo ...
\foo {a} ...         
\foo {a}{b} ...         
\foo {a}{b}{c} ...      
\foo {a}{b}{c}{d} ...   
\foo {a}{b}{c}{d}{f} ...

% NormalTeXsyntaxOff

Edit As an example the code above is packed to \multidef and the usage of the macro with three parameters with default values is shown:

\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\ssdef#1{\expandafter\def\csname\string#1\endcsname}
\newcount\tmpnum
\def\multidef#1{%
  \def#1{\def\tmpparam{}\tmpnum=0
         \expandafter\futurelet\expandafter\next\csname\string#1-A\endcsname}%
  \ssdef{#1-A}{\ifx\next\bgroup \csname\string#1-B\expandafter\endcsname\else
      \csname \string#1\the\tmpnum\expandafter\expandafter\expandafter\endcsname
      \expandafter\tmpparam\fi}%
  \ssdef{#1-B}##1{\addto\tmpparam{{##1}}\advance\tmpnum by1
      \expandafter\futurelet\expandafter\next\csname\string#1-A\endcsname}%
}
\multidef\foo  % the \foo macro with various numbers of parameters is defined here
\ssdef{\foo0}{\fooNormal{defaultA}{defaultB}{defaultC}}
\ssdef{\foo1}#1{\fooNormal{defaultA}{defaultB}{#1}}
\ssdef{\foo2}#1#2{\fooNormal{defaulA}{#1}{#2}}
\ssdef{\foo3}{\fooNormal}
\def\fooNormal#1#2#3{foo invoked: param1=#1, param2=#2, param3=#3}

Test:
\foo ...            % does: \fooNormal{defaultA}{defaultB}{defaultC}
\foo {a} ...        % does: \fooNormal{defaultA}{defaultB}{a}
\foo {a}{b} ...     % does: \fooNormal{defaultA}{a}{b}
\foo {a}{b}{c} ...  % does: \fooNormal{a}{b}{c}

Is it what do you want?

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.