enumitem (Formatierung, Zähler, inline)

LaTeX-Listen wirken zu luftig – meist ist das der Grund, zum Paket enumitem zu greifen; die tatsächlichen Zahlen hat allerdings kaum jemand nachgesehen. In der Klasse article beträgt der Grundlinienabstand zwischen zwei Einträgen 20pt, gegenüber 12pt bei einer gewöhnlichen Zeile – acht zusätzliche Punkte Luft zwischen je zwei Einträgen. Diese acht Punkte sind zwei Längen: \itemsep (4pt) und \parsep (4pt). Genau dafür gibt es das Paket enumitem, das sie über Schlüssel=Wert-Optionen wie itemsep=0pt unmittelbar überschreibt. Diese Seite verfolgt, wie die Voreinstellungen wirklich lauten, was nosep und leftmargin=* tatsächlich ändern und wie \setlist eine Linie für ein ganzes Dokument festlegt – durchweg mit gemessenen Werten.

Wie die Listen-Voreinstellungen von LaTeX wirklich lauten

Gemessen in article bei 10pt, Ebene 1: \itemsep beträgt 4pt, \parsep 4pt, \topsep 8pt, \leftmargin 25pt, \labelwidth 20pt und \labelsep 5pt. Mit diesen Zahlen wird der Vorwurf der Luftigkeit greifbar. Der senkrechte Abstand zwischen zwei Einträgen ist \itemsep plus \parsep, zusammen 8pt – mit dem Zeilenabstand von 12pt ergibt das 20pt. In einem auf 12pt gesetzten Textkörper läuft also allein die Liste mit 1,67 Zeilen je Eintrag. Satztechnisch ist das Absicht: Die Einträge sollen sich optisch trennen. Zehn kurze Einträge hintereinander lassen die Seite jedoch löchrig wirken. Waagerecht dasselbe Bild: Dem \leftmargin von 25pt steht ein Aufzählungspunkt von keinen 5pt Breite gegenüber – 20pt dieses Einzugs sind schlicht Luft.

Länge (= Schlüsselname)article-Vorgabe (Ebene 1)Wirkungsort
itemsep4pt (plus 2pt minus 1pt)Zwischen zwei Einträgen
parsep4pt (plus 2pt minus 1pt)Zwischen Absätzen innerhalb eines Eintrags
topsep8pt (plus 2pt minus 4pt)Ober- und unterhalb der ganzen Liste
partopsep2pt (plus 1pt minus 1pt)Zusätzlich, nur wenn die Liste einen neuen Absatz beginnt
leftmargin25ptEinzug des gesamten Eintragsblocks von links
labelwidth20ptBreite der Etikettenbox; ein breiteres Etikett ragt nach links hinaus
labelsep5ptZwischen Etikettenbox und Eintragstext
rightmargin0ptDer rechte Rand; damit lässt sich die Liste beidseitig einengen, etwa für ein Zitat
itemindent0ptZusätzlicher Einzug nur der ersten Zeile eines Eintrags; ein negativer Wert zieht sie nach links
labelindent— (ein von enumitem ergänzter Schlüssel)Vom äußeren Rand bis zur linken Kante der Etikettenbox

Mit der Tiefe schrumpfen die Werte. Auf itemize-Ebene 2 fallen \itemsep und \parsep auf 2pt, \topsep auf 4pt und \leftmargin auf 22pt; auf Ebene 3 und 4 erreicht \parsep 0pt und \topsep 2pt, während \leftmargin auf 18,7pt und dann 17pt zusammengeht. LaTeX verfolgt also von Anfang an die Linie, die flachen Ebenen am stärksten zu öffnen; tiefe Verschachtelungen sind ohnehin eng. Deshalb ist die Ebene, die man verdichten möchte, meist Ebene 1.

Die Schlüssel=Wert-Schreibweise: Die Schlüssel sind LaTeX' eigene Längen

Mit \usepackage{enumitem} in der Präambel geladen, erhalten die drei Umgebungen itemize, enumerate und description ein optionales Argument: kommagetrennte key=value-Paare in den eckigen Klammern konfigurieren genau diese Liste. Entscheidend am Entwurf ist, dass die Schlüsselnamen genau den Längennamen der obigen Tabelle entsprechen. itemsep=1ex überschreibt \itemsep, leftmargin=1cm überschreibt \leftmargin. enumitem zu lernen heißt damit zugleich, die Listen-Interna von LaTeX zu lernen – darin liegt der eigentliche Vorteil gegenüber der älteren Gewohnheit, interne Befehle per \renewcommand zu ersetzen. TeX Live 2024 liefert die Fassung v3.9 (2019/06/20) von Javier Bezos aus; kpsewhich enumitem.sty zeigt, welche Kopie die eigene Installation verwendet.

document.tex
\usepackage{enumitem}
% ...
\begin{itemize}[itemsep=1ex, leftmargin=1cm]
  \item the key names are the LaTeX length names
  \item second entry
\end{itemize}

Derselbe Schlüssel lässt sich auf drei Ebenen überschreiben: für das ganze Dokument, für einen Umgebungstyp oder für eine einzelne Liste (über \setlist, siehe unten). Der spezifischste Wert gewinnt; sinnvoll ist daher, zuerst eine globale Linie festzulegen und nur dort auszuscheren, wo es sein muss. Ist ein Wert vollständig in geschweifte Klammern gefasst, wird ein äußeres Paar entfernt (das Standardverhalten von keyval) – wer die Klammern selbst behalten will, verdoppelt sie.

Listen verdichten: nosep gegen noitemsep

nosep setzt vier senkrechte Längen auf null, noitemsep nur zwei. Im Quelltext des Pakets setzt nosep \partopsep, \topsep, \itemsep und \parsep sämtlich auf 0pt, noitemsep dagegen allein \itemsep und \parsep. Vergessen wird meist partopsep – jene 2pt, die nur hinzukommen, wenn die Liste nach einer Leerzeile, also als neuer Absatz, beginnt. Gemessen setzt ein itemize mit nosep seine Eintragsgrundlinien exakt 12pt auseinander, genau wie gewöhnliche Textzeilen. Auch der Abstand über und unter der Liste verschwindet, sodass sie vollständig im laufenden Text aufgeht.

document.tex
% nosep  -> partopsep = topsep = itemsep = parsep = 0pt
% noitemsep -> itemsep = parsep = 0pt, list keeps its 8pt topsep
\begin{itemize}[nosep]
  \item item baselines land exactly 12pt apart
  \item as tight as ordinary body text
\end{itemize}

Die Wahl hängt davon ab, ob die Liste als Teil des Fließtexts gelesen werden soll. Stehen die Einträge im Mittelpunkt – eine Handlungsanweisung, eine Folie –, ist nosep recht. Für eine kurze Liste mitten im Text eines Aufsatzes ist noitemsep die sicherere Wahl: Die 8pt über und unter der Liste bleiben erhalten, die Grenze zwischen Absatz und Liste bleibt also sichtbar. Verdichtet man auch oben und unten, klebt die Liste an den Nachbarabsätzen, und Anfang und Ende der Aufzählung sind schwer auszumachen. Es gibt zudem den älteren Schlüssel nolistsep, der sich von nosep nur dadurch unterscheidet, dass er topsep auf 0pt plus .1pt statt auf glatt null setzt; für neue Dokumente empfiehlt sich nosep.

label= und ref=: Etikett und Querverweis getrennt gestalten

Das Etikett einer Liste wird mit label= festgelegt. Im Wert stehen die Sternformen \arabic*, \alph*, \Alph*, \roman* und \Roman* für den aktuellen Zähler dieser Ebene. label=(\arabic*) ergibt (1) (2) (3), label=\alph*) ergibt a) b) c), label=\Roman*. ergibt I. II. III. Die Sternformen nehmen kein Argument; sie sind Sonderschreibweisen, die nur innerhalb eines Etiketts Sinn ergeben. Daneben gibt es label*=, das an das Etikett der Elternliste anhängt, sodass sich beim Verschachteln 1., 1.1., 1.2. usw. aufbauen.

document.tex
\begin{enumerate}[label=(\arabic*), ref=\arabic*]
  \item \label{step:one} prepare the ingredients
  \item heat the pan
\end{enumerate}
Go back to step~\ref{step:one}.   % prints "step 1", not "step (1)"

Standardmäßig bestimmt label= auch das Aussehen des Querverweises. Versieht man einen Eintrag einer bloß als [label=(\arabic*)] deklarierten Liste mit \label, so druckt \ref das eingeklammerte (1) – daher rührt der alltägliche Ärger mit doppelten Klammern in „zurück zu Schritt (1)“. Ergänzt man ref=\arabic*, bleibt das gedruckte Etikett (1), während \ref eine nackte 1 liefert. Der obige Code, tatsächlich gesetzt, bestätigt genau das. Zu beachten: Die Werte von label und ref gelten als bewegliche Argumente, weshalb ein fragiler Befehl darin \protect benötigen kann; die Sternformen der Zähler selbst sind unproblematisch.

Wer Etiketten in der knappen Schreibweise des alten Pakets enumerate notieren möchte, lädt es als \usepackage[shortlabels]{enumitem}. Dann bedeutet ein A, a, I, i oder 1 als erstes Element in den Klammern jeweils \Alph*, \alph*, \Roman*, \roman* oder \arabic*, und \begin{enumerate}[(1)] funktioniert. Praktisch beim Portieren eines alten Manuskripts weg vom Paket enumerate; in neuen Arbeiten macht ein ausgeschriebenes label= die Absicht beim Wiederlesen deutlicher.

leftmargin=* und wide: den Rand sich selbst berechnen lassen

Die waagerechten Schlüssel sind nicht unabhängig, sondern durch eine einzige Gleichung verbunden: \leftmargin + \itemindent = \labelindent + \labelwidth + \labelsep. Übergibt man einigen von ihnen ein * statt eines Werts, löst enumitem die Gleichung für den Rest. Gemessen ist die Wirkung beträchtlich: Ein voreingestelltes itemize hat \leftmargin von 25pt; mit [leftmargin=*] schrumpft es auf 9,99pt – gerade genug für den Aufzählungspunkt. Wichtiger ist der umgekehrte Fall: Bei einem breiten Etikett wie label=(\roman*) passt „(viii)“ nicht in die voreingestellte 20pt-Box und ragt nach links hinaus, während leftmargin=* die Box dem Etikett anpasst. Wer ein breites Etikett verwendet, schreibt leftmargin=* gleich dazu – das verhindert die meisten Unfälle.

Der andere bequeme Schlüssel ist wide. Er setzt linken Rand und Etikettenbox auf null, sodass das Etikett als Teil des Textes gelesen wird und der Eintrag wie ein gewöhnlicher Absatz erscheint. Im Quelltext setzt er \leftmargin und \labelwidth auf null, legt sein Argument (voreingestellt \parindent) in \labelindent, gleicht \listparindent daran an und berechnet \itemindent aus der Gleichung. Gemessen ergeben sich \leftmargin 0pt, \itemindent 20pt und \listparindent 15pt, also \parindent. Ein Wert wie wide=0pt ändert den Einzug. Der Schlüssel ist die Wahl, wenn das Layout Listen ohne Vorsprung nach links und einen bündigen linken Textrand verlangt. Dazu passt align=, das entscheidet, ob das Etikett in seiner Box linksbündig (left), rechtsbündig (right, Vorgabe) oder in einer linksbündigen Parbox (parleft) steht.

Bei 5 beginnen oder die vorige Liste fortsetzen (start, resume, series)

start= legt die Nummer des ersten Eintrags fest, resume setzt die Nummerierung des unmittelbar vorangehenden enumerate fort. Eine Anleitung durch einen erläuternden Absatz zu unterbrechen und dann bei „7.“ weiterzumachen, ist ein sehr häufiger Bedarf; von Hand mit \setcounter erledigt, bricht es, sobald ein weiterer Schritt eingefügt wird. Tatsächlich gesetzt, ergab [start=5] die Nummern 5 und 6; nach einem dazwischenliegenden Absatz führte [resume] bei 7 fort. Mit resume* erbt man nicht nur die Nummer, sondern auch die Optionen der vorigen Liste (diese Sternform hat nur in den Klammern der Umgebung eine Bedeutung).

document.tex
\begin{enumerate}[start=5]
  \item numbered 5
  \item numbered 6
\end{enumerate}
An explanatory paragraph goes here.
\begin{enumerate}[resume]
  \item numbered 7 -- the count carries over
\end{enumerate}

resume sieht nur auf die unmittelbar vorangehende Liste und reicht daher nicht, wenn mehrere weit auseinanderliegende Listen – etwa über Abschnitte hinweg – eine einzige durchlaufende Zählung tragen sollen. Dafür dient eine Serie: Die erste Liste erhält series=Name, spätere Listen resume=Name oder resume*=Name; die Nummerierung schließt dann an, gleich was dazwischenliegt. Für eine lange, über Abschnitte verteilte Anleitung ist das der einzige Weg, der wirklich trägt.

Dokumentweite Vorgaben mit \setlist und eigene Listen mit \newlist

Dieselben Optionen jedes Mal zu schreiben, ist unrealistisch. \setlist wendet Einstellungen gebündelt auf einen gewählten Listentyp und eine Ebene an: \setlist{...} ohne Klammern erfasst jede Ebene jeder Liste, \setlist[itemize]{...} alle Ebenen von itemize, \setlist[enumerate,1]{...} nur Ebene 1 von enumerate. Das gesternte \setlist* ergänzt die bisherigen Einstellungen, statt sie zu ersetzen. Wer die eingangs beschriebene Luftigkeit dokumentweit beheben will, erreicht mit einer Zeile \setlist{noitemsep} in der Präambel den größten Effekt bei geringstem Aufwand.

preamble
\usepackage{enumitem}
\setlist{noitemsep}                    % tighten every list in the document
\setlist[itemize]{leftmargin=*}        % let itemize size its own margin
\setlist[enumerate,1]{label=(\arabic*), ref=\arabic*}

% a list type of your own
\newlist{steps}{enumerate}{1}
\setlist[steps]{label=\textbf{Step \arabic*.}, leftmargin=*}

Einen Schritt weiter lässt sich ein eigener Listentyp definieren. \newlist{Name}{Typ}{Maximaltiefe} klont eine der drei Grundlisten (enumerate, itemize oder description) in eine neue Umgebung, und ein folgendes \setlist[Name]{...} gibt ihr ihr Aussehen (mindestens das Etikett muss gesetzt werden). Beim Setzen des obigen Codes lieferte \begin{steps} „Step 1.“ und „Step 2.“. Der Gewinn liegt weniger im Druckbild als in der Lesbarkeit der Quelle: Wer \begin{steps} sieht, weiß ohne Blick auf die Seite, dass hier eine Anleitung steht. Die Bedeutung der Liste trägt ihr Name, nicht ihre Formatierung.

Einlauflisten innerhalb eines Absatzes (enumerate*)

Wird das Paket als \usepackage[inline]{enumitem} geladen, kommen die Sternumgebungen enumerate*, itemize* und description* hinzu, deren Einträge waagerecht durch den Absatz laufen, statt in eigene Zeilen umzubrechen. Gesetzt ergibt das eine einzige Zeile: „We need (1) flour (2) sugar (3) salt for this.“ Wenn nur drei oder vier kurze Wendungen aufzuzählen sind, liest sich das oft besser, als vier Zeilen der Seite für eine abgesetzte Liste zu verbrauchen – und im wissenschaftlichen Text ist diese Art, Bedingungen aufzuzählen, sogar die üblichere.

document.tex
\usepackage[inline]{enumitem}
% ...
We need
\begin{enumerate*}[label=(\arabic*)]
  \item flour \item sugar \item salt
\end{enumerate*}
for this.

Die Trenner regelt man mit itemjoin (zwischen den Einträgen; voreingestellt ein Leerzeichen), itemjoin* (für ein abweichendes Trennzeichen unmittelbar vor dem letzten Eintrag – so entsteht das englische „a, b, and c“) und afterlabel (direkt nach dem Etikett; voreingestellt ~). Zu beachten ist, dass die Einträge einer Inline-Liste voreingestellt in Boxen stehen, weshalb Gleitobjekte, verschachtelte Listen und abgesetzte Formeln nicht hineinpassen; wer sie braucht, gibt mode=unboxed an. In der Praxis ist die vernünftige Grenze: Inline-Listen nur für kurze Wendungen.