
Alle Dokumentationen, die ich über markierte/nicht markierte Versionen von Befehlen gelesen habe, empfehlen mehr oder weniger die folgende Vorgehensweise (zum Beispieldie Liste der TeX-FAQs):
\newcommand{\mycommand}{\@ifstar\mycommandStar\mycommandNoStar}
\newcommand{\mycommandStar}{%
<few lines of code only for starred mycommand>
<many lines of code common to starred/non starred mycommand>
}
\newcommand{\mycommandNoStar}{%
<few lines of code only for non starred mycommand>
<many lines of code common to starred/non starred mycommand>
}
Für Umgebungen gilt ein ähnliches Schema (zum Beispieldiese Antwort):
\newenvironment{myenvironment}{%
<few lines of code only for non starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}{%
<few lines of code only for non starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}
\newenvironment{myenvironment*}{%
<few lines of code only for starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}{%
<few lines of code only for starred myenvironment>
<many lines of code common to starred/non starred myenvironment>
}
Meistens gibt es jedoch nur geringfügige Unterschiede zwischen den mit Sternchen gekennzeichneten und den nicht mit Sternchen gekennzeichneten Versionen und diese Vorgehensweise erfordert das Kopieren aller Änderungen im gemeinsamen Code zwischen den beiden Versionen, was einen hohen Wartungsaufwand bedeutet (insbesondere, wenn der gemeinsame Code lang ist).
Gibt es eine effizientere Vorgehensweise?
Antwort1
Es hängt hauptsächlich davon ab, was die Befehle tun sollen. Wenn es nur deshalb \mycommand*
abweicht \mycommand
, weil am Anfang anderer Code ausgeführt werden muss, sollte der folgende Ansatz funktionieren:
\newcommand{\mycommand}{\@ifstar{\@tempswatrue\@mycommand}{\@tempswafalse\@mycommand}}
\newcommand{\@mycommand}{%
\if@tempswa
<few lines of code only for starred mycommand>
\else
<few lines of code only for non starred mycommand>
\fi
<many lines of code common to starred/non starred mycommand>
}
Damit xparse
wird es einfacher:
\usepackage{xparse}
\NewDocumentCommand{\mycommand}{s}
{\IfBooleanTF{#1}
{<few lines of code only for starred mycommand>}
{<few lines of code only for non starred mycommand>}%
<many lines of code common to starred/non starred mycommand>%
}
Für das Umgebungsformular ergeben sich zusätzliche Komplikationen, da dieses nicht \@ifstar
verfügbar ist.
\newenvironment{myenvironment}{%
<few lines of code only for non starred myenvironment>
\@myenvironmentstart
}{%
<few lines of code only for non starred myenvironment>
\@myenvironmentfinish
}
\newenvironment{myenvironment*}{%
<few lines of code only for starred myenvironment>
\@myenvironmentstart
}{%
<few lines of code only for starred myenvironment>
\@myenvironmentfinish
}
\newcommand{\@myenvironmentstart}{%
<many lines of code common to starred/non starred myenvironment>
}
\newcommand{\@myenvironmentfinish}{%
<many lines of code common to starred/non starred myenvironment>
}
Eine wirkliche Vereinfachung ist mit nicht möglich xparse
.
Antwort2
Das xparse
Paket, das Teil des LaTeX3-Pakets ist, ist in dieser Hinsicht sehr praktisch. Zum Beispiel:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\foo}{s}{This is the \IfBooleanTF{#1}{starred }{}foo command.}
\begin{document}
\foo{}
\foo*{}
\end{document}