Geheftet

The Answer Girl

01.02.2001
Dass der Computer-Alltag auch unter Linux des Öfteren für Überraschungen gut ist, ist eher eine Binsenweisheit: Immer wieder funktionieren Dinge nicht oder nicht so, wie eigentlich angenommen. Das Answer-Girl im LinuxUser zeigt, wie man mit solchen Problemchen elegant fertig wird.

Ausdrucke, in unseren Breiten mit schöner Langweiligkeit Seite per Seite auf je einem A4-Blatt platziert, haben im Alltag ja durchaus ihre Berechtigung. Doch wenn man der Liebsten die selbstgeschriebene Gedichtsammlung verehren möchte, dann sollte dabei doch wenigstens ein hübsches A5-Heft, doppelseitig bedruckt, heraus kommen.

Weniger romantische Gründe hat die Papiersparerin: Die 100-seitige Diplomarbeit zum Korrekturlesen auszudrucken, schont auf dem heimischen Zwei-Seiten-je-Minute-Tintenspritzer weder die Nerven (Tinte wie Papier sind teuer, von Zeit ganz zu schweigen), noch motiviert der resultierende Papierberg sonderlich zum Durcharbeiten. Psychologisch gesehen macht sich ein dünnerer Stapel besser. Ob es also Bäume, Arbeitseifer oder Nerven zu schonen gilt – mehrere logische Seiten auf einem A4-Blatt unterzubringen ist durchweg eine gute Idee.

Alles auf ein Format

Wie gut, dass mit PostScript ein einheitliches Format existiert, durch das (fast) alle Drucksachen unter Linux hindurch müssen: Als PostScript-Datei werden sie von den Applikationen an die Druckmaschinerie übergeben, und als solche kann man sie auch von Hand über den lpr-Befehl zum Inhalt eines Druckauftrags machen.

Über das berühmt-berüchtigte "Drucken in Datei" erhält man aus jeder Textverarbeitung (und natürlich auch aus anderen Applikationen wie Webbrowsern, dem von LaTeX-Schreiberlingen benutzten dvips u.a.) eine PostScript-Datei, die sich vor dem tatsächlichen Ausdruck weiter verarbeiten lässt.

Wer jetzt denkt, PostScript als Programmiersprache, das müsste doch auch "von Hand" mit einem Editor in Form zu bringen sein, der oder die hat zwar nicht unbedingt Unrecht, doch ein Blick in den PostScript-Code (z.B. mit less dateiname.ps und einem q wie "quit" zum Schließen, wenn der Schmerz nachgelassen hat) dürfte klar machen: Das ist nichts, was in einen einzigen Artikel passt.

Was wir brauchen sind also Werkzeuge, die PostScript als Eingabeformat nehmen, mehrere bisherige Seiten auf eine packen, ggf. nach unseren Vorgaben umordnen und am Ende wieder PostScript ausspucken.

Auf Werkzeugsuche

Mal sehen, ob unsere schlauen Manpages da was für uns im Angebot haben: man -k (-k wie "keyword", Schlüsselwort), das zumeist auch unter dem Namen apropos anzutreffen ist, sollte uns hier zumindest Aufschluss darüber erteilen, ob es sich überhaupt lohnt, die Aufgabe mit installierten Bordmitteln in Angriff zu nehmen.

[trish@lillegroenn answergirl]$ apropos postscript[…]
 mpage (local)        - print multiple pages per sheet on PostScript printer[…]
 pstops (1)           - shuffle pages in a PostScript file

Obwohl ein ganzer Haufen Tools sich in irgendeiner Weise mit Umwandlungen von und nach PostScript beschäftigt, bleibt nach eingehender Lektüre der Kurzbeschreibungen nicht mehr so viel übrig – und es ist nicht einmal gesagt, dass Ihre Distribution und Ihr Installationsumfang genau das ausspuckt, was Sie oben sehen.

Wie die Nachfrage beim Paketmanager ergibt, steckt pstops im Paket psutils (das die meisten Distributionen mitliefern, im Zweifelsfall ist es z.B. unter http://rpmfind.net/linux/rpm2html/search.php?query=psutils zu finden):

[trish@lillegroenn answergirl]$ rpm -q -f `which pstops`
 psutils-1.17-3

Der "Red Hat Packet Manager" nimmt Anfragen ("queries") mit der Option -q entgegen. Was wir von ihm wissen wollen, sagen wir ihm mit -f: in diesem Fall, zu welchem Paket das anschließend angegebene File gehört.

Da eine Datei nur dann eindeutig spezifiziert ist, wenn nicht nur ihr Name (pstops), sondern auch der zugehörige Verzeichnispfad angegeben wird, reicht es nicht, einfach -f pstops zu sagen. Bei im Suchpfad vorhandenen Programmen bekommt man jedoch mit which programmname heraus, wo sie zu finden sind. Schließen wir dieses Kommando in Backquotes (``) ein, so wertet es die Shell zuerst aus und setzt das Ergebnis (bei den meisten Distributionen /usr/bin/pstops) ins Querykommando ein, sodass wir tatsächlich nach rpm -q -f /usr/bin/pstops fragen.

mpage hingegen steckt zumeist in einem gleichnamigen Paket, das im Zweifel z.B. unter http://rpmfind.net/linux/rpm2html/search.php?query=mpage zu bekommen ist.

Erstmal die kleineren Brötchen

Ein kurzer Blick auf die Manpages zu pstops und mpage verspricht die Lösung für ambitionierte Heftchenherausgeber/innen zwar mit ersterem Tool, doch wirkt letzteres leichter bedienbar. Da es zudem perfekt auf die Aufgabe "Papierstapelverkleinerung durch Drucken mehrerer logischer Seiten auf einer A4-Seite" zugeschnitten scheint, lassen wir zunächst unsere Faulheit siegen.

mpage ist oft so vorkonfiguriert, dass sein Output direkt an den Defaultdrucker geht. Was später nützlich ist, wollen wir zunächst vermeiden, denn was soll die Papiersparerei, wenn wir auf dem Weg dahin massenweise Probeausdrucke produzieren? Wie es sich für ein ordentliches Unix-Filterprogramm gehört, kann mpage seine PostScript-Ausgabe über den "Pfeil" > in eine Datei umleiten.

Mit altgedienten PostScript-Anzeigeprogrammen wie gv und ghostview oder der (aus dem KDE-Dateimanager auch per Drag&Drop bedienbaren) KDE-Alternative kghostview lässt sich die so erzeugte Testdatei stets inspizieren, bevor man sie auf Papier bannt.

So ausgestattet fällt die erste mpage-Übung nicht schwer: Glaubt man der Manpage, bannt mpage -2 diplomarbeit.ps > korrektur.ps die Datei diplomarbeit.ps so auf's virtuelle Blatt, dass immer eine ungerade und die darauf folgende gerade Seite (also insgesamt 2) auf einer A4-Seite landen.

Netterweise hat mpage um jede logische Seite einen hübschen Rahmen gezogen – doch beim Ausdruck sitzt der und damit der gesamte Blattinhalt alles andere als zentriert auf der A4-Seite. Da stimmt wohl was mit dem Format nicht…

Tatsächlich kennt mpage die Option -b, hinter der ohne Leerzeichen das Papierformat angegeben werden muss. Wenn die mit mpage -x erhältliche Kurzbeschreibung des Programms mit

-b papersize: A4|Letter|Legal (default US letter)

erklärt, dass die einkompilierte Voreinstellung das "US letter"-Format ist, braucht die Verschiebung nicht wundern. Dann bleibt wohl nichts anderes übrig, als das mpage-Kommando um -ba4 anzureichern, sofern wir auf A4 ausdrucken. Gerade wenn man ohnehin unnummerierte Seiten auf Papier bannen will (wie die, die z.B. Netscape 4.x unter File/Save as... produziert, wenn man als Format for saved document PostScript auswählt), hilft ein -X, das den Namen der Datei sowie das Datum in der Kopfzeile verewigt, beim Ordnunghalten. Die Option -o wie "outlines off" schaltet den per Default erzeugten Rahmen um jede einzelne logische Seite ab.

All das lässt sich bei Netscape u.a. natürlich auch ohne das Zwischenspeichern in einer echten PostScript-Datei nutzen: Ein mpage -ba4 -X |lpr als Print Command wie im in Abbildung 1 gezeigten File/Print-Dialog druckt die angezeigte Webseite seitennummeriert und mit der Quelle stdin versehen auf A4-Papier aus, wobei – die Option -4 muss als Standardeinstellung nicht mit angegeben werden – vier logische Seiten auf einer A4-Seite landen.

Abbildung 1: Mit mpage die Druckausgabe von Netscape beeinflussen

Diese werden dabei wie in Abbildung 2 angeordnet – links, wenn Netscape die logischen Seiten im Portrait-Format, rechts in Landscape ausrichtet, bevor mpage zum Zuge kommt. Will man auf einem hochkanten Blatt oben von links nach rechts die logischen Seiten 1 und 2 sowie darunter 3 und 4 haben, muss man die mpage-Option -a einschalten.

Abbildung 2: Defaultanordnung logischer Seiten bei mpage: rechts lag das Ausgangsmaterial im Querformat vor, links im Hochformat

Der aufmerksamen Manpage-Leserin ist inzwischen natürlich längst aufgefallen, dass mpage neben weiteren spannenden Optionen auch eine beherrscht, die das "Pipen" der mpage-Ausgabe ins Druckkommando lpr (so überhaupt nötig) überflüssig macht: mpage -P druckt von sich aus auf dem Standarddrucker aus (wie erwähnt kann man dieses Flag je nach Vorkonfiguration ggf. ganz weglassen), mit -Pdruckername wird wie bei lpr ein anderer eingerichteter Drucker ausgewählt.

Doch bei aller Schwelgerei in mpage-Optionen lässt sich nicht verhehlen, dass sich Enttäuschung breit macht: Heftchen lassen sich nicht mal mit -E (jede 1. und 4. Seite gemeinsam auf einer Seite) und -E (jede 2. und 3. Seite auf einer Seite) erstellen – es sei denn, es handelt sich um ein sehr dünnes Heft, das lediglich aus einem einzigen Bogen Papier besteht.

Ordnung ins Chaos

Da empfiehlt sich pstops schon dem Namen nach als Allheilmittel in Sachen PostScript-interner Umwandlung. Doch auch dieses Tool kann nicht hexen und erwartet, dass die Quelldatei die Konventionen zur Strukturierung von PostScript-Dokumenten ("Document Structuring Conventions" – DSC) des PostScript-Erfinders Adobe einhält.

Leider tun das weder alle PostScript-ausgebende Programme, noch beherrscht pstops sämtliche DSC-Anforderungen von A bis Z, sodass es vorkommen kann, dass pstops' Künste versagen.

Doch das soll nicht als Ausrede dienen! Jetzt heißt es, tapfer zu sein und der pstops-Manpage ins Auge zu sehen. Und damit wir den Wald vor lauter Bäumen auch sehen, tun wir gut daran, erst einmal zu spezifizieren, was wir wollen.

Wir möchten unsere Gedichtsammlung gern so ausdrucken, dass ein Heftchen heraus kommt. Damit das geht, muss die logische Seitenanzahl durch vier teilbar sein – pstops wird am Ende soviel Leerseiten hinzu fügen, dass das passt. Auf der Vorderseite eines A4-Bogens landen dann jeweils die erste (rechts) und die letzte (links), die dritte (rechts) und die vorvorletzte (links) usw. Auf die Rückseite von Bogen 1 kommen Seite 2 (links) und die vorletzte Seite (rechts). Bei einem 12-seitigen Heftchen sieht das aus wie in Tabelle 1a.

Da wir pstops jedoch schlecht mit einer solchen Tabelle füttern können, müssen wir das Ganze ein wenig formalisieren. Wenn wir die zu druckenden Seiten gedanklich so durchzählen, dass wir aller vier Seiten neu mit 0 beginnen (bei zwölf Seiten also 0 1 2 3 0 1 2 3 0 1 2 3), ergibt sich folgendes Schema: Auf die erste zu bedruckende Vorderseite kommt rechts die erste noch nicht gedruckte logische Seite, die beim Durchzählen gedanklich mit 0 markiert wurde. Links daneben wird die letzte ungedruckte Seite, also die erste Seite von hinten, gesetzt, wobei die Division ihrer Seitenzahl minus 1 durch vier den Rest 3 ergibt.

Auf die Rückseite kommt mit dem Rücken zur letzten Seite die zweite Seite von hinten (Rest: 2), links daneben findet die zweite Seite von vorn (Rest 1) ihren Platz.

Das ganze Prozedere – wir teilen Seitenzahl-1 durch 4 und schreiben den Rest auf – nennt sich übrigens modulo-Division.

Die ersten vier logischen Seiten sind damit abgehakt, die alte Seite 3 wird zur neuen logischen Seite 1, und wir beginnen wieder von neuem mit der Modulo-Durchnummerierung: 0 1 2 3 0 1 2 3. Hier – oh Wunder – wiederholt sich das Schema: Auf die nächste Vorderseite gehören die erste Seite von hinten mit Rest 3 und die erste Seite von vorn mit Rest 0. Die Rückseite teilen sich wiederum 1 von vorn und 2 von hinten.

Das selbe Spielchen wiederholt sich mit den verbleibenden vier logischen Seiten, und mit dem so gefundenen Schema (vgl. Tabelle 1b) hätten wir den Anfang der Druckseitenspezifikation gefunden, die in der pstops-Manpage so angegeben ist:

pstops […] pagespecs […][…]
 pagespecs folgt folgender Syntax:
     pagespecs   = [modulo:]specs
     specs       = spec[+specs][,specs]
     spec        = [-]pageno[L][R][U][@scale][(xoff,yoff)]

Wir haben den Teiler 4 für den modulo-Wert, die Vorderseiten-specs beginnen mit der spec für die linke Seite: einem -, weil wir eine Seite von hinten haben wollen, gefolgt von der pageno 3. Da wir noch eine spec für die rechte Seite dazu wollen, gibt es ein + und eine neue spec: kein Minus diesmal, da wir eine logische Seite von vorn nehmen, als pageno hatten wir die 0 heraus gefunden.

Damit lauten die pagespecs für alle Druckvorderseiten bislang:

4:-3+0

Analog hilft ein Blick in Tabelle 1b dabei, die bislang gefundene Seitenbeschreibung für die Druckrückseite aufzuschreiben:

4:1+-2

Tabelle 1a: Blatteinteilung für ein 12-seitiges A5-Heftchen

A4-Blatt Nr. Vorderseite Rückseite
links rechts links rechts
1 12 1 2 11
2 10 3 4 9
3 8 5 6 7

Tabelle 1b: … auf eine Formel gebracht

Noch nicht berücksichtigte Seiten durchgezählt von 0 bis 3: 3 0 1 2
Von vorn (+) oder von hinten (-)? - + + -

Drehen, schubsen, klein machen

Das ist schon einmal sehr schön, doch wie bekommen wir überhaupt zwei logische A4-Seiten auf eine? Ganz einfach, werden Sie sagen: Sie müssen lediglich um 90 Grad gedreht, um die Hälfte verkleinert und auf den richtigen Platz verschoben werden.

Leider entnehmen wir der Manpage zu pstops, dass diese Operationen immer in der Reihenfolge

  • Verschiebung um xoff in x-Richtung und yoff in y-Richtung,
  • 90-Grad-Rotation entgegen dem Uhrzeigersinn (L wie "links"), im Uhrzeigersinn (R – "rechts") oder 180-Grad-Rotation ("Umkehrung" – U) und ggf.
  • Skalierung auf scale der Ausgangsgröße ausgeführt werden.

Damit nehmen wir uns am besten ein paar Blatt A4-Papier zur Hand und spielen ein wenig mit den geometrischen Operationen.

Abbildung 3: 1. Schritt: horizontales Verschieben der A4-Seite

Legen wir das Blatt hochkant hin, wie es bei den meisten Druckern üblich ist: In diesem Format und an dieser Stelle müssen wir auch nach all den Transformationen wieder landen. Wenn wir uns entscheiden, das Blatt entgegen dem Uhrzeigersinn um die linke untere Ecke zu drehen, bleibt der linken unteren Ecke der zukünftigen linken Blatthälfte demnach nichts anderes übrig, als rechts unten zu landen. Dazu müssen wir das hochformatige Blatt zunächst horizontal verschieben, und zwar so weit, wie es breit ist (Abbildung 3).

Da ein A4-Blatt 21 cm breit und 29.7 cm hoch ist, erweitern wir unsere pagespecs für Vorderseiten zu

4:-3(21cm,0)+0

und für Rückseiten auf

4:1(21cm,0)+-2

Dann können wir ungestört wie in Abbildung 4 links herum um 90 Grad rotieren, was unsere pagespecs wie folgt erweitert:

4:-3L(21cm,0)+0
 4:1L(21cm,0)+-2
Abbildung 4: 2. Schritt: Rotation entgegen dem Uhrzeigersinn

Jetzt liegt die jeweils linke Seite so da, dass wir sie nur noch verkleinern müssen, damit sie am passenden Ort mit der passenden Größe zu liegen kommt. A5, die Zielgröße, ist halb so groß wie A4. Wer jetzt allerdings einfach Höhe und Breite halbiert, kommt – wie Abbildung 5 zeigt – zu einem falschen, da zu kleinen Ergebnis.

Das ist nicht verwunderlich, denn die Halbierung bezieht sich nicht auf die Seitenabmessungen, sondern auf den Flächeninhalt. Dummerweise interessiert sich pstops bei der Skalierung nicht um das Verhältnis der Flächeninhalte und will tatsächlich Seitenverhältnisse sehen, wobei unterschiedliche Skalierungen in x- und y-Richtung nicht möglich sind.

Ein Blick auf Abbildung 5 oder das "lebende Papier-Objekt" verrät zum Glück, dass die gedrehte Seite soweit verkleinert werden muss, dass die längere Seite der alten A4-Breite entspricht. Die Breite einer A5-Seite wiederum entspricht der Hälfte der A4-Länge, mithin 29.7/2 cm = 14.85 cm.

Setzt man die Breiten von A5 und A4 (14.85 cm : 21 cm) oder auch die Längen (21 cm : 29.7 cm) miteinander ins Verhältnis, so erhält man den Skalierungsfaktor 0.7. Abbildung 6 zeigt, dass wir damit genau richtig liegen und unsere Seitenspezifikationen somit wie folgt ergänzen können:

4:-3L@0.7(21cm,0)+0
 4:1L@0.7(21cm,0)+-2
Abbildung 5: Falsch: Verkleinern der Seitenabmessungen um die Hälfte
Abbildung 6: 3. Schritt: Verkleinern des Flächeninhalts um die Hälfte

Bleiben die rechten Seiten: Was Rotation und Skalierung betrifft, können wir alles beim Alten lassen:

4:-3L@0.7(21cm,0)+0L@0.7
 4:1L@0.7(21cm,0)+-2L@0.7

Wir müssen dazu lediglich unser A4-Blatt zu Beginn ein bisschen anders verschieben: nicht nur die 21 horizontalen Zentimeter, sondern auch noch um die Hälfte der A4-Länge (mithin 14.85 cm) nach oben (Abbildung 7).

Damit sehen unsere finalen pagespecs so aus:

4:-3L@0.7(21cm,0)+0L@0.7(21cm,14.85cm)
 4:1L@0.7(21cm,0)+-2L@0.7(21cm,14.85cm)
Abbildung 7: Die Schritte 1 bis 3 für zukünftige rechte Seitenhälften

Gut gedruckt, Löwe

Menschen mit Druckern, die von sich aus doppelseitig ausdrucken, haben es jetzt gut, denn sie dürfen alle Seiten auf einmal in eine Datei schreiben:

pstops -pa4 "4:-3L@0.7(21cm,0)+0L@0.7(21cm,14.85cm),4:1L@0.7(21cm,0)+-2L@0.7(21cm,14.85cm)" gedichte.ps gedichteheft.ps

Als Seitengröße geben wir mit -p (wie "page") a4 an. Die Fehlermeldung

pstops: page specification error:
   <pagespecs> = [modulo:]<spec>
   <spec>      = [-]pageno[@scale][L|R|U][(xoff,yoff)][,spec|+spec]
                 modulo<=1, 0<=pageno<modulo

lässt uns jedoch aufschrecken und noch einmal gründlich die Manpage studieren. Tatsächlich, zum Kombinieren der Spezifikationen für Vorder- und Rückseiten in einer einzigen pagespec darf modulo: nur einmal zu Beginn auftauchen:

pstops -pa4 "4:-3L@0.7(21cm,0)+0L@0.7(21cm,14.85cm),1L@0.7(21cm,0)+-2L@0.7(21cm,14.85cm)" gedichte.ps gedichteheft.ps

Die weniger glücklichen Benutzer(innen) einseitiger Drucker generieren zwei Dateien für die Vorderseiten…

pstops -pa4 "4:-3L@0.7(21cm,0)+0L@0.7(21cm,14.85cm)" gedichte.ps gedichteheft-vorder.ps

… und die Rückseiten:

pstops -pa4 "4:1L@0.7(21cm,0)+-2L@0.7(21cm,14.85cm)" gedichte.ps gedichteheft-rueck.ps

… und müssen den Papierstapel des Ausdrucks lpr gedichteheft-vorder.ps noch einmal in den Papierbehälter einlegen. In Mehrbenutzerumgebungen empfiehlt es sich, damit bis zu einem Zeitpunkt zu warten, wo Ausdrucke von Mitbenutzer(innen) unwahrscheinlich sind, um nicht urplötzlich den Geschäftsbrief der Kollegin auf der Rückseite des heißesten Liebesgedichts zu finden.

Doch selbst wenn das Timing stimmt, gilt es, die richtige Lage des Papierbogens heraus zu finden – eine nicht immer einfache Aufgabe, der man am besten so begegnet, dass man gedichteheft-vorder.ps in gv o.ä. lädt, lediglich die erste Seite markiert (Abbildung 8) und nur diese mit Print Marked ausdruckt.

Abbildung 8: Mit dem dritten Markierungsbutton unterhalb von Redisplay markiert man in gv die ausgewählte Seite

Hat man heraus gefunden, wie sich die erste Seite von gedichteheft-rueck.ps auf dem so bedruckten Blatt korrekt abbilden lässt, kann man mit den ersten zwei Seiten den Test fahren, ob die mit gedichteheft-vorder.ps bedruckten Blätter auch wirklich so angeordnet sind, dass die Seiten in gedichteheft-rueck.ps wirklich auf den passenden Vorderseiten landen.

Stellt man hier fest, dass der Drucker die gedichteheft-vorder.ps-Seiten so ausspuckt, dass gedichteheft-rueck.ps besser mit der letzten Rückseite zuerst gedruckt wird, hilft z.B. mpage -r -1 -o.

Glossar

LaTeX

Eine professionelle Textsatzumgebung, bei der die Formatierungshinweise wie bei HTML als Klartext-"Befehle" in den ASCII-Dokumenttext geschrieben und von den Programmen latex resp. tex entsprechend den Regeln des Schriftsatzes umgesetzt werden. Besonders gut für wissenschaftliche Texte nahezu unbegrenzter Länge, aber auch für Briefe oder Folien geeignet.

dvips

Der dvi-nach-PostScript-Konverter erzeugt PostScript-Code aus dem von TeX/LaTeX generierten geräteunabhängigen ("device independent", daher der Name) dvi-Format. Meist ist dvips so vorkonfiguriert, dass ein dvips dateiname.dvi den PostScript-Code direkt an den Standarddrucker schickt. Mit der Option -o dateiname.ps erzwingt man in diesem Fall, dass dvips ihn stattdessen in die Datei dateiname.ps "druckt".

stdin

Die Standardeingabe, in der Shell normalerweise die Tastatur. Hier bei Netscape zeigt sich an dieser Angabe lediglich, dass die Druckaufbereitung nicht direkt von der dargestellten Datei aus-, sondern über Filter geht, deren Ausgabe wie in einer Pipe (|) als Standardeingabe für das nächste Kommando gilt.

[]

In der Backus-Naur-Schreibweise, in der Manpages im Abschnitt Synopsis die gesamte Syntax eines Kommandos auf einen Schlag angeben, sind Argumente in eckigen Klammern optional.

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

Kommentare