\@ifstar
¶Synopsis:
\newcommand{\mycmd}{\@ifstar{\mycmd@star}{\mycmd@nostar}} \newcommand{\mycmd@nostar}[nostar-num-args]{nostar-body} \newcommand{\mycmd@star}[star-num-args]{star-body}
Many standard LaTeX environments or commands have a variant with the
same name but ending with a star character *
, an asterisk.
Examples are the table
and table*
environments and the
\section
and \section*
commands.
When defining environments, following this pattern is straightforward
because \newenvironment
and \renewenvironment
allow the
environment name to contain a star. So you just have to write
\newenvironment{myenv}
or
\newenvironment{myenv*}
and continue the definition as
usual. For commands the situation is more complex as the star not being
a letter cannot be part of the command name. As in the synopsis above,
there will be a user-called command, given above as \mycmd
, which
peeks ahead to see if it is followed by a star. For instance, LaTeX
does not really have a \section*
command; instead, the
\section
command peeks ahead. This command does not accept
arguments but instead expands to one of two commands that do accept
arguments. In the synopsis these two are \mycmd@nostar
and
\mycmd@star
. They could take the same number of arguments or a
different number, or no arguments at all. As always, in a LaTeX
document a command using an at-sign @
in its name must be
enclosed inside a \makeatletter ... \makeatother
block
(see \makeatletter
& \makeatother
).
This example of \@ifstar
defines the command \ciel
and a
variant \ciel*
. Both have one required argument. A call to
\ciel{blue}
will return "not starry blue sky" while
\ciel*{night}
will return "starry night sky".
\makeatletter \newcommand*{\ciel@unstarred}[1]{not starry #1 sky} \newcommand*{\ciel@starred}[1]{starry #1 sky} \newcommand*{\ciel}{\@ifstar{\ciel@starred}{\ciel@unstarred}} \makeatother
In the next example, the starred variant takes a different number of
arguments than the unstarred one. With this definition, Agent 007’s
``My name is \agentsecret*{Bond},
\agentsecret{James}{Bond}.''
is equivalent to entering the commands
``My name is \textsc{Bond}, \textit{James} textsc{Bond}.''
\newcommand*{\agentsecret@unstarred}[2]{\textit{#1} \textsc{#2}} \newcommand*{\agentsecret@starred}[1]{\textsc{#1}} \newcommand*{\agentsecret}{% \@ifstar{\agentsecret@starred}{\agentsecret@unstarred}}
After a command name, a star is handled similarly to an optional
argument. (This differs from environment names in which the star is
part of the name itself and as such could be in any position.) Thus,
it is technically possible to put any number of spaces between the
command and the star. Thus \agentsecret*{Bond}
and
\agentsecret *{Bond}
are equivalent. However, the
standard practice is not to insert any such spaces.
There are two alternative ways to accomplish the work of
\@ifstar
. (1) The suffix
package allows the
construct \newcommand\mycommand{unstarred-variant}
followed by
\WithSuffix\newcommand\mycommand*{starred-variant}
.
(2) LaTeX provides the xparse
package, which allows
this code:
\NewDocumentCommand\foo{s}{\IfBooleanTF#1 {starred-variant}% {unstarred-variant}% }