Der beste Grund, in LaTeX eigene Befehle – also Makros – zu definieren, ist nicht die gesparte Tipparbeit. Man stelle sich eine Dissertation vor, in der jeder Vektor als \mathbf{v} gesetzt ist, vierhundertmal, und eine Betreuung, die nun doch Pfeile möchte. Stünde dort \vect{v}, gestützt auf ein einziges \newcommand, wäre die Umstellung eine Zeile in der Präambel; andernfalls sind es vierhundert sorgfältige Änderungen. Ein Makro ist der Ort, an dem sich später noch die Meinung ändern lässt. Diese Seite beginnt bei \newcommand und seinen Argumenten, klärt \renewcommand und \providecommand, erklärt, wohin der Leerraum hinter einem Makronamen verschwindet, und endet bei fragilen Befehlen, \protect und dem modernen \NewDocumentCommand.
Eigene Befehle mit \newcommand definieren
Die gesamte Syntax passt in eine Zeile: \newcommand{\name}{definition}. Das erste Argument ist der gewünschte Name, das zweite dessen Bedeutung; von da an wird jedes getippte \name durch definition ersetzt. Der übliche Platz dafür ist die Präambel, also vor \begin{document}. Genau hier zahlt sich die Vektorgeschichte aus: Der Name \vect benennt eine Bedeutung, kein Aussehen. Wer „das ist ein Vektor“ schreibt statt „das ist fett“, hält die Entscheidung – fett oder Pfeil darüber – an einer einzigen Stelle fest. Es ist derselbe Handel, den LaTeX ohnehin anbietet: \section statt handgesetzter 14pt-Fettschrift beruht auf genau demselben Gedanken.
% preamble: one line decides how every vector in the document looks
\usepackage{amsmath,amssymb}
\newcommand{\vect}[1]{\mathbf{#1}}
% \newcommand{\vect}[1]{\vec{#1}} % swap this line, the whole thesis follows
% semantic names for things you refer to constantly
\newcommand{\R}{\mathbb{R}}
\newcommand{\dd}{\mathrm{d}}
% body
\[ \vect{v} \cdot \vect{w} = \lvert \vect{v} \rvert \, \lvert \vect{w} \rvert \cos\theta \]
\[ \int_{\R} f(x) \, \dd x \]Makros mit Argumenten – und das optionale Argument
Damit sich der Inhalt bei jedem Aufruf ändern kann, gehört die Anzahl der Argumente in eckige Klammern hinter den Namen; in der Definition werden sie als #1, #2 usw. abgeholt: \newcommand{\name}[⟨nargs⟩]{... #1 #2 ...}. Es gibt genau eine harte Grenze – die Parameter reichen von #1 bis #9, also höchstens neun. Bemerkenswert daran: Wer ein zehntes verlangt, erhält ! You already have nine parameters., und diese Meldung stammt von der TeX-Engine, nicht von LaTeX. Die Grenze gehört zum darunterliegenden Primitiv \def, \newcommand kann sie nicht lockern. Mehr als neun zu brauchen ist meist ein Hinweis, den Entwurf auf Schlüssel-Wert-Optionen statt auf Positionsargumente umzustellen.
% two mandatory arguments: a number and a unit
\newcommand{\unit}[2]{#1\,\mathrm{#2}}
$a = \unit{9.8}{m/s^2}$Ein Schritt weiter lässt sich das erste Argument optional machen und mit einem Standardwert versehen. Das ist die Form mit doppelten Klammern, \newcommand{\name}[⟨nargs⟩][⟨default⟩]{...}: #1 wird zum optionalen Argument, und ein Aufruf ohne es setzt ⟨default⟩ ein. Geschrieben wird dann \name{...} für den Standardwert oder \name[x]{...}, um #1 auf x zu setzen; die übrigen Pflichtargumente zählen ab #2. Die Falle steckt in der Zählung: [⟨nargs⟩] ist die Gesamtzahl der Argumente einschließlich des optionalen. Im Beispiel unten bedeutet [2][2] also „zwei Argumente, davon das erste optional mit Standardwert 2“.
% two arguments in total; the first is optional and defaults to 2
\newcommand{\pow}[2][2]{(x + y)^{#1}_{#2}}
$\pow{n}$ % -> (x + y)^2_n
$\pow[3]{n}$ % -> (x + y)^3_n
% starred form: the argument may not contain a blank line
\newcommand*{\keyword}[1]{\textsf{#1}}Zwei Details gehören noch dazu. Erstens ist es etwas anderes, [⟨default⟩] wegzulassen, als leere Klammern [] zu schreiben: Letzteres ergibt ein optionales Argument mit der leeren Zeichenkette als Standardwert. Zweitens erzeugt das gesternte \newcommand* ein „kurzes“ Makro, dessen Argument keine Leerzeile (also kein \par) enthalten darf. Das wirkt wie eine Einschränkung, ist aber eine Diagnose: Bei einer vergessenen schließenden Klammer erscheint ! Paragraph ended before \keyword was complete. nahe am Fehler. Ohne Stern liest TeX bereitwillig den nächsten Absatz und den übernächsten als Teil des Arguments, und der Fehler taucht erst Seiten später auf. Ein * an jedem Makro, das ohnehin keine Absätze überspannen soll, erspart später viel Suchen.
Der Unterschied zwischen \newcommand, \renewcommand und \providecommand
Alle drei nehmen Argumente auf genau dieselbe Weise entgegen; verschieden ist nur, wie sie auf einen bereits vergebenen Namen reagieren. \newcommand verweigert und bricht ab, \renewcommand überschreibt, und \providecommand tritt still zurück und behält die vorhandene Definition. Auf einen existierenden Namen angesetzt, hält \newcommand also mit ! LaTeX Error: Command \emph already defined. an, während \renewcommand auf einen undefinierten Namen mit ! LaTeX Error: Command \foo undefined. anhält. Die beiden Meldungen bilden ein Paar und schützen von zwei Seiten: davor, versehentlich etwas zu überschreiben, und davor, ein Überschreiben zu glauben, das gar nicht stattgefunden hat.
Eine Kuriosität am Rande: \newcommand{\endnotes}{...} bricht mit Command \endnotes already defined. ab, obwohl nirgends ein Befehl dieses Namens existiert. Die zweite Zeile der Meldung verrät den Grund – sie lautet weiter Or name \end... illegal, see p.192 of the manual. Die Namensprüfung in latex.ltx stellt zuerst fest, dass der Name undefiniert ist, und verlangt zusätzlich, dass seine ersten drei Buchstaben nicht end lauten und der Name nicht relax ist. Da \end{itemize} intern über den Aufruf von \enditemize funktioniert, würde ein frei erfundener Name mit end am Anfang die Zuordnung von Umgebungen zerstören; deshalb ist das ganze Präfix reserviert. Die Formulierung „already defined“ ist nur eine grobe Meldung, die beide Fälle abdeckt.
| Befehl | Bei vorhandenem Namen | Verwendung |
|---|---|---|
\newcommand | Bricht mit Fehler ab | Neuen Befehl sicher erzeugen |
\renewcommand | Überschreibt ihn (Fehler, falls undefiniert) | Bestehenden Befehl umbauen |
\providecommand | Tut nichts (alte Definition bleibt) | Style-Dateien, die mehrfach geladen werden können |
\DeclareRobustCommand | Überschreibt ihn und notiert es im Log | Robuste Befehle für bewegliche Argumente |
Die praktische Arbeitsteilung ist klar. \renewcommand ist die Tür mit der Aufschrift „etwas ersetzen, das LaTeX schon bereitstellt“; das Aufzählungszeichen mit \renewcommand{\labelitemi}{--} zu ändern ist der klassische Fall. \providecommand erklärt „bereitstellen, falls es das noch nicht gibt“, damit eine eigene Style-Datei auch dann heil bleibt, wenn sie von zwei Stellen aus geladen wird. Im Beispiel unten existiert \vect bereits, also tut \providecommand gar nichts, und die fette Definition überlebt. \DeclareRobustCommand schließlich ist der Hauptdarsteller des nächsten Abschnitts: Es bricht bei vorhandenem Namen nicht ab, sondern hinterlässt lediglich eine Zeile wie LaTeX Info: Redefining \emph on input line 2. im .log. Das Überschreiben zu protokollieren statt es stillschweigend auszuführen – darin liegt der eigentliche Unterschied zu \renewcommand.
% replace something the class already defines
\renewcommand{\labelitemi}{--}
% define only if nobody else did; here \vect exists, so this line is a no-op
\providecommand{\vect}[1]{\vec{#1}}
% redefine on purpose, and say so in the log
\DeclareRobustCommand{\emph}[1]{\textbf{#1}}Warum der Leerraum hinter einem Makro verschwindet – und was \xspace löst
Ein nur aus Buchstaben gebildeter Befehlsname endet beim ersten Nicht-Buchstaben, und die folgenden Leerzeichen werden als Namensende-Markierung verschluckt. Steht also \newcommand{\lab}{Knuth Lab} in der Präambel, ergibt \lab was founded. im Text die Ausgabe „Knuth Labwas founded.“ Das Leerzeichen ist nicht verschwunden; TeX hat es aufgebraucht, um zu bestimmen, wo der Name \lab aufhört. Aufschlussreich ist die Ausnahme: \$ de behält seinen Abstand und setzt „$ de“. \$ ist ein einzeichiges Kontrollsymbol aus einem Nicht-Buchstaben; sein Name ist nach diesem einen Zeichen vollständig, ein Vorauslesen erübrigt sich. Die Falle betrifft also nur Befehlsnamen aus Buchstaben.
\usepackage{xspace}
\newcommand{\lab}{Knuth Lab}
\newcommand{\labx}{Knuth Lab\xspace}
\lab was founded. % -> Knuth Labwas founded.
\lab{} was founded. % -> Knuth Lab was founded.
\lab\ was founded. % -> Knuth Lab was founded.
\labx was founded. % -> Knuth Lab was founded.
\labx, and a comma. % -> Knuth Lab, and a comma.Drei Abhilfen stehen bereit. Üblich ist ein leeres Klammerpaar, \lab{}, das das Namensende markiert; daneben das geschützte Leerzeichen \lab\ ; und drittens \xspace aus dem Paket xspace. Das Raffinierte an \xspace: Es fügt den Abstand nicht bedingungslos ein, sondern sieht zuerst auf das nächste Token. Die Ausnahmeliste in xspace.sty enthält , . ' / ? ; : ! ~ - ) und schließende Klammern sowie \footnote und Verwandte; vor keinem davon wird ein Abstand gesetzt. Deshalb ergibt \labx, and korrekt „Knuth Lab, and“. Das Paket gehört zum LaTeX-Tools-Bündel und stammt ursprünglich von David Carlisle; mit \xspaceaddexceptions lässt sich die Liste erweitern. Der Preis sei genannt: \xspace ist ein Vorausschau-Trick, für Makros mit Argumenten überflüssig (die enden ohnehin auf }) und im Argument eines anderen Makros gelegentlich überraschend. Im Zweifel ist {} die sicherste der drei Lösungen.
Fragile Befehle, bewegliche Argumente, \protect und \DeclareRobustCommand
Ein selbst geschriebenes Makro kann in einer Abschnittsüberschrift oder einer Bildunterschrift plötzlich zerbrechen. Ursache ist das bewegliche Argument. Der Text von \section{...} wird nicht nur im Fließtext gesetzt: Er wird für das Inhaltsverzeichnis in die .aux-Datei geschrieben und an die Kopfzeile weitergereicht. Derselbe Inhalt „wandert“ also an andere Orte. \caption{...}, \thanks{...} sowie die @{...}-Ausdrücke von tabular und array verhalten sich genauso. Ein Befehl, dessen Code beim Hinausschreiben durch Expansion seinen Sinn verliert, heißt fragile command; einer, der das unverändert übersteht, robust command.
Das klassische Gegenmittel ist \protect, unmittelbar vor einen fragilen Befehl gesetzt und mit der Botschaft „hier nicht expandieren, sondern unverändert hinausschreiben“. Geschützt wird jeweils genau ein Befehl. Es gibt jedoch gute Nachrichten: Seit der LaTeX-Ausgabe vom Oktober 2019 wurden sehr viele einst fragile Befehle robust gemacht. Dokumentiert ist die Änderung in LaTeX News 30 im Abschnitt „Making more user commands robust“; sie reicht bis zu \begin und \end, sodass ganze Umgebungen inzwischen in Überschriften funktionieren. Der hartnäckige Ausreißer ist \verb: In einem Abschnittstitel bricht der Lauf mit ! LaTeX Error: \verb illegal in argument. ab (meist zieht er ! Paragraph ended before \@sect was complete. mit sich). Diesen Fall rettet \protect nicht, in Überschriften und Beschriftungen führt der praktische Weg über \texttt{...}.
% \verb cannot go here at all -- rewrite it
\section{The \texttt{\textbackslash par} primitive}
% a macro that is robust from the start, even though \ifmmode is fragile
\DeclareRobustCommand{\seq}[2][n]{%
\ifmmode #2_{1}\ldots #2_{#1}\else\textbf{??}\fi
}
\section{Sequences $\seq{x}$} % works without \protectFür eigene Makros ist es verlässlicher, sie mit \DeclareRobustCommand von vornherein robust zu definieren, als jedes Mal an \protect zu denken. Die Argumente werden genau wie bei \newcommand angegeben, und selbst wenn im Rumpf fragiler Code wie \ifmmode steckt, übersteht der entstehende Befehl ein bewegliches Argument. Das obige \seq ist das Beispiel aus LaTeX’ eigenem clsguide, das genau dies vorführen soll. Der Preis ist eine geringfügige Ineffizienz; ein Makro, das nie in einer Überschrift oder Bildunterschrift auftaucht, muss deshalb nicht robust sein. Die einzige nützliche Frage lautet: Kann dieses Makro jemals im Inhaltsverzeichnis landen?
\NewDocumentCommand – die moderne Art zu definieren
\newcommand kann nur eine Form erzeugen: höchstens ein optionales Argument in eckigen Klammern, gefolgt von Pflichtargumenten. \NewDocumentCommand{\name}{⟨arg-spec⟩}{...} hebt diese Grenze auf. Statt einer Argumentzahl wird eine Argumentspezifikation (arg-spec) übergeben: eine Buchstabenfolge, die die Art jedes Arguments benennt. Ursprünglich war das eine Funktion des Pakets xparse, doch die Ausgabe vom 1. Oktober 2020 nahm sie in den LaTeX-Kernel auf (Modul ltcmd); sie funktioniert daher heute ohne \usepackage{xparse}. LaTeX News 32 hält den Übergang fest.
| Spezifizierer | Bedeutung | Ankunft im Rumpf |
|---|---|---|
m | Pflichtargument | Gewöhnliches #1 usw. |
o | Optionales [...]-Argument | No-value-Marke, wenn es fehlt |
O{default} | Optional, mit Standardwert | Der Standardwert, wenn es fehlt |
s | Optionaler Stern * | Mit \IfBooleanTF geprüft |
Hier liegt der entscheidende Vorsprung gegenüber \newcommand: mehrere optionale Argumente sind möglich, und Sternvarianten werden als vollwertiges Merkmal behandelt. Ein s sorgt dafür, dass #1 als Wahrheitswert ankommt, der die Anwesenheit des Sterns meldet; verzweigt wird mit \IfBooleanTF{#1}{mit Stern}{ohne Stern}. Der Präfixwechsel zwischen New, Renew, Provide und Declare liefert die Gegenstücke zu \newcommand, \renewcommand, \providecommand und zum bedingungslosen Überschreiben. Für neuen Code darf diese Schnittstelle die Voreinstellung sein – wobei \newcommand weder verschwunden noch veraltet ist und für eine kurze Definition mit ein bis zwei Argumenten völlig genügt.
% s = optional star, m = mandatory argument
\NewDocumentCommand{\diff}{s m}{%
\IfBooleanTF{#1}%
{\frac{\mathrm{d}}{\mathrm{d}#2}}% starred: d/dx
{\mathrm{d}#2}% plain: dx
}
$\diff{x}$ % -> dx
$\diff*{x}$ % -> d/dx
% O{...} gives an optional argument with a default
\NewDocumentCommand{\note}{O{note} m}{\textbf{#1:} #2}Makros ohne Namenskollision benennen – und wo die Definitionen hingehören
Das beste Werkzeug gegen Namenskollisionen ist \newcommand selbst. Wer zuerst mit \renewcommand oder \def überschreibt, erfährt nie, was dabei zerstört wurde; wer erst mit \newcommand definiert, bekommt mit einem already defined sofort gesagt, dass der Name schon belegt ist. Genau deshalb sollten Kernel- oder Paketbefehle nicht leichtfertig mit \renewcommand plattgemacht werden. Bei eigenen Namen sind zu kurze zu meiden, besser ist ein projekteigenes Präfix (\myR, \bookTitle). Gerade kurze Namen mathematischer Operatoren sind längst vergeben – \ker, \deg, \arg, \Re –, wer also \R möchte, klärt das am besten mit einem Testlauf über \newcommand.
Zu viele Makros sind ebenso unlesbar wie zu wenige. Eine extreme Abkürzung wie \newcommand{\x}{\xi} ist Geheimschrift für das eigene künftige Ich und für Mitautoren. Makros gehören dem, was oft wiederholt wird, vermutlich gesammelt geändert wird oder einen Namen nach seiner Bedeutung verdient; alles Übrige liest sich ausgeschrieben meist besser. Der Test ist einfach: Lässt sich der Name auf einen Blick verstehen? \vect ja, \x nein.
Bleibt die Frage des Orts. Für einen einzelnen Aufsatz genügt die Präambel; ein Buch mit einer Datei je Kapitel oder mehrere Aufsätze mit gemeinsamer Notation lassen sich leichter pflegen, wenn die Definitionen in einer eigenen Datei stehen, die mit \usepackage geladen wird. Das bringt einen kleinen Vorteil: Innerhalb einer .sty- oder .cls-Datei gilt @ als Buchstabe, interne Namen wie \mybook@vecfont funktionieren also ganz ohne \makeatletter. Da ein Name mit @ aus dem Dokumenttext nicht aufrufbar ist, entsteht eine namentliche Trennung zwischen öffentlichen und privaten Befehlen. Dasselbe in der Präambel verlangt eine Einfassung zwischen \makeatletter und \makeatother – eine zusätzliche Fehlerquelle.
% ---- mynotation.sty --------------------------------------------
\ProvidesPackage{mynotation}[2024/01/01 shared notation]
\RequirePackage{amsmath,amssymb}
% private: the @ makes it uncallable from the document body
\newcommand{\mynot@vecfont}[1]{\mathbf{#1}}
% public
\newcommand{\vect}[1]{\mynot@vecfont{#1}}
\newcommand{\R}{\mathbb{R}}
% ---- thesis.tex ------------------------------------------------
% \usepackage{mynotation}