122

I would like to define a *'d version of a command, something like

\newcommand{\foo}{blah}
\newcommand{\foo*}{blahblah}

If I try to do this, LaTeX complains that I'm trying to redefine \foo, so I guess I need to do something special to handle *s. But what?

1
  • 4
    Of the different replies given: what is currently the recommended answer to this question? Feb 23, 2016 at 7:49

3 Answers 3

77

See this entry in the UK TeX FAQ.

The "elegant" way is to use the suffix package (which requires eTeX):

\documentclass{article}

\usepackage{suffix}
\newcommand\foo{blah}
\WithSuffix\newcommand\foo*{blahblah}

\begin{document}

\foo

\foo*

\end{document}
4
  • Does this work with commands with optional arguments too? If so how?
    – jan-glx
    Mar 11, 2014 at 10:59
  • 1
    @YAK I don't know. Note that the combination starred/optional is very rare.
    – lockstep
    Mar 11, 2014 at 11:37
  • 1
    Ups, I meant normal arguments, not optionals. And it works (\WithSuffix\newcommand\foo*[1]{Foo #1}) but warns "No 2nd argument following newcommand"...
    – jan-glx
    Mar 11, 2014 at 12:13
  • Maybe I misunderstood what you meant, and maybe the package has changed since then, but; \WithSuffix\newcommand\mycommand*[3]{starred command #1 #2 #3} works fine (\mycommand*{1}{2}{3})
    – Mogu
    Jul 25, 2019 at 9:22
85

If you look at source2e you might see a lot of lines that look like

\def\foo{\@ifstar\@foo\@@foo}
\def\@foo#1{...}
\def\@@foo#1{...}

This makes \foo a one-argument command that has regular and starred versions. The starred version is the expansion of \@foo while the nonstarred version is that of \@@foo. Using the @ sign in the auxiliary macros is a TeX convention which some authors embrace and some avoid.

There are higher-level ways to do it (as lockstep points out) but once you learn this pattern it's not too hard to use. Just make sure it's between \makeatletter...\makeatother or in a .sty file.

Edits removed some inaccuracies and editorializing.

3
  • 1
    What's the controversy with @? FWIW, it's also used in Plain and ConTeXt (although far less in the latter, which do is more common, leading to some funny command names such as \dodohideblock). Oct 22, 2010 at 3:22
  • 2
    Let me be clear that I follow the @-convention and am not advocating against it. But I can also see the point of view that the name \@foo (or \f@o or \f@@) doesn't help the human reader understand the relationship. \@foowithstar and \@foowithoutstar might be better. Sorry if I blew that internal ambivalence into a controversy. :-) Also, I wanted to point out that @'s are not required in auxiliary macros. Oct 22, 2010 at 11:12
  • 12
    Yes, using '@' in place of vowels is a pain in the neck, whereas using it as a divider is fine.
    – Joseph Wright
    Oct 23, 2010 at 17:39
73

LaTeX3 solution:

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\foo{s}{%
  \IfBooleanTF#1%
    {blahblah}% If a star is seen
    {blah}%     If no star is seen
}
1
  • This was the only solution that worked for me when using \dekotenize in the command and invoking the command from the caption of a lstlisting. Oct 5, 2021 at 20:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.