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 xparse
ist 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 \newcommand
es etwas kniffliger. Das \@ifstar
Makro 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:
Ihr Code funktioniert, aber nicht wie erwartet. Er \MyCommand[1][1]
sucht nach einem optionalen Argument „while expanding“ \MyCommand
und 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 \@ifstar
Test 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 \MyCommand
Sie 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}