Das Aussehen einer LaTeX-Überschrift wird an einer erstaunlich kleinen Stelle festgelegt. Vier Zeilen ab Zeile 302 von article.cls — ein einziger Aufruf, der einem Befehl namens \@startsection sechs Argumente übergibt — bestimmen Schrift, Nummerierung und Abstände jeder \section. Das Paket titlesec von Javier Bezos liest genau diese sechs Argumente wieder aus der Klasse heraus und serviert sie als lesbares \titleformat und \titlespacing. Deshalb ändert das bloße Laden auf der Seite keinen einzigen Punkt. Diese Seite öffnet zuerst das \@startsection der Klasse, zeigt dann, wie \titleformat und \titlespacing geschrieben werden, was der Stern wirklich bedeutet und warum das Paket mit KOMA-Script und memoir kollidiert — durchgehend gemessen.
\@startsection: die sechs Argumente, in denen eine Klasse eine Überschrift definiert
Lässt man sich die Definition von \section ausgeben, erscheint ein einziger Aufruf mit sechs Argumenten. Alle Überschriften der Standardklassen außer \part haben diese Gestalt; die Argumente sind der Reihe nach Name der Überschrift, Ebenennummer, Einzug, Abstand darüber, Abstand darunter und Formatierung. Genau das stehen in den Zeilen 302 bis 305 von article.cls.
% article.cls, lines 302-305 (TeX Live 2024)
\newcommand\section{\@startsection {section}{1}{\z@}%
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
{\normalfont\Large\bfseries}}
% \paragraph, from the same file - note the NEGATIVE after-skip
\newcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
{3.25ex \@plus1ex \@minus.2ex}%
{-1em}%
{\normalfont\normalsize\bfseries}}Interessant ist, dass die Vorzeichen des vierten und fünften Arguments Bedeutung tragen. Ein negatives viertes Argument (der Abstand darüber) heißt: „Den Absatz nach dieser Überschrift nicht einrücken.“ Ein negatives fünftes (der Abstand darunter) heißt: „Nach der Überschrift nicht umbrechen, der Text läuft weiter“ — also eine eingelaufene Überschrift (run-in). \section hat oben -3.5ex, deshalb wird der Absatz nach einem Abschnitt nicht eingerückt. \paragraph hat unten -1em, deshalb ist \paragraph eine eingelaufene Überschrift. Verhalten über das Vorzeichen einer Länge zu schalten, ist TeX-Design der 1980er in Reinform. Der Beleg steckt in der Implementierung: Die Routine, mit der titlesec eine Klassendefinition wieder ausliest, wählt bei negativem vierten Argument das gesternte \titlespacing* und bei negativem fünften die Form runin — und dreht dabei jeweils das Vorzeichen um.
| Gliederungsbefehl | Ebene in article | Ebene in book / report |
|---|---|---|
\part | 0 | −1 |
\chapter | (existiert nicht) | 0 |
\section | 1 | 1 |
\subsection | 2 | 2 |
\subsubsection | 3 | 3 |
\paragraph | 4 (standardmäßig eingelaufen) | 4 |
\subparagraph | 5 (ebenso) | 5 |
Es gibt also sechs Ebenen in article (0 bis 5) und sieben in book und report (−1 bis 5); die zusätzliche ist \chapter. Wie tief nummeriert wird, steckt in \c@secnumdepth: gemessen 3 im article und 2 in book und report. Deshalb nummeriert article bis \subsubsection, book dagegen nur bis \subsection. Mit \setcounter{secnumdepth}{4} bekommt auch \paragraph eine Nummer. Wie tief das Inhaltsverzeichnis reicht, ist eine eigene Rechnung und steht in tocdepth.
Was beim Laden von titlesec tatsächlich geschieht
Auf der Seite ändert sich nichts. Was sich ändert, ist die Definition von \section: Der Aufruf von \@startsection wird durch titlesecs eigene Maschinerie ersetzt. Gemessen lautet \section vor dem Laden \@startsection {section}{1}{\z@}{-3.5ex ...}{2.3ex ...}{\normalfont \Large \bfseries} und danach nur noch \ttl@straightclass {section}. Dabei wandern die sechs Argumente in titlesecs internen Speicher, wo der Abstand darüber zur konkreten Länge 15.0694pt plus 4.30554pt minus 0.86108pt und der darunter zu 9.90276pt plus 0.86108pt wird. Das sind schlicht ausgerechnete 3.5ex und 2.3ex, denn in 10pt Computer Modern gilt 1ex = 4.30554pt (die Anteile plus und minus sind Dehnung und Schrumpfung, die LaTeX beim Ausgleichen des Seitenfußes nutzen darf). Kurz: eine Äquivalenzumformung, bei der kein Fitzelchen Bedeutung verloren geht.
% Measured in a 10pt article. These two lines reproduce exactly what the
% class already does - they are what titlesec extracted on load.
\titleformat{\section}[hang]
{\normalfont\Large\bfseries}{\thesection}{1em}{}
\titlespacing*{\section}{0pt}
{15.0694pt plus 4.30554pt minus 0.86108pt} % = 3.5ex plus 1ex minus .2ex
{9.90276pt plus 0.86108pt} % = 2.3ex plus .2ex\titleformat schreiben: sieben Argumente und sechs Formen
\titleformat ist das Zentrum der Umgestaltung. Es nimmt viele Argumente, doch sie entsprechen den sechs von \@startsection, also ist nichts zu fürchten. Soll nur die Schrift anders sein, ist die Sternform \titleformat* der kürzeste Weg — zwei Argumente, etwa \titleformat*{\section}{\large\bfseries\sffamily} —, und Nummerierung wie Abstände bleiben, wie die Klasse sie gesetzt hat. Noch kürzer geht es mit der einfachen Einrichtung allein über Paketoptionen: \usepackage[sf,bf]{titlesec} macht alle Überschriften serifenlos fett. Die Optionen bilden drei Familien — rm sf tt md bf up it sl sc; big medium small tiny; raggedleft center raggedright — dazu compact, das den Abstand oben und unten verkleinert. Soll sich nur die Darstellung der Nummer ändern, dient \titlelabel, etwa \titlelabel{\thetitle.\quad}, wobei \thetitle für die Nummer der Überschrift steht.
\titleformat{⟨command⟩}[⟨shape⟩]{⟨format⟩}{⟨label⟩}{⟨sep⟩}{⟨before-code⟩}[⟨after-code⟩]⟨command⟩— der Gliederungsbefehl, den du neu gestaltest:\part,\chapter,\section,\subsection,\subsubsection,\paragraphoder\subparagraph.[⟨shape⟩](optional) — die „Form“ der Überschrift:hang,block,display,runin,leftmargin,rightmargin,frame,drop,wrap. Standard isthang.{⟨format⟩}— Formatierung für Label und Titel. Schrift und Größe stehen hier zusammen, die Ausrichtung regeln\filcenter,\filright,\filleft,\fillastsowie\filinner/\filouterim zweiseitigen Satz.{⟨label⟩}— wie die Nummer ausgegeben wird; hier steht\thesectionoder\@seccntformat{section}, um die Formatierung der Klasse zu erhalten. Bleibt es leer, fehlt die Nummer auch im Inhaltsverzeichnis.{⟨sep⟩}— Abstand zwischen Label und Titel. Er muss eine Länge sein und darf nicht leer sein (horizontal beihang/block, vertikal beidisplay, Titel-zu-Rahmen-Abstand beiframe).{⟨before-code⟩}— Code, der direkt vor dem Titel läuft. Hier kommt der Schmuck hin:\titlerulefür eine Linie,\titleline, um beliebiges Material auf eine eigene Zeile zu setzen.[⟨after-code⟩](optional) — Code direkt nach dem Titel (vertikaler Modus beihang/block/display, horizontaler beirunin/leftmargin).
| shape | Wirkung |
|---|---|
hang | Standard: hängendes Label, der Titel rechts daneben ausgerichtet (das Standard-\section) |
block | Setzt Label und Titel als einen Block (Absatz); die richtige Wahl für zentrierte Überschriften |
display | Stellt das Label in eine eigene Zeile über den Titel (das Standard-\chapter) |
runin | Eingelaufene Überschrift: kein Umbruch, der Text läuft in derselben Zeile weiter (das Standard-\paragraph) |
leftmargin | Setzt den Titel in den linken Rand; rightmargin ist die Variante für den rechten Rand |
frame | Wie display, aber der Titel wird gerahmt |
drop | Lässt den Text um den Titel fließen; wrap passt die Titelbox an ihren Inhalt an |
\titlespacing und die Bedeutung des Sterns: warum fast immer \titlespacing*
Der Stern bedeutet: den Einzug des Absatzes nach der Überschrift unterdrücken. Am leichtesten merkt man ihn sich als direkte Übersetzung der Konvention aus dem vorigen Abschnitt: Ein negativer Abstand darüber heißt „kein Einzug“. Das Standard-\section hat oben -3.5ex; wer das Aussehen der Klasse behalten will, nimmt also die Sternform — daher die Faustregel „fast immer \titlespacing*“. Die Argumente sind der zusätzliche linke Rand, der Abstand über der Überschrift, der Abstand zwischen Überschrift und Text sowie ein optionaler zusätzlicher rechter Rand. In den leftmargin-Formen ist das erste Argument die Titelbreite, bei runin der Einzug direkt davor. Bei drop, wrap und runin gibt es ohnehin keinen Einzug zu unterdrücken, dort bleibt der Stern also wirkungslos.
\titlespacing*{⟨command⟩}{⟨left⟩}{⟨before-sep⟩}{⟨after-sep⟩}[⟨right⟩]
% All arguments must be LENGTHS. A value containing a command such as
% \stretch, or an empty {}, produces:
% ! Missing number, treated as zero.
% ! Illegal unit of measure (pt inserted).
%
% Shorthand: *4 means 4 units of \beforetitleunit (or \aftertitleunit)
\titlespacing*{\section}{0pt}{*4}{*2}Alle Argumente müssen Längen (Maße) sein. Übergibt man einen Wert mit einem Befehl darin, etwa \stretch{1}, folgt ! Missing number, treated as zero. und danach ! Illegal unit of measure (pt inserted). Ein leeres {} erzeugt dasselbe Fehlerpaar. Wem das Ausschreiben voller Skip-Werte lästig ist, kürzt mit * und einer Zahl ab, etwa *4; die Einheiten dafür stehen in \beforetitleunit und \aftertitleunit.
Ein Verhalten, das eine Messung verdient, weil viele darauf hereinfallen. \titlespacing bewirkt bei \chapter und \part nichts, solange man nicht zugleich ihr Format mit \titleformat definiert. Schreibt man in der Klasse report nur \titlespacing*{\chapter}{0pt}{0pt}{10pt} und misst dann, wo der Text nach einem Kapitel beginnt, kommen 305.1077pt heraus — kein einziger skalierter Punkt Unterschied zum Weglassen. Ergänzt man in derselben Datei \titleformat{\chapter}[display]{...}, rückt der Wert auf 229.2701pt. Weder Warnung noch Fehler erscheinen; das Unangenehme ist, es nicht zu bemerken. \part ist ohnehin nicht über \@startsection implementiert, weshalb selbst die einfache Einrichtung es unangetastet lässt. Bei beiden Ebenen fängt man mit \titleformat an.
Eine Überschrift mit Linie und eine eingelaufene Überschrift bauen
\titleformat und \titlespacing* schreibt man üblicherweise als Paar. Die folgende Präambel macht aus \section eine Überschrift mit dünner Linie über dem Titel und aus \subsection eine eingelaufene Überschrift, die mit einem Punkt endet und den Text weiterlaufen lässt. Für die Linie setzt man idiomatisch \titlerule in das {⟨before-code⟩} der Form [display]. Die Option [explicit] sorgt dafür, dass der Titeltext nicht mehr von selbst erscheint: Man muss ihn dann ausdrücklich mit #1 platzieren — genau der Mechanismus, den man braucht, wenn vor und nach dem Titel Schmuck stehen soll.
\documentclass{article}
\usepackage[explicit]{titlesec}
% A rule above the title, sans-serif bold below it
\titleformat{\section}[display]
{\normalfont\Large\bfseries\sffamily} % applies to label and title
{\thesection} % the number
{0pt} % label-to-title gap (vertical here)
{\titlerule\vspace{2pt}#1} % before-code, then the title itself
\titlespacing*{\section}{0pt}
{3.5ex plus 1ex minus .2ex}{2.3ex plus .2ex}
% A run-in subsection: "1.1 Beta. Text continues here."
\titleformat{\subsection}[runin]
{\normalfont\bfseries}{\thesubsection}{.5em}{#1.}
\titlespacing*{\subsection}{0pt}{2ex plus .5ex}{.5em}
\begin{document}
\section{Alpha}
The paragraph after a starred \titlespacing is not indented.
\subsection{Beta}
This text runs on from the heading, on the same line.
\end{document}Inhaltsverzeichnis und Kolumnentitel anpassen: titletoc und titleps
Sind die Überschriften umgestaltet, sollen meist auch Inhaltsverzeichnis und Kolumnentitel dazu passen. titlesec bringt im selben Bündel zwei Schwesterpakete mit, die auch eigenständig nutzbar sind: titletoc für das Verzeichnis und titleps für die Seitenstile. Kern von titletoc sind \titlecontents, das einen Verzeichniseintrag vollständig definiert, und \dottedcontents, eine Voreinstellung mit Punktführung. Einzige Falle: Das erste Argument ⟨section⟩ ist der Name ohne Backslash (section, chapter, figure, …). titleps definiert mit \newpagestyle einen kompletten Seitenstil und füllt dessen linke, mittlere und rechte Position über \sethead und \setfoot. Welcher Überschriftenname in den Kolumnentitel gelangt, steuert \settitlemarks; mit \bottitlemarks, \toptitlemarks und \firsttitlemarks lässt sich wählen, welche Überschrift der Seite verwendet wird. Der Bau von Kopf- und Fußzeilen selbst — samt fancyhdr — hat eine eigene Seite.
\usepackage{titletoc}
% Dotted leaders for section entries:
% indent 1.5em, no numbered-entry format, label width 2.3em, leader 1pc
\dottedcontents{section}[1.5em]{}{2.3em}{1pc}
\usepackage{titleps}
\newpagestyle{main}{\sethead{\thesection}{}{\thepage}}
\pagestyle{main}Warum titlesec nicht zu KOMA-Script oder memoir passt
Beide Klassenfamilien bauen ihre Überschriften mit eigener Mechanik, sodass ein titlesec, das darüber hinweg \@startsection abfangen will, nicht greift. Sie scheitern allerdings völlig unterschiedlich. KOMA-Script meldet sich zu Wort. Lädt man titlesec in scrartcl, kommt zuerst Class scrartcl Warning: Usage of package titlesec together with a KOMA-Script class is not recommended. und danach je Überschrift eine Meldung: Package titlesec Warning: Non standard sectioning command \section detected. Using default spacing and no format. Diese zweite Meldung ist der eigentliche Kern: KOMA-Scripts \section ruft \scr@startsection statt \@startsection auf, sodass titlesec nichts von der Gestaltung der Klasse auslesen kann und die Überschrift stattdessen mit eigenen Vorgaben neu setzt. Und es bleibt nicht immer bei einer Warnung. Kombiniert man es mit einer Überschriftenoption der Klasse, etwa \documentclass[headings=big]{scrartcl}, lautet das gemessene Ergebnis ! Package titlesec Error: No format for this command., gefolgt von ! Missing number, treated as zero. und ! Illegal unit of measure (pt inserted). — der Satz bricht dort schlicht zusammen. Mit KOMA-Script gestaltet man Überschriften über die klasseneigene Schnittstelle: \setkomafont und \RedeclareSectionCommand.
memoir dagegen sagt gar nichts. Unter TeX Live 2024 lief die Kombination ohne Warnung und ohne Fehler durch, und \titleformat wirkte wie erwartet. Der Grund: memoirs \section hat die Gestalt \sechook \@startsection {section}{1}{\secindent}{\beforesecskip}{\aftersecskip}{\normalfont \secheadstyle}, die titlesec als Standard erkennt und auslesen kann. Sieht man sich das Ausgelesene an, bleiben \secheadstyle und \secindent zwar als Namen erhalten, doch die Abstände oben und unten wurden auf die beim Laden geltenden Werte 15.0694pt und 9.90276pt eingefroren. \setsecheadstyle überlebt also, während \setbeforesecskip und \setaftersecskip wirkungslos werden — das Paket zerbricht die halbe Schnittstelle, und zwar stumm. memoir bringt einen vollständigen eigenen Mechanismus für Überschriften mit; diesen zu verwenden ist der sicherere Weg.
Noch zwei nützliche Dinge rund um titlesec. \titleclass weist einer Ebene eine andere Klasse zu, etwa \titleclass{\subsection}{straight}; gültige Klassennamen sind nur top, page und straight, alles andere führt zu Package titlesec Error: Unknown sectioning class. \assignpagestyle{\chapter}{plain} legt den Seitenstil für die Seite fest, auf der eine bestimmte Überschrift beginnt. Und eine Notiz zum Autor: Javier Bezos ist zugleich der aktuelle Betreuer des mehrsprachigen Pakets babel und der Autor von enumitem, das Listenlayout steuert — wer einen Tag lang in LaTeX Überschriften, Listen und Sprachen einstellt, begegnet dem Code derselben Person also dreimal.