Booklets erzeugen

Um ein Dokument so zu drucken, dass man nach dem Drucken daraus eine klammergeheftete Broschüre machen kann, muss man die Einzelseiten des Dokumentes nach einem ganz bestimmten Schema auf den Druckbogen anordnen, um die Seitenabfolge nicht durcheinander zu bringen. Im Beispiel von diesem Monat werden wir uns anschauen, wie man mit diesen als Ausschießen bezeichneten Vorgang automatisch erledigen kann. Dazu werden wir das Paket pdfpages verwenden und außerdem mit 3 eine eigene Lösung programmieren, die anders als pdfpages auch den sog. Bundzuwachs berücksichtigen kann.

Gewinnspiel

Mein Blog feiert seinen ersten Geburtstag und für die Leser gibt’s Geschenke!

Die Gewinne – 1. „LaTeX Hacks“, 2. „Erste Hilfe in Typografie“, 3. „Grau wie unser Hund“

Zum Einjährigen verlose ich diese drei Bücher:

Das Gewinnspiel ist beendet!

Der einzige Teilnehmer und damit glückliche Gewinner der „ Hacks“ ist Michel Döring. Herzlichen Glückwunsch!

Einleitung

Um aus einem Dokument eine Broschüre zu erstellen, muss man die Einzelseiten nach einem bestimmten Schema ausschießen und auf den Druckbogen verteilen. Im einfachsten Fall – und nur mit dem wollen wir uns hier beschäftigen – werden die Druckbogen nach dem Druck in der Mitte geheftet und gefalzt und die Broschüre anschließend ggf. noch beschnitten, damit saubere Kanten entstehen. Auf jedem Druckbogen erscheinen dann je vier Dokumentseiten.

Ausschießen

Das Ausschießen erfolgt so: Ist die Seitenzahl des Dokumentes nicht durch vier teilbar, müssen zunächst ein bis drei Leerseiten angehängt werden. Dann werden auf der Vorderseite des ersten Druckbogens die erste und die letzte Dokumentseite nebeneinander angeordnet; auf der Rückseite des Bogens erscheinen die zweite und die vorletzte Dokumentseite. Auf dem nächsten Druckbogen vorderseitig dann die dritte und dritt-letzte Dokumentseite und rückseitig die vierte und die viert-letzte. Die weiteren Druckbögen werden analog aufgebaut, bis alle Dokumentseiten verteilt sind und sich auf der Rückseite des letzten Druckbogens die beiden mittleren Dokumentseiten treffen.

Je nachdem, ob der Bogen beim Drucken über die lange oder die kurze Seite gewendet wird (bei Office-Druckern häufig als „Binden über kurze/lange Kante“ o. ä. bezeichnet), müssen die Vorder- und Rückseite des Bogens evtl. um 180° gegeneinander verdreht werden. Die folgende Abbildung zeigt das Schema für eine 16-seitige Broschüre für beide Fälle. Die jeweiligen Rückseiten sind in der Abbildung grau dargestellt und „umgeklappt“ um sie sichtbar zu machen.

Ausschießschema für eine 16-seitige Broschüre

Nach dem Drucken werden die Bogen entlang der gestrichelten Linie gefalzt, ineinander gelegt (der 4. in den 3., diese in den 2. usw.), geheftet und ggf. beschnitten. In der rechten Spalte sieht man gut, wie die Seiten beim Ausschießen gleichzeitig vom Anfang (aufsteigen gezählt) und vom Ende (absteigen gezählt) des Dokumentes genommen werden und sich nur die beiden mittleren Seiten – hier 8 und 9 – auch auf dem Druckbogen nebeneinander stehen.

Bundzuwachs

Durch die Papierdicke kommt es beim Ineinanderlegen zu einer Verschiebung/Verdrängung der inneren Seiten: dem sog. Bundzuwachs (BZW). Die folgende Abbildung zeigt, dass dadurch von den inneren Seiten beim Schneiden mehr abgeschnitten wird, als von den äußeren.

Bundzuwachs – Beim Schneiden werden die inneren Seiten stärker beschnitten als die äußeren.

Um dem entgegen zu wirken, muss der Inhalt der inneren Seiten beim Ausschießen leicht nach innen verschoben werden bzw. das ganze Layout entsprechend angepasst werden. Ob man den Bundzuwachs in der Praxis berücksichtigen muss und wie groß dieser ist, hängt von der Seitenzahl und der Papierdicke ab. Mit dieser Formel kann der Bundzuwachs berechnet werden:

BZW = (Seitenzahl inkl. Umschlag – 4) ÷ 4 × Papierdicke
BZW = (Bogenzahl – 1) × Papierdicke

Die genaue Verschiebung v einer Einzelseite hängt dann davon ab, auf welchem Bogen sie steht:

v = BZW ÷ (Bogenzahl – 1) × (Bogennummer – 1)
v = Papierdicke × (Bogennummer – 1)

Datei einzelseiten.tex

Bevor wir richtig beginnen können, erzeugen wir uns mit dieser Datei ein Testdokument, das wir dann zu einer Broschüre machen werden.

Für unser Testdokument benutzen wir die Klasse scrartcl (FAQ 2) und laden sie mit der Option a5paper, um ein Dokument im Format DIN A5 zu erzeugen, und mit der Einstellung DIV=10, für kleine Seitenränder (siehe dazu den Beitrag Layout I: Seitengröße und ‑ränder).

\documentclass[
   a5paper,
   DIV = 10,
]{scrartcl}
\usepackage{lmodern}

tikz mit der calc-Bibliothek benötigen wir um auf den Testseiten Linien anzubringen, mit denen wir später die Korrektur des Bundzuwachs überprüfen können.

\usepackage{tikz}
\usetikzlibrary{calc}

Wir schalten den Seitenstil auf empty, um die Fußzeile auszublenden (siehe auch den Beitrag Layout II: Kopf- und Fußzeilen).

\pagestyle{empty}

Wir stellen die Textausrichtung im Dokument auf zentriert und die Schrift auf Schreibmaschinenschrift (\ttfamily), Schriftgröße 250 pt (\fontsize{250pt}{250pt}\selectfont; FAQ 8) und Fettdruck (\bfseries)

\centering
\ttfamily
\fontsize{250pt}{250pt}\selectfont
\bfseries

Nun durchlaufen wir mit \foreach (gehört auch zu TikZ) eine Schleife über die Zahlen 1, 2, …, 16, um die Testseiten zu erzeugen. Die Gesamtseitenzahl – hier 16 – können wir dabei beliebig ändern.

\foreach \n in {1,...,16} {%

Mit jedem Schleifendurchlauf beginnen wir eine neue Seite und geben dann die aktuelle Seitenzahl (hier sind Zähler der Schleife \n und die tatsächliche Seitenzahl \thepage identisch)

   \clearpage
   \n

Nun fügen wir noch ein TikZ-Bild ein: mit der Option remember picture erhalten wir Zugriff auf den Seiten-Node, mit overlay geben wir an, dass das Bild sich über die Seite legt, ohne aus ’s Sicht Platz einzunehmen und mit x/y legen wir die Basisvektoren des Bildes fest. Dann zeichnen wir in jede Ecke der Seite ein 10 mm großes Quadrat sowie an die linke und rechte Seitenkante jeweils 11 Linien mit 1 mm Abstand. (Mehr über die Funktionen TikZ erfahren sie bspw. im Beitrag TikZ-Adventskalender und in der hervorragenden Paketdokumentation.)

   \begin{tikzpicture}[remember picture, overlay, x=1mm, y=1mm]
      \fill [cyan] (current page.north east) rectangle ++(-10,-10);
      \fill [green!40!yellow] (current page.north west) rectangle ++(10,-10);
      \fill [cyan] (current page.south east) rectangle ++(-10,10);
      \fill [green!40!yellow] (current page.south west) rectangle ++(10,10);
      \foreach \x in {0,...,10} {
         \draw [blue, dash pattern=on 1mm off 1mm]
            ($(current page.north east)+(-\x,0)$)
            -- ($(current page.south east)+(-\x,0)$);
         \draw [green!75!black, dash pattern=on 1mm off 1mm, dash phase = 1mm]
            ($(current page.north west)+(\x,0)$)
            -- ($(current page.south west)+(\x,0)$);
      }
   \end{tikzpicture}%

Ende der \foreach-Schleife

}
\end{document}

Hinweis: Damit die Rechtecke und Linien korrekt positioniert werden, muss das Dokument zwei Mal kompiliert werden.

Datei booklet-mit-pdfpages.tex

Mit pdfpages ein Booklet zu erzeugen ist erfreulich einfach, denn das Paket hat alles was wir brauchen schon „eingebaut“ – zumindest wenn wir keinen Bundzuwachs berücksichtigen müssen/wollen.

Obwohl es im Grunde relativ egal ist, verwenden wir auch hier eine KOMA-Script-klasse, weil wir das Papierformat dann sehr bequem einstellen können. Wichtig ist nämlich, dass das Format der Druckbogen so groß ist, dass es zwei Einzelseiten aufnehmen kann (DIN A4 wäre einen Millimeter zu groß). Das Format geben wir mit der Option paper=Breite:Höhe an.

\documentclass[
   paper=296mm:210mm,
]{scrartcl}
\usepackage{pdfpages}
\begin{document}

Wie versprochen ist es sehr einfach, eine Broschüre zu erzeugen: Dem Befehl \includepdf geben wir mit pages den zu verwendenden Seitenbereich an, wobei - „alle Seiten“ bedeutet (1-8 wären bspw. die ersten acht Seiten), und mit booklet, dass die Seiten als Booklet ausgeschossen werden sollen. Das obligatorische Argument ist der Dateiname der Einzelseiten-PDF.

Passen Druckbogen- und Seitenformat nicht zusammen, werden die Einzelseiten skaliert.

\includepdf[pages=-,booklet]{einzelseiten}
\end{document}

Mit diesen paar Zeilen erzeugen wir eine Broschüre, die beim Drucken über die lange Kante gewendet werden muss. Das Paket bietet keine Möglichkeit, die Druckbogen so auszurichten, dass über die kurze Kante gewendet werden kann. Dennoch gibt es auch dafür eine Lösung: pdfpages rotate odd pages 180° auf TeX.SX.

Datei booklet-mit-latex3.tex

Nun wird es etwas komplizierter … wir wollen jetzt mit 3 eine eigene Lösung programmieren, die den Bundzuwachs berücksichtigt. Die Grundlagen von 3 können Sie im Beitrag Musikalische Funktionssymbole mit 3 nachlesen.

Zielstellung

\MakeBooklet[Verschiebung]{Dateiname}

der eine Datei ausschießt und dabei den Bundzuwachs berücksichtigt: Wir wollen die Verschiebung v pro Bogen (siehe Gleichung oben) im optionalen Argument angeben können. Der Dateiname soll immer ohne Endung angegeben werden.

Die Seiten sollen hier so ausgegeben werden, dass der Druckbogen über die kurze Seite gewendet wird.

Herangehensweise

Um die Druckbogen zusammenszustellen werden wir eine Schleife implementieren, die solange läuft, bis alle Seiten im Einzelseiten-PDF verarbeitet wurden. Mit jedem Schleifendruchlauf soll ein kompletter Druckbogen also zwei Druckbogenseiten (Vorder- und Rückseite) ausgegeben werden. D. h. es werden pro Schleifendruchlauf vier Einzelseiten verarbeitet.

Das Modul nennen wir booklet.

Wie im pdfpages-Beispiel nutzen wir scrartcl und geben die Druckbogengröße mit paper an.

\documentclass[
   paper=296mm:210mm,
]{scrartcl}

Das Paket xparse laden wir, um den Befehl \NewDocumentCommand nutzen zu können. Außerdem lädt es intern alle für 3 nötigen Pakete.

\usepackage{xparse}

graphicx brauchen wir zum Einbinden der Einzelseiten.

\usepackage{graphicx}

Um die Einzelseiten anzuordnen benutzen wir tikz mit der calc-Bibliothek. Außerdem stellen wir hier ein, dass alle Nodes exakt so groß sind wie ihr Inhalt (inner sep) und sie beim Ausrichten nicht von einem Rand umgeben sind (outer sep).

\usepackage{tikz}
   \usetikzlibrary{calc}
   \tikzset{
      every node/.style = {
         inner sep = 0pt,
         outer sep = 0pt,
      }
   }

Auch hier stellen wir den Seitenstil auf empty, damit die eingebundenen Seiten nicht von der voreingestellten Fußzeile überlagert werden.

\pagestyle{empty}

Ab hier gilt die 3-Syntax

\ExplSyntaxOn

Variablen

Zähler für die Anzahl der Druckbogenseiten

\int_new:N \l_booklet_sheets_int

Zähler für die Laufvariable der Schleife

\int_new:N \l_booklet_counter_int

Zähler für die Anzahl der Einzelseiten

\int_new:N \l_booklet_total_pages_int

Zähler für die Anzahl der Einzelseiten auf eine durch vier teilbare Zahl gebracht

\int_new:N \l_booklet_total_pages_to_four_int

Länge für die tatsächliche Verschiebung einer Seite

\dim_new:N \l_booklet_creep_dim

Hilfsmakro

Wir definieren ein Hilfsmakro zum Einbinden einer Seite aus der Einzelseiten-PDF: Der Befehl \booklet_get_page:nn hat zwei Argumente:

  • #1: Seitenzahl
  • #2: Dateiname

Beginn der Definition

\cs_new:Npn \booklet_get_page:nn #1#2 {

Zunächst prüfen wir, ob die Nummer der angeforderte Seite (#1) kleiner oder gleich der Gesamtseitenzahl ist.

   \int_compare:nT { ( #1 ) <= \l_booklet_total_pages_int } {

Und nur wenn das der Fall ist, binden wir die Seite ein. Dabei skalieren wir diese unter Berücksichtigung des Seitenverhältnis’ auf halbe Druckbogenbreite und ganze Druckbogenhöhe, um sicher zu gehen, das nichts abgeschnitten wird, auch wenn die Druckbogengröße einmal falsch angeben wird.

      \includegraphics [
         width = 0.5\paperwidth,
         height = \paperheight,
         keepaspectratio,
         page = #1,
      ] { #2 }

Ende der if-Abfrage

   }

Ende der Definition

}

Dadurch, dass wir prüfen, ob die geforderte Seite vorhanden ist, stellen wir sicher, dass es nicht zu einer Fehlermeldung kommt, wenn eine nicht vorhandene Seite eingefügt werden soll. Wenn wir dann später eine nicht vorhandene Seite anfordern, um den Bogen zu füllen, auch wenn die Seitenzahl der Einzelseiten nicht durch vier teilbar ist, entsteht so automatisch eine leere Seite.

Hauptmakro

Nun können wir das eigentliche Makro definieren.

\NewDocumentCommand { \MakeBooklet } { O{0mm} m } {

Als erstes prüfen wir, ob die Datei überhaupt existiert. Nur wenn das der Fall ist wird der folgende Code ausgeführt.

   \file_if_exist:nTF { #2 .pdf } {

Zunächst setzen wir die Laufvariable und die Verschiebung auf Null.

      \int_zero:N \l_booklet_counter_int
      \dim_zero:N \l_booklet_creep_dim

Dann lesen wir die Einzelseiten-PDF einmal mit \pdfximage ein, um die dann in \pdflastximagepages gespeicherte Seitenzahl in unserer eigenen Variable \l_booklet_total_pages_int zu übertragen (Quelle).

      \pdfximage { #2 .pdf }
      \int_set:Nn \l_booklet_total_pages_int
         { \the \pdflastximagepages }

Jetzt überprüfen wir mit der Modulo-Funktion \int_mod:nn, ob die Seitenzahl glatt durch vier teilbar ist. Ist das nicht der Fall ist der Modulo ungleich (!=) Null und \l_booklet_total_pages_to_four_int wird auf die nächst größere durch vier Teilbare Zahl gesetzt, in dem vier vier addieren und das Ergebnis der Modulo-Division abziehen. Wenn die Seitenzahl schon durch vier teilbar ist, kann \l_booklet_total_pages_to_four_int mit ihr gleich gesetzt werden.

      \int_compare:nTF { \int_mod:nn { \l_booklet_total_pages_int } { 4 } != 0 } {
         \int_set:Nn \l_booklet_total_pages_to_four_int
            { \l_booklet_total_pages_int + 4 - \int_mod:nn { \l_booklet_total_pages_int } { 4 } }
      } {
         \int_set_eq:NN \l_booklet_total_pages_to_four_int \l_booklet_total_pages_int
      }

Die Anzahl Druckbogenseiten berechnen wir, indem wir die Seitenzahl der Einzelseiten halbieren (es passen vier Einzelseiten auf einen Druckbogen und jeder Druckbogen besteht aus zwei Druckbogenseiten).

      \int_set:Nn \l_booklet_sheets_int
         { \l_booklet_total_pages_to_four_int / 2 }

Für das Ausschießen verwenden wir eine \int_do_while-Schleife, die solange läuft, wie die Laufvariable \l_booklet_counter_int kleiner ist als die Anzahl der zu Druckbogenseiten. (Die Laufvariable werden wir pro Druchlauf um zwei erhöhen.)

      \int_do_while:nn { \l_booklet_counter_int < \l_booklet_sheets_int } {

Wir beginnen eine neue Seite und erhöhen die Laufvariable um eins.

         \clearpage
         \int_incr:N \l_booklet_counter_int

Auf der Vorderseite des Druckbogens auf der rechten Hälfte geben wir in aufsteigender Folge die Einzelseiten aus, beginnend mit der ersten Seite im Einzelseiten-PDF (vgl. Abbildung oben). Für die Positionierung nutzen wir ein TikZ-Bild: Dieses wird mit \clip auf die linke Druckbogenhälfte beschnitten und dann wird mit \node an der Druckbogenmitte (current page.center) ausgerichtet die Seite eingelesen, wobei die Verschiebung \l_booklet_creep_dim (von der Druckbogenmitte weg) berücksichtigt wird. Im ersten Schleifendurchlauf, also auf dem ersten Druckbogen, ist diese Verschiebung noch Null; ihren Wert ändern wir am Ende der Schleife.

         \begin{tikzpicture}[remember~picture, overlay]
            \clip (current~page.north) rectangle (current~page.south~east);
            \node [anchor = west] at ($
               (current~page.center)
               -
               (\dim_use:N \l_booklet_creep_dim, 0)
            $) {
               \booklet_get_page:nn
                  { \int_use:N \l_booklet_counter_int }
                  { #2 }
            };
         \end{tikzpicture}

Analog dazu geben wir auf der linken Hälfte die Seiten in absteigender Folge beginnend mit der letzten Seite des Einzelseiten-PDFs aus.

         \begin{tikzpicture}[remember~picture, overlay]
            \clip (current~page.north~west) rectangle (current~page.south);
            \node [anchor = east] at ($
               (current~page.center)
               +
               (\dim_use:N \l_booklet_creep_dim, 0)
            $) {
               \booklet_get_page:nn
                  { \int_eval:n { \l_booklet_total_pages_to_four_int - \l_booklet_counter_int + 1 } }
                  { #2 }
            };
         \end{tikzpicture}

Nun beginnen wir wieder eine neue Seite – jetzt sind wir auf der Rückseite des Druckbogens – und erhöhen die Laufvariable erneut um eins.

         \clearpage
         \int_incr:N \l_booklet_counter_int

Auf der linken Hälfte der Druckbogenrückseite erscheint die aufsteigen gezählt nächste Seite.

        \begin{tikzpicture}[remember~picture, overlay]
           \clip (current~page.north~west) rectangle (current~page.south);
           \node [anchor = east] at ($
              (current~page.center)
              +
              (\dim_use:N \l_booklet_creep_dim, 0)
           $) {
              \booklet_get_page:nn
                 { \int_use:N \l_booklet_counter_int }
                 { #2 }
           };
        \end{tikzpicture}

Und auf der rechten Hälfte die absteigen gezählt nächste Seite.

         \begin{tikzpicture}[remember~picture, overlay]
            \clip (current~page.north) rectangle (current~page.south~east);
            \node [anchor = west] at ($
               (current~page.center)
               -
               (\dim_use:N \l_booklet_creep_dim, 0)
            $) {
               \booklet_get_page:nn
                  { \int_eval:n { \l_booklet_total_pages_to_four_int - \l_booklet_counter_int + 1 } }
                  { #2 }
            };
         \end{tikzpicture}

Auf der Vorder- und Rückseite des Druckbogens, sind also linke und rechte Hälfte gerade gegeneinander vertauscht.

Als letztes in diesem Schleifendurchlauf setzen wir die Seitenverschiebung für den nächsten Durchlauf der Schleife. Die Verschiebung berechnen wir in dem wir die Verschiebung pro Bogen (#1) mit der aktuellen, durch zwei geteilten Druckbogenseitenzahl (das entspricht Nummer des nächsten Druckbogens!) teilen.

         \dim_set:Nn \l_booklet_creep_dim {
            #1 * \l_booklet_counter_int / 2
         }

Ende der Schleife

      }

Ist die Datei nicht vorhanden, wird dieser Code ausgeführt: Wir geben eine Fehlermeldung aus.

   } {
      \Huge
      \noindent \textbf { Fehler! } \\
      Datei ~ \texttt { #2 .pdf } ~ nicht ~ gefunden.
   }

Ende der Definition

}

Ende der 3-Syntax

\ExplSyntaxOff

Tipp: Um zu verstehen, wie das Makro die Druckbogen aufbaut, hilft es die Schleife ganz konkret bspw. für ein sechzehnseitiges Dokument „zu Fuß“ durchzugehen und sich jeweils die Werte der Variablen klar zu machen bzw. zu notieren.

Makro anwenden

Jetzt können wir endlich das definierte Makro nutzen. Dabei geben wir zu Testzwecken ein unrealistisch hohe Verschiebung pro Bogen von 1 mm an.

\begin{document}
 
\MakeBooklet[1mm]{einzelseiten}
 
\end{document}

Hinweis: Damit die Einzelseiten korrekt positioniert werden, muss das Dokument zwei Mal kompiliert werden.

Anmerkung

Ja nach Layout lässt sich der Bundzuwachs nicht ohne Weiteres ausgleichen. Denn bei der eben gezeigten Lösung werden die Einzelseiten schließlich auf der zur Bindung zeigenden Seite beschnitten, der Innenrand wird also immer kleiner. Automatische Lösungen bieten folglich immer nur die Verlagerung des Problems vom Außenrand auf den Innenrand. Für komplizierte Layouts, bedeutet das mehr Handarbeit, um die inneren Seiten insgesamt zu verschmälern, ohne Innen- und Außenrand zu verändern.