Ich möchte hier zwei Möglichkeiten vorstellen, die das Gewünschte machen.
## machen, aber (im Gegensatz zu [Clemens][1]’ bereits [ausführlichen Antwort][2]) Macros des [LaTeX-Kernels][3] verwenden, die das ganze Prozedere vereinfachen/verkürzen.
**Version 1** gibt dabei eine Warnung aus, falls das Macro bereits definiert war, **Version 2** überschreibt das zu definierende Macro, komme was wolle. In beiden Fällen müssen wir aber erst mal schauen, ob dem Command ein Asterisk `*` folgt, das entscheidet, ob die folgende Definition `long` ist. (Mehr dazu unter [Was ist der Unterschied zwischen `\newcommand` und `\newcommand*`?][5]
# `\@star@or@long`
Alle Versionen von `\*command` und `\*environment` verwenden als erstes das Macro **`\\@star@or@long`**, das ein Argument erwartet (das Macro, was es nach getaner Arbeit ausführen soll).
Es setzt **`\\l@ngrel@x`** entweder zu `\long` (kein `*`) oder `\relax` (mit `*`). Dieses Macro wird dann in der eigentlichen Definition dem `\def` vorangestellt.
Soweit sehen beide Definition noch sehr ähnlich aus:
% Version 1
\newcommand*\Newcommand{\@star@or@long\New@command}
% Version 2
\newcommand*\NewCommand{\@star@or@long\New@Command}
# Version 1 (mit Warnung)
Diese Version macht in etwa das Gleiche, was [Clemens][1] in [seiner Antwort][2] erstellt hat, sie verwendet allerdings die originalen LaTeX-Macros, die auch von `\newcommand`, `\renewcommand`, etc. verwendet werden.
Das Macro **`\\@star@or@long`**
\def\@star@or@long#1{%
\@ifstar
{\let\l@ngrel@x\relax#1}%
{\let\l@ngrel@x\long#1}}
übernimmt dabei die Aufgabe den Asterisk `*` zu verarbeiten, die Information darüber wird in einem Macro **`\\l@ngrel@x`** gespeichert, das entweder zu `\long` or zu `\relax` gelassen (`\let`) wurde und somit direkt vor dem eigentlichen `\def`, das das Macro definiert, gestellt werden kann.
Das Macro **`\\New@command`** testet dann die zu definierende nun die ihm als Argument übergebene Macro-Sequenz `#1` mittels **`\\@ifundefined`**, dem wir das Macro aber ohne `\` übergeben, übergeben müssen, wobei `\@ifundefined` es dann nichts anderes macht als es gleich wieder mittels `\csname` zu einer Macro-Sequenz zusammenbaut. Es testet dann mithilfe von `\ifx` gegen `\relax`, da `\relax`; alle `\csname`s von Macros, die undefiniert sind, `\relax` gleichen.
gleichen bei einem `\ifx`-Test `\relax`.
Falls dieser Test wahr ist, wird nichts gemacht (`{}`); falls das Macro aber *wider Erwarten* doch bereits definiert ist, wird eine Warnung ausgegeben und die „magische“ Zeile
\let\@ifdefinable\@rc@ifdefinable
ausgeführt, die kurzer Hand den eigentlichen Test der Definierbarkeit aushebelt; `\@rc@ifdefinable` selbst stellt die originale Definition von `\@ifdefinable` dann wieder her (damit es beim nächsten Mal wieder ganz normal funktioniert).
Die zu definierende Macro-Sequenz wird einfach an `\new@command` weitergeleitet, das dann den Rest übernimmt (Anzahl der Argumente sowie optionaler Default-Wert).
Default-Wert und eigentliche Definition).
## Code
\newcommand*\Newcommand{\@star@or@long\New@command}
\newcommand*\New@command[1]{%
\@ifundefined{\expandafter\@gobble\string#1}{}{%
\@latex@warning@no@line{Redefining \string#1!}%
\let\@ifdefinable\@rc@ifdefinable}%
\new@command#1}
# Version 2 (ohne Warnung)
Möchte man sich die Warnung ersparen, macht man im Prinzip das Gleiche, nur lässt man eben gleich den eigentlichen Test für die Warnung weg und schaltet eben immer den Test auf Definierbarkeit ab (siehe „magische“ Zeile).
folgenden Definierbarkeitstest mit der oben erwähnten „magischen“ Zeile ab.
## Code
\newcommand*\NewCommand{\@star@or@long\New@Command}
\newcommand*\New@Command[1]{\let\@ifdefinable\@rc@ifdefinable\new@command#1}
## Oder andersrum
Man könnte den Test auch kurzer Hand austricken, in dem man das zu definierende Macro `#1` zu `\relax` lässt (siehe die Ausführung zu `\csname` und `\@ifundefined`):
\let#1\relax
`\@ifundefined` oben):
\newcommand*\New@Command[1]{\let#1\relax\new@command#1}
Der Test wird dann aber unnötigerweise ausgeführt, mit `\@rc@ifdefinable` findet er aber nicht mal statt.
Das ist wäre ein bisschen das Gegenteil von der `\providecommand`-`\renewcommand`-Lösung, die den Test von `\renewcommand` auf Definiertheit aushebelt, in dem das Macro eben einfach definiert wird, falls es noch nicht existierte.
## Code 1 (mit Warnung, kleines `c`)
\newcommand*\Newcommand{\@star@or@long\New@command}
\newcommand*\New@command[1]{%
\@ifundefined{\expandafter\@gobble\string#1}{}{%
\@latex@warning@no@line{Redefining \string#1!}%
\let\@ifdefinable\@rc@ifdefinable}%
\new@command#1}
## Code 2 (ohne Warnung, großes `C`)
\newcommand*\NewCommand{\@star@or@long\New@Command}
\newcommand*\New@Command[1]{\let\@ifdefinable\@rc@ifdefinable\new@command#1}
[1]: http://texwelt.de/wissen/benutzer/4/clemens
[2]: http://texwelt.de/wissen/antwort_link/1589/http://texwelt.de/wissen/antwort_link/1589/
[3]: http://www.tex.ac.uk/CTAN/macros/latex/unpacked/latex.ltx
[5]: http://texwelt.de/wissen/fragen/1587/wie-kann-ich-ein-makro-redefinieren-falls-existent-sonst-definieren