¿Cómo puedo definir un nuevo comando que admita variantes destacadas y no destacadas, y que también admita un argumento opcional?
Intenté lo siguiente:
\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}
Pero esto da:
La variante sin estrella con parámetro: 1
La variante con estrella con parámetro: 1
La variante sin estrella con parámetro: 2
La variante con estrella con parámetro: 1[2]
Sin embargo, se puede escribir \MyCommand[2]*
para obtener "La variante destacada con parámetro: 2", pero de alguna manera me gustaría que funcione la versión anterior.
Respuesta1
Es xparse
muy fácil jugar con argumentos opcionales y variantes destacadas:
\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}
Con LaTeX \newcommand
es un poco más complicado. La \@ifstar
macro mira el siguiente token después de expandirse y haber absorbido sus argumentos, por lo que primero debe verificar el *
argumento opcional y solo luego buscarlo:
\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 versiones imprimen:
Su código funciona, pero no como esperaba. Busca \MyCommand[1][1]
un argumento opcional "mientras se expande" \MyCommand
, que luego le proporciona:
\@ifstar{%
The starred variant with parameter: <optional argument or default>%
}{%
The non-starred variant with parameter: <optional argument or default>%
}
y solodespuésla \@ifstar
prueba se expandirá para buscar el opcional *
y elegir el texto en consecuencia, por lo que la sintaxis real para el comando que definiste es:
\MyCommand[optional argument]<optional star>
Respuesta2
No tomes \MyCommand
parámetros, solo calcula la estrella. Luego bifurca desde allí.
\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}