Sie sind hier

Abstand vor und nach (Unter-)Abschnittsüberschrift ändern?

Gibt es eine Möglichkeit, den Abstand vor und nach (Unter-)Abschnittsüberschriften auf elegante Weise zu ändern?

Hintergrund: Ein Verlag verlangt von mir eine definierte Anzahl an Leerzeilen vor bzw. nach Überschriften.
Für Kapitelüberschriften funktioniert das sehr schön mittels \renewcommand*{\chapterheadendvskip}{\vspace*{3\baselineskip}}¹.
Leider gibt etwas Vergleichbares für (Unter-)Abschnittsüberschriften nicht (zumindest konnte ich es in zweitägiger Internet-Suche nicht finden).
Das Paket titlesec scheint leider inkompatibel zu KOMA-Script zu sein und ich habe auch nicht das nötige Wissen, um mittels \renewcommand\section¹ in den Eingeweiden des Befehls herumzubasteln. "{-3.5ex \@plus -1ex \@minus -.2ex}¹" ist mir einfach zu kryptisch, außerdem brauche ich die Abstände in Zeilen, nicht in ex¹...
Bin dankbar für jede Hilfe!

[Admin-Edit:]

  1. <code></code> Tags eingefügt (siehe Formatierungshinweise)

Bild von Markus Kohm

Da man durch unsachgemäße Änderung von (ggf. auch einzelnen) Abständen zu leicht das ganze Dokument versauen kann, war das in KOMA-Script vor Version 3.15 nicht vorgesehen. Es blieb daher nur die Verwendung eines Zusatzpakets wie beispielsweise das genannte titlesec, mit dem Nachteil, dass dann diverse KOMA-Script-Möglichkeiten nicht mehr zur Verfügung stehen, weil diese Pakete üblicherweise sehr tief eingreifen.

Abstände in Zeilen ohne glue (also ohne \@plus und \@minus) waren dabei übrigens machbar, indem man die entsprechenden Abstände beispielsweise als -5\baselineskip statt als -3.5ex angibt. Als Quelle für die Umdefinierung sollte man aber nicht irgendwelche Angaben aus dem Internet verwenden, sondern die Original-Definitionen aus der verwendeten KOMA-Script-Klasse, etwa (Achtung, dieser Code ist inzwischen veraltet!):

\makeatletter
% Warnen, falls die vorgefundene Originaldefinition nicht
% der erwarteten Originaldefinition entspricht:
\CheckCommand{\subsection}{\@startsection{subsection}{2}{\z@}%
  {-3.25ex\@plus -1ex \@minus -.2ex}%
  {1.5ex \@plus .2ex}%
  {\ifnum \scr@compatibility>\@nameuse{scr@v@2.96}\relax
    \setlength{\parfillskip}{\z@ plus 1fil}\fi
    \raggedsection\normalfont\sectfont\nobreak\size@subsection
  }%
}
% Definition ändern:
\renewcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
  {-2\baselineskip}%
  {\baselineskip}%
  {\ifnum \scr@compatibility>\@nameuse{scr@v@2.96}\relax
    \setlength{\parfillskip}{\z@ plus 1fil}\fi
    \raggedsection\normalfont\sectfont\nobreak\size@subsection
  }%
}
\makeatother

Min. seit KOMA-Script 3.14 gibt obiger Code dabei eine Warnung aus:

LaTeX Warning: Command \subsection  has changed.
               Check if current package is valid.

Seit KOMA-Script 3.15 gibt es u. a. die Anweisung \RedeclareSectionCommand, über die man auch die Abstände leicht ändern kann:

\documentclass{scrartcl}
\usepackage{mwe}
 
\RedeclareSectionCommand[%
  beforeskip=-2\baselineskip,
  afterskip=\baselineskip
]{subsection}
 
\begin{document}
\blinddocument
\end{document}

Danke für die schnelle und detaillierte Antwort!
Ich habe es gleich ausprobiert (sowohl section als aus subsection umdefiniert), aber das Ergebnis sah tatsächlich etwas seltsam aus.
Ich werde einfach die KOMA-Script-Einstellungen verwenden.

Trotzdem der Neugier halber noch zwei Fragen:¹

  1. Wie funktioniert der glue?
  2. Kann man \baselineskip² in ex² umrechnen, wenn man die Standardschriftgröße kennt?

[Admin-Edit:]

  1. <ol> </ol> und <li> </li> Tags eingefügt (siehe Formatierungshinweise)
  2. <code></code> Tags eingefügt (siehe Formatierungshinweise)

Bild von Markus Kohm

Wenn eine Seite vertikal ausgeglichen wird, worunter man versteht, dass die erste Zeile und die letzte Zeile auf allen Seiten an derselben vertikalen Position stehen, dann müssen vertikale Abstände variabel definiert sein. Bei Überschriften ist das beispielsweise deshalb so, weil sie in einer anderen Schriftgröße und damit einem anderen Zeilenabstand gesetzt werden. Nun könnte man zwar vorab die Abstände vor und nach Überschriften so wählen, dass eine Zeile Überschrift in größerer Schrift + Abstand davon + Abstand danach ein Vielfaches einer Zeile in der Grundschriftgröße sind. Wenn dann aber die Überschrift eben nicht aus einer, sondern aus zwei, drei oder sogar vier Zeilen besteht, dann passt das auch wieder nicht.

Um nun also einen Abstand variabel zu definieren, fügt man glue ein. Dazu kann man bei einem Abstand angeben, dass er ggf. vergrößert oder verkleinert werden darf. Den Betrag, um den er vergrößert werden darf, gibt man mit plus, den Betrag, um den er verkleinert werden darf, gibt man mit minus an. Im LaTeX-Kern wird dafür dann \@plus und \@minus definiert. Man merke sich schlicht, dass das das gleiche ist.

Hinweis: Erschwerend kommt noch hinzu, dass Vergrößerung und Verkleinerung auch negativ sein dürfen. Wer ganz genau wissen will, wie das funktioniert, muss sich das TeXbook besorgen und es dort nachlesen.

BTW: TeX unterscheidet zwischen Abständen (skip-Register) und Ausdehnungen (dimension-Register). Abstände können Leim enthalten, während Ausdehungen nie Leim enthalten. Das ist beispielsweise bei Zuweisungen wichtig. LaTeX fordert mit \newlength immer neue Abstände an, basiert also auf skip-Registern. Einem Abstand kann in einer Wert-Zuweisung nur einmal plus- oder minus-Leim zugewiesen werden. Während also folgendes funktioniert:

\newlength{\LEins}\newlength{LZwei}%
\setlength{\LEins}{1pt}%
\setlength{\LZwei}{\LEins plus 2pt}%
\setlength{\LEins}{\LZwei minus 3pt}%

wird die darauffolgende Anweisung

\setlength{\LZwei}{\LEins plus 4pt minus 5pt}%

nicht mehr funktionieren. Das liegt schlicht daran, weil dies

\setlength{\LZwei}{1pt plus 2pt minus 3pt plus 4pt minus 5pt}%

entsprechen würde und das eben nicht zulässig ist.

Da nun \baselineskip ebenfalls bereits Leim (plus- und minus-Anteile) enthalten kann, kann man nicht einfach mal eben \baselineskip zusätzlich noch mit einem plus- und minus-Anteil versehen.

Deine andere Frage: Du brauchst \baselineskip nicht in ex umzurechnen. A-Priori ist das ohnehin nur dann möglich, wenn man sowohl die verwendete Schrift, als auch die verwendete Schriftgröße als auch den gewählten Durchschuss kennt. Das liegt daran, dass \baselineskip von der gewählten Schriftgröße und dem gewählten Durchschuss abhängt, während 1ex eine Designgröße jedes einzelnen Fonts ist. Font verstehe ich hier als eine tfm-Datei = eine Entwurfsgröße einer Schrift.

Die aktuelle Größe von \baselineskip kann man sich mit \the\baselineskip in pt in die Log-Datei schreiben lassen. Die aktuelle Größe von 1ex kann man sich auf Umwegen in pt in die Log-Datei schreiben lassen:

\newlength{\MeineMessLaenge}% in die Präambel
\setlength{\MeineMessLaenge}{1ex}\showthe\MeineMessLaenge% irgendwo

Um den Leim aus einem Abstand zu entfernen, muss man den Abstand einer Ausdehnung zuweisen und wieder zurück. Ausgehend von obigem ersten Beispiel:

\showthe\LZwei
\newdimen\DZwei
\setlength{\DZwei}{\LZwei}%
\setlength{\LZwei}{\DZwei}%
\showthe\LZwei

Innerhalb des Argument von \@startsection kann man diesen Trick natürlich nicht anwenden, weil das Argument ja direkt als Länge verwendet wird. Man müsste das also stattdessen eher so machen:

% Wir brauchen eine Hilfslänge
\newdimen\HilfsLaenge
% Definition ändern:
\renewcommand{\subsection}{%
  \setlength{\HilfsLaenge}{\baselineskip}%
  \@startsection{subsection}{2}{\z@}%
  {-2\HilfsLaenge plus .5\HilfsLaenge minus .5\HilfsLaenge}%
  {\HilfsLaenge plus .25\HilfsLaenge minus .25\HilfsLaenge}%
  {\ifnum \scr@compatibility>\@nameuse{scr@v@2.96}\relax
    \setlength{\parfillskip}{\z@ plus 1fil}\fi
    \raggedsection\normalfont\sectfont\nobreak\size@subsection
  }%
}

Dabei wir die Hilfslänge vor dem Aufruf von \@startsection als Ausdehnung, also als Wert ohne glue bestimmt. Deshalb kann die Ausdehnung dann auch mit glue verwendet werden.

Diese Berechnung vor dem Aufruf von \@startsection funktioniert aber nur, solange man mit vertikalen Abständen arbeitet. Bei horizontalen Abständen wird das nicht funktionieren, weil diese in der Schrift aus dem 6. Argument gesetzt werden sollen. Wie wir wissen, ändert sich \baselineskip mit der Schriftumschaltung aber. Also müsste man in dem Fall die Berechnung der Hilfslänge am Ende mit in das 6. Argument packen. Das wiederum würde für die vertikalen Abstände aber nicht funktionieren. Alles ein wenig sehr unübersichtlich …

Seit KOMA-Script 3.15 geht das aber unter Verwendung von beispielsweise \RedeclareSectionCommand ebenfalls deutlich einfacher. Dort kann man nämlich nicht nur glue expressions verwenden, wie sie in der e-TeX-Anleitung erklärt sind:

\documentclass{scrartcl}
\usepackage{mwe}
 
\RedeclareSectionCommand[%
  beforeskip=\glueexpr -2\baselineskip - 0pt plus .5\baselineskip minus .5\baselineskip,
  afterskip=\glueexpr \baselineskip + 0pt plus .25\baselineskip minus .25\baselineskip
]{subsection}
 
\begin{document}
\blinddocument
\end{document}

Aufgrund einiger Seltsamheiten bei der Behandlung von glue funktioniert sogar:

\documentclass{scrartcl}
\usepackage{mwe}
 
\RedeclareSectionCommand[%
  beforeskip=-2\baselineskip plus -.5\baselineskip minus -.5\baselineskip,
  afterskip=1\baselineskip plus .25\baselineskip minus .25\baselineskip,
]{subsection}
\begin{document}
\blinddocument
\end{document}

Wobei der Faktor 1 vor dem \baselineskip in der zweiten Zuweisung zwingend ist! Das hat etwas mit TeX's Behandlung von dimensions oder glue mit Faktor zu tun. Das muss man als normaler Anwender nicht wissen und als Paketautor muss man sich nicht schämen, wenn nur langsam dämmert, was da passiert.

Und ja, den Trick könnte man prinzipiell auch für die Umdefinierung über \@startsection verwenden. Da diese aber ohnehin überholt ist, habe ich wenig Lust, die entsprechenden Ausführungen auch noch zu überarbeiten.

Zum Schluss der Hinweis: Wenn es seltsam aussieht, liegt das nicht an der Einheit, in der die Abstände angegeben werden, sondern nur daran, welche Werte angegeben werden. Gute Werte sind nicht so einfach aus dem Ärmel zu schütteln. Das ist eben der Grund, warum es dafür keine einfache Schnittstelle in KOMA-Script gibt, obwohl ich immer mal wieder überlegt habe, ob ich die einbauen sollte.

Die Chronologie erschloss sich leider nicht gleich.
Eine elegantere Loesung scheint es also scheinbar nicht zu geben.

Bild von Markus Kohm

Die Verwendung von \RedeclareSectionCommand ist eine sehr elegante Möglichkeit.

Comments for "Abstand vor und nach (Unter-)Abschnittsüberschrift ändern?" abonnieren