Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Q] LaTeX command with two optional arguments?

2,321 views
Skip to first unread message

Rebecca and Rowland

unread,
Oct 30, 1998, 3:00:00 AM10/30/98
to
That's it really - does anyone know of a moderately easy way to define a
LaTeX command that takes two optional arguments?

Rowland.


--
Remove the animal for my email address: reb...@astrid.dog.u-net.com
Sorry - the spam got to me. PGP pub key A680B89D
UK biker? Join MAG and help keep bureaucracy at bay
http://dredd.meng.ucl.ac.uk/www/mag/mag.html

Heiko Oberdiek

unread,
Oct 30, 1998, 3:00:00 AM10/30/98
to
real-addr...@flur.bltigibbet (Rebecca and Rowland) wrote:

>That's it really - does anyone know of a moderately easy way to define a
>LaTeX command that takes two optional arguments?

There are several possibilities:

1.)
\newcommand{\cmd}[1][default-A]{%
\def\cmdDefaultA{#1}%
\cmdNext
}
\newcommand{\cmdNext}[2][default-B]{%
DefaultParam 1: \cmdDefaultA
DefaultParam 2: #1
Param 3: #2
}
Use: \cmd[A][B]{...}, \cmd[A]{...}, \cmd{...}


2.)
\newcommand{\cmd}[1][default-A]{%
\@ifnextchar[{%
\expandafter\cmdDo\@getnextopt{#1}%
}{%
\cmdDo{#1}{default-B}%
}%
}
\newcommand{\@getnextopt}{}
\long\def\@getnextopt#1[#2]{{#1}{#2}}
\newcommand{\cmdDo}[3]{%
DefaultParam 1: #1
DefaultParam 2: #2
Param 3: #3
}%


or 2.) formed to a package:
%%% --- snip --- twoopt.sty --- snip ---
% twoopt.sty
%
% Copyright (c) 1998 by Heiko Oberdiek.
% Email: ober...@ruf.uni-freiburg.de
%
% Function: Defining commands with two optional arguments
%
% Use:
% \newcommandtwoopt<cmd>[<n>][<A>][<B>]{...}
% * <cmd> command to be defined
% * <n> number of arguments
% * <A> default for first optional argument
% * <B> default for second optional argument
% There is a star form for non-long macros (similar '\newcommand*').
%
% Example:
% \newcommandtwoopt{\cmd}[3][aa][bb]{[#1:#2:#3]}
% \cmd[A][B]{C}, \cmd[A]{C}, \cmd{C}
%

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{twoopt}[1998/10/30 v1.0 %
Define commands with two opt. arg. (HO)]

\newcommand{\newcommandtwoopt}{%
\@ifstar{\@newcommandtwoopt{*}}{\@newcommandtwoopt{}}%
}
% #1: star
% #2: command name to be defined
\newcommand{\@newcommandtwoopt}{}
\long\def\@newcommandtwoopt#1#2{%
\expandafter\@@newcommandtwoopt\csname\string#2@2\endcsname{#1}{#2}%
}

% #1: help command to be defined
% #2: star
% #3: command name to be defined
% #4: number of total arguments
% #5: default for opt. 1
% #6: default for opt. 2
\newcommand{\@@newcommandtwoopt}{}
\long\def\@@newcommandtwoopt#1#2#3[#4][#5][#6]{%
\newcommand#2{#3}[1][#5]{%
\@ifnextchar[{%
\expandafter#1\@ArgOptToArgArg{##1}%
}{%
#1{##1}{#6}%
}%
}%
\newcommand#2#1[#4]%
}

\newcommand{\@ArgOptToArgArg}{}
\long\def\@ArgOptToArgArg#1[#2]{{#1}{#2}}

\endinput
%%% --- snip --- twoopt.sty --- snip ---

Yours sincererly
Heiko <ober...@ruf.uni-freiburg.de>

Heiko Oberdiek

unread,
Oct 30, 1998, 3:00:00 AM10/30/98
to
Stefan Ulrich <ulr...@cis.uni-muenchen.de> wrote:

>ober...@ruf.uni-freiburg.de (Heiko Oberdiek) writes:
>
>> real-addr...@flur.bltigibbet (Rebecca and Rowland) wrote:
>>
>> >That's it really - does anyone know of a moderately easy way to define a
>> >LaTeX command that takes two optional arguments?

>[...]
>
>And, just for completeness, yet another one,
>frequently used in latex.ltx:
>
>\def\foo{\@testopt\@foo{Testing}}
>\def\@foo[#1]{\@testopt{\@@foo[#1]}{Testing}}
>\def\@@foo[#1][#2]#3{%
> \typeout{first optional arg: #1}%
> \typeout{second optinal arg: #2}%
> \typeout{first arg: #3}}
>
>There's also a \@protected@testopt for moving arguments.
Yes, therefore I have used \newcommand[][], so \@protected@testopt
is called automatically.

* I see, your definitions are shorter, so I have optimized
my macros ;-)

* And I corrected a bug with handling of "optional" arguments.
Because the same type of bug is in Stefan Ulrich's \@foo and in
LaTeX's \@testopt I explain it:
\def\cmd#1{\nextcmd[#1]}
\def\nextcmd[#1]{\message{ arg = '#1' }}

If the argument of \cmd is enclosed in a curly brace pair it is
removed by TeX's macro substitution:
\cmd{ABC} ==> \nextcmd[ABC]

Now if the problem arises if the argument contains a close square
bracket:
\cmd{[ABC]} ==> \nextcmd[[ABC]]

So \nextcmd thinks the first close square bracket delimits the
its argument and not the correct second one.
\nextcmd[[ABC]] ==> \message{ arg = '[ABC' }]

For that reason there should be a brace pair around #1 in \cmd:
\def\cmd#1{\nextcmd[{#1}]}

>(Now, I did pay attention when you posted all that to
>de.comp.text.tex, didn't I ? ;-))

Of course I can post it to dctt, but I wait a little for the case,
someone found errors or better solutions, that make twoopt obsolete.

Yours sincerely
Heiko <ober...@ruf.uni-freiburg.de>

%%% --- snip --- twoopt.sty 1.1 --- snip ---


% twoopt.sty
%
% Copyright (c) 1998 by Heiko Oberdiek.
% Email: ober...@ruf.uni-freiburg.de
%
% Function: Defining commands with two optional arguments
%
% Use:
% \newcommandtwoopt<cmd>[<n>][<A>][<B>]{...}
% * <cmd> command to be defined
% * <n> number of arguments
% * <A> default for first optional argument
% * <B> default for second optional argument
% There is a star form for non-long macros (similar '\newcommand*').

% (Caution: With both definitions the defaults and the first optional
% argument are processed by non-long macros!)


%
% Example:
% \newcommandtwoopt{\cmd}[3][aa][bb]{[#1:#2:#3]}
% \cmd[A][B]{C}, \cmd[A]{C}, \cmd{C}
%

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{twoopt}[1998/10/30 v1.1 %


Define commands with two opt. arg. (HO)]

\newcommand{\newcommandtwoopt}{%
\@ifstar{\@newcommandtwoopt{*}}{\@newcommandtwoopt{}}%
}
% #1: star
% #2: command name to be defined
\newcommand{\@newcommandtwoopt}{}
\long\def\@newcommandtwoopt#1#2{%

\expandafter\@@newcommandtwoopt\csname2\string#2\endcsname{#1}{#2}%
}

% #1: help command to be defined (\2\<name>)


% #2: star
% #3: command name to be defined
% #4: number of total arguments
% #5: default for opt. 1
% #6: default for opt. 2
\newcommand{\@@newcommandtwoopt}{}
\long\def\@@newcommandtwoopt#1#2#3[#4][#5][#6]{%
\newcommand#2{#3}[1][{#5}]{%

\@ScanSecondOptArg#1{##1}{#6}%
}%
\newcommand#2#1[{#4}]%
}

% #1: help command to be defined (\2\<name>)
% #2: first arg of command to be defined
% #3: default for second opt. arg.
\newcommand{\@ScanSecondOptArg}[3]{%
\@ifnextchar[{%
\expandafter#1\@ArgOptToArgArg{#2}%
}{%
#1{#2}{#3}%
}%
}

\newcommand{\@ArgOptToArgArg}{}
\long\def\@ArgOptToArgArg#1[#2]{{#1}{#2}}

% bug fix, added braces around #2
\def\@testopt#1#2{%
\@ifnextchar[{#1}{#1[{#2}]}%
}

\endinput
%%% --- snip --- twoopt.sty 1.1 --- snip ---

David Carlisle

unread,
Oct 30, 1998, 3:00:00 AM10/30/98
to Heiko Oberdiek

> % bug fix, added braces around #2
> \def\@testopt#1#2{%
> \@ifnextchar[{#1}{#1[{#2}]}%
> }

grrr can you make a small test file and then use latexbug.tex to send
that to the usual address. I'll try to remember to get that fixed.

David

Heiko Oberdiek

unread,
Oct 30, 1998, 3:00:00 AM10/30/98
to
Stefan Ulrich <ulr...@cis.uni-muenchen.de> wrote:

>It also seems that you just have forgotten your posting
>
>http://www.dejanews.com/getdoc.xp?AN=318653750
>
>where you explained the various ways of \@testopt in detail.
Indeed. The solution from 23.01.1998 looks terrible, I think the
"second wheel" is better.

>The proper place for `twoopt' would be CTAN, I presume :-)
Of course :-)

Yours sincerely
Heiko <ober...@ruf.uni-freiburg.de>

Donald Arseneau

unread,
Oct 30, 1998, 3:00:00 AM10/30/98
to
In article <3639c3cd...@news.uni-freiburg.de>, ober...@ruf.uni-freiburg.de (Heiko Oberdiek) writes...

>Stefan Ulrich <ulr...@cis.uni-muenchen.de> wrote:
> If the argument of \cmd is enclosed in a curly brace pair it is
> removed by TeX's macro substitution:
> \cmd{ABC} ==> \nextcmd[ABC]
>
> Now if the problem arises if the argument contains a close square
> bracket:

This problem is very common. I complained when LaTeX2e was young that
it stripped several levels of braces from arguments, specifically in
\documentstyle[12pt,{disk:[my.macs]macros},fleqn]{article}.
I don't know if that was fixed.

Donald Arseneau as...@triumf.ca

Rebecca and Rowland

unread,
Oct 30, 1998, 3:00:00 AM10/30/98
to
Heiko Oberdiek <ober...@ruf.uni-freiburg.de> wrote:

> real-addr...@flur.bltigibbet (Rebecca and Rowland) wrote:
>
> >That's it really - does anyone know of a moderately easy way to define a
> >LaTeX command that takes two optional arguments?
>

> There are several possibilities:
>
> 1.)
> \newcommand{\cmd}[1][default-A]{%
> \def\cmdDefaultA{#1}%
> \cmdNext
> }
> \newcommand{\cmdNext}[2][default-B]{%
> DefaultParam 1: \cmdDefaultA
> DefaultParam 2: #1
> Param 3: #2
> }
> Use: \cmd[A][B]{...}, \cmd[A]{...}, \cmd{...}

This'll do very nicely - thanks :-)

Rowland.
(screaming uncontrollably at the way ItalicAngle in some afm files isn't
actually the angle the glyphs slope at so he's got to add yet another
bloody correction factor to the code to print a fake euro symbol)

[snip other stuff that doesn't look anything like as comprehensible but
is probably more elegant for reason the TeXnical can understand)

Heiko Oberdiek

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to
ober...@ruf.uni-freiburg.de (Heiko Oberdiek) wrote:
>real-addr...@flur.bltigibbet (Rebecca and Rowland) wrote:
>>That's it really - does anyone know of a moderately easy way to define a
>>LaTeX command that takes two optional arguments?

>% twoopt.sty
>[...]

Stefan Ulrich <ulr...@cis.uni-muenchen.de> wrote:
>The proper place for `twoopt' would be CTAN, I presume :-)

Now 'twoopt' is available on CTAN in directory:
CTAN:macros/latex/contrib/oberdiek/

Yours sincerely
Heiko <ober...@ruf.uni-freiburg.de>

0 new messages