Como posso definir um novo comando que admite variantes com e sem estrela, e que também admite um argumento opcional?
Eu tentei o seguinte:
\documentclass{minimal}
\makeatletter
\newcommand\MyCommand[1][1]{%
\@ifstar{%
The starred variant with parameter: #1%
}{%
The non-starred variant with parameter: #1%
}
}
\makeatother
\begin{document}
\MyCommand \\
\MyCommand* \\
\MyCommand[2] \\
\MyCommand*[2]
\end{document}
Mas isso dá:
A variante sem estrela com parâmetro: 1
A variante com estrela com parâmetro: 1
A variante sem estrela com parâmetro: 2
A variante com estrela com parâmetro: 1[2]
No entanto, pode-se escrever \MyCommand[2]*
para obter "A variante estrelada com parâmetro: 2", mas de alguma forma eu gostaria que a versão acima funcionasse.
Responder1
É xparse
muito fácil brincar com argumentos opcionais e variantes marcadas com estrela:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\MyCommand
{
s % optional *
O{1} % first optional argument (default = 1)
}
{%
\IfBooleanTF{#1}
{The starred variant with parameter: #2}
{The non-starred variant with parameter: #2}
}
\begin{document}
\noindent
\MyCommand \\
\MyCommand* \\
\MyCommand[2]\\
\MyCommand*[2]
\end{document}
Com o LaTeX é \newcommand
um pouco mais complicado. A \@ifstar
macro olha para o próximo token depois que a macro é expandida e absorve seus argumentos, então você precisa primeiro verificar *
e só então procurar o argumento opcional:
\documentclass{article}
\makeatletter
\newcommand\MyCommand
{%
\@ifstar
{\MyCommand@star}
{\MyCommand@nostar}%
}
\newcommand\MyCommand@star[1][1]{%
The starred variant with parameter: #1%
}
\newcommand\MyCommand@nostar[1][1]{%
The non-starred variant with parameter: #1%
}
\makeatother
\begin{document}
\noindent
\MyCommand \\
\MyCommand* \\
\MyCommand[2]\\
\MyCommand*[2]
\end{document}
Ambas as versões imprimem:
Seu código funciona, mas não como você espera. O \MyCommand[1][1]
procura por um argumento opcional “durante a expansão” \MyCommand
, que fornece:
\@ifstar{%
The starred variant with parameter: <optional argument or default>%
}{%
The non-starred variant with parameter: <optional argument or default>%
}
e somentedepois dissoo \@ifstar
teste será expandido para procurar o opcional *
e escolher o texto de acordo, então a sintaxe real do comando que você definiu é:
\MyCommand[optional argument]<optional star>
Responder2
Faça \MyCommand
sem parâmetros, apenas descubra a estrela. Então bifurque a partir daí.
\documentclass{minimal}
\makeatletter
\newcommand\MyCommand{%
\@ifstar{\mycommandstar}{\mycommandnostar}
}
\newcommand\mycommandstar[1][1]{The starred variant with parameter: #1}
\newcommand\mycommandnostar[1][1]{The non-starred variant with parameter: #1}
\makeatother
\begin{document}
\MyCommand \\
\MyCommand* \\
\MyCommand[2] \\
\MyCommand*[2]
\end{document}