Menu

HowTo_ChapterWithLines

Wie eine horizontale Linie über und unter Kapitelüberschriften gesetzt werden kann

Eine Anforderung, die man recht häufig findet ist, Kapitelüberschriften mit horizontalen Linien zu versehen. Hierfür bieten die KOMA-Script-Klassen scrbook und scrreprt verschiedene Lösungsmöglichkeiten. Eine seit über zwanzig Jahren verfügbare Möglichkeit besteht darin, die Anweisungen \chapterheadstartvskip und \chapterheadendvskip umzudefinieren:

\documentclass{scrbook}
\usepackage{blindtext}
\usepackage{xpatch}
\xapptocmd{\chapterheadstartvskip}{%
  {%
    \setlength{\parskip}{0pt}%
    \setlength{\parfillskip}{0pt plus 1fil}%
    \noindent\rule[.3\baselineskip]{\linewidth}{1pt}\par
  }\nobreak
}{%
  \typeout{Horizontal line before chapter heading added.}%
}{%
  \errmessage{Failed to patch \string\chapterheadstartvskip}%
}%
\xpretocmd{\chapterheadendvskip}{%
  {%
    \setlength{\parskip}{0pt}%
    \setlength{\parfillskip}{0pt plus 1fil}%
    \noindent\rule[-.3\baselineskip]{\linewidth}{1pt}\par
  }\nobreak
}{%
  \typeout{Horizontal line after chapter heading added.}%
}{%
  \errmessage{Failed to patch \string\chapterheadendvskip}%
}%
\begin{document}
\tableofcontents
\blinddocument
\end{document}

Seite 1 und 3 des Beispiels

Normalerweise werden die beiden Anweisungen verwendet, um den vertikalen Abstand vor und nach der Kapitelüberschrift auszugeben. Hier wird nach der Ausgabe des oberen Abstandes in \chapterheadstartvskip und vor der Ausgabe des unteren Abstandes in \chapterheadendvskip mit Hilfe des Paket xpatch die Ausgabe einer Linie in die beiden Anweisungen gepatcht. Da zu diesem Zeitpunkt noch die Dokumenteinstellungen für \parindent, \parskip und \parfillskip gelten, die Linie jedoch über die gesamte Breite gesetzt werden soll, muss innerhalb einer lokalen Gruppe zumindest \parskip und \parfillskip kurzzeitig angepasst und ein etwaiger Einzug mit \noindent verhindert werden.

Die Methode funktioniert sowohl für nummerierte als auch nicht nummerierte Überschriften. Sie würde auch bei Verwendung von Option chapterprefix funktionieren und dann die obere Linie noch über der Präfixzeile einfügen.

Nachteil dieser Methode ist, dass jeder Aufruf von \DeclareSectionCommand oder \RedeclareSectionCommand zur Konfigurierung von \chapter die Änderung zunichte macht, weil dabei \chapterheadstartvskip und \chapterheadendvskip wieder auf die Standarddefinition zurückgesetzt werden.

Seit KOMA-Script 3.19 gibt es jedoch mit den Befehlen \chapterlinesformat und \chapterlineswithprefixformat eine weitere, bessere Möglichkeit:

\documentclass{scrbook}
\usepackage{blindtext}
\makeatletter% because of using \@hangfrom
\renewcommand*{\chapterlinesformat}[3]{%
  \Ifstr{#1}{chapter}{%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
  }{}%
  \@hangfrom{#2}{#3}%
  \Ifstr{#1}{chapter}{%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
  }{}%
}
\renewcommand*{\chapterlineswithprefixformat}[3]{%
  \Ifstr{#1}{chapter}{%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
  }{}%
  #2#3%
  \Ifstr{#1}{chapter}{%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
  }{}%
}
\makeatother% because of \makeatletter
\begin{document}
\tableofcontents
\blinddocument
\end{document}

Seite 1 und 3 des Beispiels

Hierbei werden die Linien direkt in der Ausgabe der Überschrift eingefügt. Über \Ifstr wird die Änderung auf Kapitelüberschriften beschränkt. Im konkreten Beispiel wäre diese Einschränkung nicht notwendig, da allein die Kapitelüberschriften im Gliederungsstil chapter gesetzt werden. Die Einschränkung wurde nur für den Fall vorgenommen, dass der Anwender weitere Gliederungsüberschriften in diesem Stil definiert.

Eine Änderung von \parskip und \parfillskip bzw. eine Verhinderung des Absatzeinzugs ist nicht notwendig, weil hier bereits der Kontext der Überschrift aktiv ist. In diesem gibt es weder einen Absatzabstand noch einen Absatzeinzug und die letzte Zeile eines Absatzes darf auch komplett gefüllt sein.

Auch diese Lösung funktioniert sowohl mit nummerierten als auch nicht nummerierten Kapitelüberschriften. Die Neudefinition von \chapterlineswithprefixformat wurde außerdem für den Fall vorgenommen, dass Option chapterprefix verwendet wird. In diesem Fall erscheint die obere Linie noch über der Präfixzeile. Häufig wird jedoch gewünscht, dass die Linie erst unter der Präfixzeile steht. Nicht selten wird dies damit kombiniert, dass die Präfixzeile rechtsbündig statt linksbündig sein soll und die komplette Überschrift in Großbuchstaben gesetzt werden soll. All dies ist durch passende Umdefinierung von \chapterformat und \chapterlineswithprefixformat problemlos möglich:

\documentclass[chapterprefix]{scrbook}
\usepackage{microtype}
\usepackage{blindtext}
\makeatletter% because of using \@hangfrom
\renewcommand*{\chapterlinesformat}[3]{%
  \Ifstr{#1}{chapter}{%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
  }{}%
  \@hangfrom{#2}{#3}%
  \Ifstr{#1}{chapter}{%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
  }{}%
}
\renewcommand*{\chapterformat}{%
  \IfUsePrefixLine{%
    \textls{\MakeUppercase{\chapapp\nobreakspace\thechapter\autodot}}%
  }{%
    \thechapter\autodot\endskip
  }%
}
\renewcommand*{\chapterlineswithprefixformat}[3]{%
  \Ifstr{#1}{chapter}{%
    \raggedleft
    #2%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
    \raggedchapter
    \textls{\MakeUppercase{#3}}%
    \rule[.3\baselineskip]{\linewidth}{1pt}\par\nobreak
  }{#2#3}%
}
\makeatother% because of \makeatletter
\begin{document}
\tableofcontents
\blinddocument
\end{document}

Seite 1 und 3 des Beispiels

Das Paket microtype wird im Beispiel verwendet, um mit \textls eine automatische Sperrung der Großbuchstaben zu erreichen. Dies ist die einzige mir bekannte Möglichkeit, die im Versalsatz notwendige Sperrung mit Ausgleich zumindest halbwegs gut automatisch zu erreichen. Wie gut die Möglichkeit funktioniert, hängt allerdings sehr stark von der verwendeten Schrift ab. Daher sehe ich automatischen Versalsatz grundsätzlich kritisch.

Vorteil der Umdefinierung von \chapterformat und \chapterlinesformat bzw. \chapterlineswithprefixformat ist, dass die Änderung Bestand hat, wenn Kapitelüberschriften mit \RedeclareSectionCommand umkonfiguriert werden. So ist es beispielsweise möglich, den Abstand zwischen der Präfixzeile und der Linie über die Option innerskip zu verändern.

Bei der Adaption dieser Lösung für Abschnitt ist zu beachten, dass \sectionlinesformat vier statt drei Argumente besitzt. Näheres ist Teil II der KOMA-Script-Anleitung oder des KOMA-Script-Buchs zu entnehmen.

Wie die obere Linie die Kapitelnummer schneiden kann

Als Erweiterung kann man sich auch vorstellen, dass die Kapitelnummer farblich hinterlegt so auf die obere der beiden Linien gesetzt werden soll, dass die Linie den Kasten mit der Kapitelnummer noch schneidet. Für Kapitelüberschriften ohne Nummer sind dabei zwei unterschiedliche Varianten denkbar:

  1. Der Kasten für die Nummer bleibt, es wird nur keine Nummer ausgegeben.
  2. Der Kasten für die Nummer entfällt.

Es mag verblüffen, dass ausgerechnet die erste Variante die einfachere ist:

\documentclass{scrbook}
%\usepackage{microtype}

\usepackage{xcolor}

\renewcommand*{\chapterformat}{\thechapter}
\renewcommand*{\raggedchapter}{\raggedleft}
\setkomafont{chapter}{\LARGE}
\setkomafont{chapterprefix}{\Huge}
\newcommand*{\ChapterCase}[1]{#1}
%\newcommand*{\ChapterCase}[1]{\MakeUppercase{#1}}% grauenvoll / ugly
%\newcommand*{\ChapterCase}[1]{\MakeUppercase{\textls[75]{#1}}}% besser / better
\renewcommand*{\chapterlinesformat}[3]{% #1 = Ebenenname / chapter command name
                                       % #2 = Nummer (oder leer) / number (or empty)
                                       % #3 = Text / text
  \rule[-\dp\strutbox]{\linewidth}{.4pt}%
  \IfArgIsEmpty{#2}{%
    \parbox[c][\dimexpr 1.5em+2\fboxsep]{0pt}{}\par\kern\fboxsep
  }{%
    \makebox[0pt][l]{%
      \hspace{-\linewidth}\hspace{.5em}%
      \colorbox{black}{%
        \parbox[c][1.5em][c]{1.5em}{%
          \centering
          \textcolor{white}{%
            \usekomafont{chapterprefix}{%
              \strut #2%
            }%
          }%
          \par
        }%
      }%
    }%
  }\par
  \ChapterCase{\strut\ignorespaces #3}%
  \rule[.5em]{\linewidth}{.4pt}\par\nobreak
}

\usepackage{mwe}

\begin{document}

\tableofcontents
\blinddocument

\end{document}

Seite 1 und 3 des Beispiels

In dem Beispiel wird übrigens zweimal \strut verwenden, damit die Höhe und Tiefe der Ausgabe unabhängig vom konkreten Text bzw. der konkreten Nummer immer gleich ist. Bei \strut handelt es sich um eine vertikale Linie der Breite Null und der Standardhöhe und Tiefe einer Zeile. Im Unterschied dazu können einzelne Zeichen abhängig von ihrer Form weniger hoch oder tief sein. Man spricht bei \strut auch von einer unsichtbaren Stütze.

Bei der zweiten Variante muss man hingegen berücksichtigen, dass normalerweise der Kasten mit der Nummer Auswirkungen auf die vertikale Position der Überschrift selbst hat. Will man also die Position derselben festnageln, so muss man den Platz für den Kasten trotzdem belegen. Eine mögliche Lösung wäre:

\documentclass{scrbook}
%\usepackage{microtype}

\usepackage{xcolor}

\renewcommand*{\chapterformat}{\thechapter}
\renewcommand*{\raggedchapter}{\raggedleft}
\setkomafont{chapter}{\LARGE}
\setkomafont{chapterprefix}{\Huge}
\newcommand*{\ChapterCase}[1]{#1}
%\newcommand*{\ChapterCase}[1]{\MakeUppercase{#1}}% grauenvoll / ugly
%\newcommand*{\ChapterCase}[1]{\MakeUppercase{\textls[75]{#1}}}% besser / better
\renewcommand*{\chapterlinesformat}[3]{% #1 = Ebenenname / chapter command name
                                       % #2 = Nummer (oder leer) / number (or empty)
                                       % #3 = Text / text
  \rule[-\dp\strutbox]{\linewidth}{.4pt}%
  \IfArgIsEmpty{#2}{%
    \parbox[c][\dimexpr 1.5em+2\fboxsep]{0pt}{}\par\kern\fboxsep
  }{%
    \makebox[0pt][l]{%
      \hspace{-\linewidth}\hspace{.5em}%
      \colorbox{black}{%
        \parbox[c][1.5em][c]{1.5em}{%
          \centering
          \textcolor{white}{%
            \usekomafont{chapterprefix}{%
              \strut #2%
            }%
          }%
          \par
        }%
      }%
    }%
  }\par
  \ChapterCase{\strut\ignorespaces #3}%
  \rule[.5em]{\linewidth}{.4pt}\par\nobreak
}

\usepackage{mwe}

\begin{document}

\tableofcontents
\blinddocument

\end{document}

Seite 1 und 3 des Beispiels

Eine im Endeffekt wesentlich einfachere Methode besteht in der Verwendung von \vphantom. Die Anweisung tut in der Vertikalen so, als wäre das entsprechende Material vorhanden, ohne es tatsächlich auszugeben. Damit der Inhalt nicht einmal für den Fall der Nummerierung und einmal für den gegenteiligen Fall angegeben werden muss, kann man ihn zunächst einfach in eine Box packen und dabei ignorieren, dass die Nummer eventuell leer ist:

\documentclass{scrbook}
%\usepackage{microtype}

\usepackage{xcolor}

\renewcommand*{\chapterformat}{\thechapter}
\renewcommand*{\raggedchapter}{\raggedleft}
\setkomafont{chapter}{\LARGE}
\setkomafont{chapterprefix}{\Huge}
\newcommand*{\ChapterCase}[1]{#1}
%\newcommand*{\ChapterCase}[1]{\MakeUppercase{#1}}% grauenvoll / ugly
%\newcommand*{\ChapterCase}[1]{\MakeUppercase{\textls[75]{#1}}}% besser / better
\newsavebox\chapternumberbox
\renewcommand*{\chapterlinesformat}[3]{% #1 = Ebenenname / chapter command name
                                       % #2 = Nummer (oder leer) / number (or empty)
                                       % #3 = Text / text
  \rule[-\dp\strutbox]{\linewidth}{.4pt}%
  \sbox\chapternumberbox
  {%
    \makebox[0pt][l]{%
      \hspace{-\linewidth}\hspace{.5em}%
      \colorbox{black}{%
        \parbox[c][1.5em][c]{1.5em}{%
          \centering
          \textcolor{white}{%
            \usekomafont{chapterprefix}{%
              \strut #2%
            }%
          }%
          \par
        }%
      }%
    }%
  }%
  \IfArgIsEmpty{#2}{%
    \vphantom{\usebox\chapternumberbox}%
  }{\usebox\chapternumberbox}%
  \par
  \ChapterCase{\strut\ignorespaces #3}%
  \rule[.5em]{\linewidth}{.4pt}\par
}
\makeatother
\usepackage{mwe}

\begin{document}

\tableofcontents
\blinddocument

\end{document}

Seite 1 und 3 des Beispiels

Ich habe in den Beispielen bewusst die Ausrichtung der Überschrift, die Wahl des Fonts und ähnliche Dinge nicht fest in die Definition von \chapterlinesformat eingebaut, damit man dergleichen Dinge leicht ändern kann. Desweiteren habe ich für die Groß-/Kleinschreibung der Überschrift drei Varianten vorgestellt. Die erste ist diejenige, die ich wählen würde. Die zweite mit ungesperrten Versalien ist diejenige, die ich keinem empfehlen würde. Die dritte nutzt das Paket microtype, um wenigstens ein wenig automatische Sperrung umzusetzen, die allerdings ohne korrekten Ausgleich daher kommt und deshalb fontabhängig teilweise auch nicht wesentlich besser ist.


Related

Wiki (Deutsch): HowTo_Headings

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.