\newcommand: Kombiniere (optional) Stern und optionalen Parameter

\newcommand: Kombiniere (optional) Stern und optionalen Parameter

Wie kann ich einen neuen Befehl definieren, der mit Sternchen versehene und nicht mit Sternchen versehene Varianten und außerdem ein optionales Argument zulässt?

Ich habe Folgendes versucht:

\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}

Das ergibt aber:

Die nicht mit Sternchen markierte Variante mit Parameter: 1
Die mit Sternchen markierte Variante mit Parameter: 1
Die nicht mit Sternchen markierte Variante mit Parameter: 2
Die mit Sternchen markierte Variante mit Parameter: 1[2]

Man kann zwar schreiben, \MyCommand[2]*dass man „die mit einem Sternchen markierte Variante mit dem Parameter 2“ erhalten möchte, aber irgendwie hätte ich gerne, dass die obige Version funktioniert.

Antwort1

Mit xparseist es sehr einfach, mit optionalen Argumenten und mit Sternchen markierten Varianten herumzuspielen:

\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}

Bei LaTeX ist \newcommandes etwas kniffliger. Das \@ifstarMakro schaut sich das nächste Token an, nachdem das Makro erweitert wurde und seine Argumente aufgenommen hat. Sie müssen also zuerst nach dem *und erst dann nach dem optionalen Argument suchen:

\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}

Beide Versionen drucken:

Bildbeschreibung hier eingeben

Ihr Code funktioniert, aber nicht wie erwartet. Er \MyCommand[1][1]sucht nach einem optionalen Argument „while expanding“ \MyCommandund gibt Ihnen dann Folgendes:

\@ifstar{%
  The starred variant with parameter: <optional argument or default>%
}{%
  The non-starred variant with parameter: <optional argument or default>%
}

und nurdanachDer \@ifstarTest wird erweitert, um nach optionalen Angaben zu suchen *und den Text entsprechend auszuwählen. Die tatsächliche Syntax für den von Ihnen definierten Befehl lautet also:

\MyCommand[optional argument]<optional star>

Antwort2

Nehmen \MyCommandSie keine Parameter an, sondern finden Sie einfach den Stern heraus. Dann verzweigen Sie von dort aus.

\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}

Bildbeschreibung hier eingeben

verwandte Informationen