Using \@ifstar to define a star variant

The reason is that with \foo*{test} * is the argument for \foo and {test} is just the word text in a group. \foo must be a macro without argument, which calls another macro with argument

\documentclass{article}

\makeatletter
\newcommand{\foo}{\@ifstar{\@foob}{\@fooi}}
\newcommand{\@foob}[1]{\textbf{#1}}
\newcommand{\@fooi}[1]{\textit{#1}}
\makeatother

\begin{document}

\foo{test}
\foo*{test}

\end{document}

Macro \foo is defined with one argument. If it is called as \foo*{test}, then the star becomes the argument (#1); then \foo is expanded and \@ifstar is called. But the following token { is not a star. The argument, the star, is then set as \textit{*}. The processing of \foo is finished and {test} is interpreted as group with the word test inside.

The example can be fixed the following way:

\documentclass{article}

\makeatletter
\newcommand*{\foo}{\@ifstar\textbf\textit}
\makeatother

\begin{document}

\foo{test}
\foo*{test}

\end{document}

Result

Macro \foo is defined without argument, thus that \@ifstar can look for a following star. Then the code in the arguments for "with star" and "without star" of \@ifstar read the following argument.

If the code in the argument of \@ifstar is more complicate, then the more general answer of Mike helps.


In your definition the argument has already been read before the \@ifstar comes into the picture. So you would have to put the star behind the argument (remaek that it eats a space::

\documentclass{article}

\makeatletter
\newcommand{\foo}[1]{\@ifstar{\textbf{#1}}{\textit{#1}}}
\makeatother

\begin{document}

\foo{test}
\foo{test}*

\end{document}

enter image description here

But what you want is probably this:

\documentclass{article}

\makeatletter
\newcommand{\foo}{\@ifstar\textbf\textit}
\makeatother

\begin{document}

\foo{test}
\foo*{test}

\end{document}

enter image description here