Die Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Verlag, Autoren und Übersetzer übernehmen keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene Fehler und deren Folgen. Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind möglicherweise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen. Kommentare und Fragen können Sie gerne an uns richten: O’Reilly Verlag Balthasarstr. 81 50670 Köln Tel.: 0221/9731600 Fax: 0221/9731608 E-Mail:
[email protected] Copyright der deutschen Ausgabe: c 2007 by O’Reilly Verlag GmbH & Co. KG
1. Auflage 2007
Die Darstellung von Winkelhaken im Zusammenhang mit dem Thema LATEX ist ein Warenzeichen von O’Reilly Media, Inc. »Hacks Books« und »The Hacks Series« und darauf basierende Warenzeichen und Logos sind Warenzeichen von O’Reilly Media und dürfen nicht ohne schriftliche Genehmigung verwendet werden. Das Zitat auf Seite V stammt aus Pavane von John David Gladwin.
Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar. Lektorat: Volker Bombien, Köln Fachliche Unterstützung: Karsten Günther, Elmshorn Korrektorat: Oliver Mosler, Eike Nitz, Köln Satz: Anselm Lingnau, Frankfurt am Main Umschlaggestaltung: Linda Palo, Sebastopol, und Michael Oreal, Köln Produktion: Andrea Miß, Köln Belichtung, Druck und buchbinderische Verarbeitung: Druckerei Media-Print, Paderborn ISBN 978-3-89721-477-4 Dieses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.
Für Eva: “Out of all the flowers growing wild in yon forest You’re the fairest rose on which I’ve laid an eye”
Inhalt
Credits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XI
Vorwort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XIII
Kapitel 1. Texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Text rechts- oder linksbündig setzen Die letzte Zeile eines Absatzes zentrieren Trennstriche und Bindestriche differenzieren Die Silbentrennung überprüfen Im Anfang schuf . . . Absätze platzsparend signieren Aufzählungen mit Stil Die Nummerierung von Listen ändern Anderthalbzeiliger Satz und andere Entgleisungen Polyglotter Parallelismus Lyrik setzen Programmtexte setzen Programm-Listings mit Stil Aufgaben und Musterlösungen setzen Shell-Kommandos ausführen Farbe in Ihre Dokumente bringen Die Modefarben der Saison zur Auswahl
1 3 4 7 11 14 16 17 22 25 30 36 40 42 45 48 53
Kapitel 2. Mathematik, Informatik und Naturwissenschaft . . . . . . .
57
18. Diese leidigen Kommas 19. Einfache Brüche schön aussehen lassen
57 59
VII
20. 21. 22. 23. 24. 25.
Physikalische Einheiten korrekt setzen Sätze und Beweise Matrizen und ähnliche Konstruktionen Bytefelder und Protokolldateneinheiten Syntaxdiagramme darstellen Chemische Symbole und Formeln
Kapitel 3. Seitenformatierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26. 27. 28. 29. 30. 31. 32. 33. 34.
Kapitelweise Seitennummerierung verwenden Linke und rechte Seiten verschieden behandeln Lebende Kolumnentitel im Index verwenden Seitenstile al Gusto Wider die Schusterjungen und Hurenkinder Den Satzspiegel einstellen Seitenformate veranschaulichen Doppelseiten im Überblick Ungewöhnliche Layouts mit fig2sty realisieren
61 63 65 67 69 72
74 74 77 81 82 85 89 94 100 102
Kapitel 4. Tabellen und Abbildungen . . . . . . . . . . . . . . . . . . . . . . . 106 35. 36. 37. 38. 39. 40. 41. 42. 43.
Tabellenspalten im Mathematikmodus setzen Noch mehr leidige Kommas Tabellenspalten mit variabler Breite Farblich passend Überlang und überbreit CSV-Dateien als Tabellen setzen Alles am rechten Platz Gruppendynamik Do-it-yourself-Gleitobjekte
106 109 111 114 118 124 129 131 135
Kapitel 5. Gliederung und Verzeichnisse . . . . . . . . . . . . . . . . . . . . 140 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. VIII
Variabler Tiefgang Überschriften erzeugen mit Stil Von \sections und Hacks Der Unterzeichnete . . . Inhaltlich korrekt Sneak Preview Auf dem Index Bibliografiestile testen Literaturverzeichnisse mit Turbolader Literaturverweise im Text mit BibTEX Literatur pro Kapitel Internationale Buchhandlung
Inhalt
140 142 147 150 154 162 164 166 172 174 177 179
Kapitel 6. Dokumente. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 56. 57. 58. 59. 60. 61. 62. 63. 64. 65.
Logische Auszeichnung Teile und herrsche Nach dem Ausschlussprinzip Seite 5 von 9 Die Zutatenliste Proceedings of the . . . Serienbriefe für Serientäter LATEX mit Datenbank-Anschluss CDs perfekt verhüllt Gestatten, LATEX
183 188 191 197 198 201 205 215 220 224
Kapitel 7. Schriften . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 66. 67. 68. 69. 70. 71. 72. 73.
Groß oder klein? Familienangelegenheiten Gebrochene Schriften verwenden LATEX und PostScript-Schriften Automatisierte Schriftanpassung Die Wahre Type Kursiv oder schräg? Schmal oder fett? Aus Groß mach Klein
231 234 237 240 252 256 259 263
Kapitel 8. Grafik. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 74. 75. 76. 77. 78. 79. 80.
Ein Bild sagt mehr als tausend Wörter dvips und Nicht-PostScript-Dateien EPS-Dateien in PDF umwandeln Schaubilder und Graphen mit Gnuplot erzeugen Für alle Fälle PGF Von Monat zu Monat Stickvorlagen aus Grafikdateien generieren
266 267 271 272 277 283 293
Kapitel 9. LATEX und PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 81. 82. 83. 84. 85. 86. 87. 88. 89.
pdfLATEX benutzen Immer eine gute Verbindung Vorschaubilder für PDF-Dateien erzeugen Sehr anhänglich Daten und Metadaten Russische Puppen Vom Scanner zur PDF-Datei Was Recht ist . . . Schnitt- und Passmarken erzeugen
300 301 303 304 307 311 312 320 322
Inhalt
IX
Kapitel 10. LATEX-Werkzeuge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100.
X
Die kpse-Werkzeuge in eigenen Shell-Skripten benutzen Seiten nach Wahl Eine Probe gefällig? Welche Schriften gibt es im Dokument? Bequeme LATEX-Editoren Benutzen Sie AUCTEX im GNU Emacs Vor- und Rückwärtssuche benutzen Ein Frühwarnsystem im Editor Referenzen mit Pfiff Von LATEX zu HTML Ganz subversiv
Inhalt
327 331 333 338 343 350 355 360 363 367 373
Credits
Über den Autor Anselm Lingnaus erstes TEX-System kostete im Jahr 1987 knapp 300 Mark, kam auf einem Berg Disketten daher (allein eine davon für die vollkommen unnütze Schrift cminch), lief auf einem Atari ST und hatte eine Art Druckertreiber für den Bildschirm (in der Voransicht eines Dokuments konnte man nicht zurückblättern). Diese Widrigkeiten hielten ihn allerdings nicht davon ab, sich weiter mit TEX und LATEX zu befassen, und eines seiner ersten Projekte war ein verbessertes Bildschirm-Anzeigeprogramm für DVI-Dateien. Ansonsten leistete LATEX ihm gute Dienste während des größten Teils seines Informatikstudiums, einiger Vortrags-Jahrbücher der Volkssternwarte Hofheim und etlicher Jahre in der Produktion der Astronomischen Mitteilungen Rhein-MainNahe. Er ist Autor der LATEX-Erweiterung float und verschiedener anderer Zusatzpakete von geringerer Bedeutung sowie Koautor eines Buchs über die Linux-Zertifizierungsprüfung LPIC-1. Anselm lebt im Rhein-Main-Gebiet und arbeitet für ein Linux-Schulungsund -Beratungsunternehmen, wo er verantwortlich ist für die Erstellung und Qualitätssicherung von Unterrichtsmaterialien, die natürlich mit LATEX gesetzt werden. In seiner Freizeit vergnügt er sich mit schottischem Tanz und schottischer Tanzmusik (auch dort gibt es viele Möglichkeiten, LATEX zum Einsatz zu bringen), Klavierspielen, Lesen, Schreiben, Fotografieren, Kochen, Reisen und zahlreichen anderen epikureischen Zeitvertreiben sowie seiner Pinguinsammlung, die älter ist als Linux 2.0.
XI
Danksagungen Die wenigsten Bücher kommen wohl zustande, ohne dass viele fähige Köpfe und treue Seelen sich dafür einsetzen. Volker Bombien gebührt als Lektor die Anerkennung, mich zu dem Projekt überredet zu haben; er hat mir (dem vermutlich nervenaufreibendsten Autor in der Geschichte von O’Reilly) geduldig die Treue gehalten und die Sache mit der richtigen Mischung aus Toleranz und sanftem Druck auch bis zum Ende durchgestanden. Karsten Günther steuerte viele wertvolle LATEXnische Anmerkungen bei und machte mich auf Fehler und Auslassungen aufmerksam. Und vielen Dank auch an den Rest des O’Reilly-Teams für dieses Buch: Andrea Miß für die Produktion, Oliver Mosler und Eike Nitz im Korrektorat, und Linda Palo und Michael Oreal für die Grafik. Ganz besonders inniger Dank gilt natürlich meiner Freundin, Eva Schiedrum, die das Buchprojekt von Anfang an unterstützt hat, obwohl es für sie zahlreiche Entbehrungen und Ärgernisse bedeutete. Sie hat mich viel zu oft vermissen müssen, weil ich wieder mal irgendwelchen losen LATEXnischen Enden nachgejagt habe, und hat mich unermüdlich daran erinnert, dass es auch eine Welt jenseits von Büchern, Computern und mit dem Computer gesetzten Büchern gibt. Meiner Familie, Dr. Gerold, Antje und Ivo Lingnau, gebührt später Dank für ihre Toleranz in meiner TEX-Frühzeit – vor allem der sägenden Geräusche, die mein NEC-P6-Matrixdrucker zu allen Tages- und Nachtzeiten von sich gab, wenn es mal wieder ein Praktikumsprotokoll zu drucken gab. Auch erwähnt werden sollte die einstmalige Redaktion der Astronomischen Mitteilungen Rhein-Main-Nahe – Burkhard Wiche, Torsten Schäfer, Norman Diehl und Volker Heinrich –, über Jahre immer wieder Testfeld für neue Makro-Ideen oder ungewöhnliche LATEX-Pakete, Weggefährten zahlloser langer astronomisch-typografischer Nächte und Rückendeckung gegenüber denen, die behaupteten, mit Microsoft Word wäre alles doch so viel einfacher! Nicht unerwähnt bleiben sollen auch die genialen Köpfe hinter TEX und LATEX: Donald E. Knuth und Leslie Lamport, ohne die es keinen Bedarf für dieses Buch gäbe. LATEXnisch steht dieses Buch auf den Schultern von diversen Riesen, die hier gar nicht alle erwähnt werden können. Exemplarisch seien in alphabetischer Reihenfolge nur Javier Bezos, David Carlisle, Frank Mittelbach und Rainer Schöpf genannt, deren Arbeit etliche der hier beschriebenen Hacks softwaretechnisch untermauert oder inspirativ katalysiert hat. Vielen Dank!
XII
Credits
Vorwort
TEX und LATEX zählen inzwischen zu den Urgesteinen des Computer-Schriftsatzes. Seit Mitte der 1980er-Jahre stehen sie für unerreichte Ausgabequalität und Flexibilität im Umgang mit den unterschiedlichsten Anforderungen. Nebenbei gebührt ihnen die Krone des vermutlich fehlerfreisten großen Softwaresystems im allgemeinen Umlauf. Allen Anfechtungen durch »Desktop Publishing« und »WYSIWYG« zum Trotz (Ganz Gallien? Nein!) entwickelt eine eingeschworene Gemeinde von Benutzern und Autoren die Software stetig weiter, ohne dabei jedoch die Basis, Donald E. Knuths seinerzeit bahnbrechendes TEX-System, aus den Augen zu verlieren. Als LATEX-Benutzer kommen Sie sowohl in den Genuss weitgehender Kompatibilität für Dokumente aus den letzten beiden Jahrzehnten als auch behutsamer Umsetzung neuer technischer Ideen, etwa wenn es um die Ausgabe von Dokumenten als PDF geht. Und das Schöne ist: Was Sie heute lernen, wird Ihnen vermutlich auch noch in fünf oder zehn Jahren von Nutzen sein. Und von welchem anderen Computerprogramm können Sie das schon behaupten? Dieses Buch ist eine Sammlung von Ideen, Methoden und Tricks (»Hacks«) aus allen möglichen Anwendungsbereichen von LATEX. Wir erheben nicht den Anspruch, alle Dinge für alle Leute zu erklären, sondern greifen uns ein paar besonders interessante oder spannende Themen heraus, um Sie auch zu weiteren Experimenten und kreativen Momenten zu inspirieren. Manches, was wir erklären, beruht auf »vorgekochten« Erweiterungen, die Sie im Netz finden können – in diesem Fall versuchen wir oft zu erklären, wie die grundlegenden Techniken aussehen, die in diesen Erweiterungen aufgegriffen und umgesetzt werden. Anderes ist in dieser Form noch nicht veröffentlicht worden und beschreitet darum LATEXnisches Neuland. In jedem Fall geht es uns aber immer darum, die gezeigten TEXniken in ihren Kontext zu setzen und Ihnen ein
XIII
Handwerkszeug zur Verfügung zu stellen, das Sie auch in anderen Situationen einsetzen können. TEX und LATEX sind keine »freistehenden« Programme, sondern immer Teil eines größeren Softwaresystems aus Editoren, Ausgabetreibern und Hilfsprogrammen unterschiedlicher Art. Einige unserer Hacks beschränken sich darum nicht auf TEX und LATEX, sondern verwenden zusätzlichen Code in Programmiersprachen wie der Linux- oder Unix-Shell oder Larry Walls Perl. Lassen Sie sich davon nicht abschrecken: Während ein gewisses grundlegendes Verständnis von Linux und Perl Ihnen dabei hilft, aus diesen Hacks das meiste zu machen, können Sie sie doch auch als black box verwenden. Und selbst wenn Sie LATEX nicht auf einem Linux- oder Unix-System einsetzen, stehen die Chancen gut, dass Sie auch Perl und eine Unix-artige Shell mit Hilfsprogrammen für Ihren Rechner finden können. Im Übrigen ist eine Sammlung wie diese niemals völlig abgeschlossen. Sie können das, was Sie aus diesem Buch gelernt haben, dazu verwenden, Ihre eigenen Hacks zu entwickeln. Seien Sie kreativ und denken Sie seitwärts! Und wer weiß, vielleicht landet einer Ihrer Hacks in der nächsten Auflage dieses Buchs.
Wie Sie dieses Buch benutzen Wenn Sie möchten, können Sie dieses Buch von Anfang bis Ende durchlesen, aber da jeder Hack eine selbstständige Einheit bildet, können Sie auch einfach blättern und zwischen den Abschnitten hin- und herspringen, die Sie am meisten interessieren. Sofern irgendwo ein spezielles Wissen vorausgesetzt wird, leitet ein Querverweis Sie zu dem entsprechenden Hack. Außerdem verweisen wir auf andere interessante Dokumentation. Wir sollten ehrlicherweise auch erwähnen, dass es sich bei diesem Buch nicht um ein LATEX-Lehrbuch handelt (von denen sind schon genug auf dem Markt). Wir setzen voraus, dass Sie schon eine Weile mit LATEX arbeiten und dass Kommandos wie \newcommand und \RequirePackage keine Fremdwörter für Sie sind. Allerdings bemühen wir uns, die allermeisten weiterführenden Konzepte zumindest kurz zu erklären. Nicht alle in diesem Buch erwähnten LATEX-Pakete und Zusatzprogramme sind tatsächlich in den gängigen Softwaredistributionen enthalten. Sie finden aber alles auf dem Comprehensive TEX Archive Network (CTAN), das Sie im Internet unter http://www.ctan.org erreichen.
XIV
Vorwort
Wie dieses Buch aufgebaut ist Dieses Buch ist mehr als nur eine Sammlung mit Tipps und Tricks in der Form »Tun Sie dies, tippen Sie das«. Wir geben Kochrezepte für interessante und wichtige Anwendungen, aber wie jedes gute Kochbuch sagen wir hin und wieder etwas über die Zutaten und den Umgang mit ihnen. Trotzdem geht es uns natürlich darum, Ihnen Methoden an die Hand zu geben, die Sie in kurzer Zeit tatsächlich einsetzen können, und Ihnen auch Ideen zu liefern, wie Sie die Hacks durch eigenes Zutun noch verbessern können. Das Buch gliedert sich in zehn Kapitel: Kapitel 1, Texte Der überwiegende Teil der meisten LATEX-Dokumente besteht aus Text in diversen Manifestationen: Fließtext, Zitate, Listen, Lyrik, Programmauszüge und vieles mehr. Wir zeigen Ihnen, wie Sie manches Problem lösen und nette Effekte erzielen können – von Initialen am Absatzanfang bis zu parallelem Satz in mehreren Sprachen. Dazu lernen Sie, ein Auge auf die Silbentrennung von TEX zu haben und Farbtabellen auszugeben. Kapitel 2, Mathematik, Informatik und Naturwissenschaft Die große Stärke von TEX und LATEX ist der Satz mathematischer Formeln, und dazu bieten wir hier einige Tricks an. Daneben können Sie einiges lernen über den Satz von Bitfeld-Schaubildern und Syntaxdiagrammen sowie die korrekte Behandlung chemischer Formeln. Kapitel 3, Seitenformatierung Die Gestaltung von Seiten ist eine wichtige Aufgabe im Schriftsatz. Dieses Kapitel gibt Ihnen Hinweise zum Umgang mit der Seitennummerierung, zu Kopf- und Fußzeilen und zur unterschiedlichen Gestaltung von linken und rechten Seiten. Sie lernen, wie man »Schusterjungen« und »Hurenkinder« vermeidet, Seitenlayouts visualisiert und wie Sie komplexe Layouts grafisch vorzeichnen und mit LATEX »ausfüllen« können. Kapitel 4, Tabellen und Abbildungen Dieses Kapitel beginnt mit einigen Tipps zur Eingabe von Tabellen und erklärt Ihnen dann, wie Sie Tabellen realisieren können, die in einzelnen Spalten Absätze von flexibler Breite enthalten. Nach einem Ausflug in die Welt farbiger Tabellen helfen wir Ihnen beim Umgang mit Tabellen, die zu lang oder zu breit für Ihre Seiten sind. Außerdem lernen Sie, wie Sie CSV-Dateien direkt an LATEX verfüttern können, wie Sie dafür sorgen, dass Ihre Gleitobjekte Ihnen nicht entgleiten, und einiges mehr. Kapitel 5, Gliederung und Verzeichnisse Traditionell war es nicht einfach, LATEXs Vorstellung davon, wie Kapitelanfänge oder Überschriften aussehen sollen, an seine eigenen Wünsche
Vorwort
XV
anzupassen. Inzwischen ist das kein Problem mehr, und wir erklären Ihnen, wie das geht. Ferner lernen Sie einiges über die automatische Erstellung von Inhaltsverzeichnissen in vielerlei Gestalt, Stichwortverzeichnissen und Literaturlisten und über die Werkzeuge, die die LATEX-Szene hierfür anzubieten hat. Kapitel 6, Dokumente In diesem Kapitel zeigen wir Ihnen Strategien und Hacks für den Umgang mit ganzen Dokumenten, etwa für eine konsistente Formatierung oder das Erzeugen mehrerer Versionen eines Dokuments aus demselben Quellcode. Sie sehen, wie Sie mehrere unabhängige LATEX-Dateien zu einem großen Dokument zusammenfügen können, und lernen Tricks für die Erstellung von Serienbriefen mit oder ohne SQL, von CD-Hüllen mit wenig Tipparbeit und von Visitenkarten und Etiketten. Kapitel 7, Schriften Ebenso intransigent wie bei den Überschriften zeigte sich LATEX früher auch bei den Schriften im Dokument (Henry Ford lässt grüßen). Zum Glück hat sich auch hier das Rad der Geschichte weitergedreht, so dass Sie in diesem Kapitel lernen, wie Sie die Schrift für Ihr Dokument radikal ändern, gebrochene Schriften korrekt verwenden oder beliebige PostScript- oder TrueType-Schriften für den Einsatz mit LATEX aufbereiten können. Außerdem finden Sie heraus, wie Sie Schrifteffekte wie Schrägstellung oder Kapitälchen realisieren können, auch wenn Ihre Schrift keine entsprechenden Schnitte aufweist. Kapitel 8, Grafik Dieses Kapitel steht ganz im Zeichen von Illustrationen: Sie lernen Bilder in Ihre Dokumente zu integrieren, auch wenn es sich um Formate handelt, die LATEX nicht direkt verdauen kann. Sie bringen LATEX dazu, das Zeichnen von Funktionsgraphen an Gnuplot zu delegieren, und lernen das moderne TEX-Grafikpaket pgf kennen. Außerdem zeigen wir Ihnen einige Anwendungen wie den Satz von Fotokalendern und Stickschrift mit LATEX. Kapitel 9, LATEX und PDF Aus dem professionellen Druckgewerbe ist PDF nicht mehr wegzudenken. Klar, dass auch LATEX damit umgehen können muss. In diesem Kapitel lernen Sie nicht nur, wie Sie mit pdfTEX direkt PDF statt DVI erzeugen können, sondern auch, wie Sie Ihre Dokumente mit Querverweisen zum Anklicken oder Vorschaubildern für die einzelnen Seiten versehen. Hängen Sie Dateien direkt an Ihre Dokumente an, schreiben und lesen Sie PDF-Metadaten und integrieren Sie andere PDF-Dokumente ganz oder seitenweise in Ihr Dokument. Ferner lernen Sie mit PDF-Zugriffsrechten umzugehen und Ihre Dokumente mit Schnittmarken zu versehen. XVI
Vorwort
Kapitel 10, LATEX-Werkzeuge LATEX ist kein alleinstehendes Programm, sondern Teil eines großen Systems von Werkzeugen. In diesem Kapitel lernen Sie einige Hilfsprogramme für LATEX kennen und finden heraus, wie andere Programme LATEX speziell zuarbeiten können. Dabei geht es um Tricks bei der Erstellung von Shell-Skripten für LATEX, die Auswahl von Teilen von Dokumenten auf DVI- und PDF-Basis und das Aufstellen von Listen der in Dokumenten verwendeten Schriften. Sie lernen einige Editoren kennen, die speziell für LATEX gedacht sind oder besondere Eigenschaften für die Bearbeitung von LATEX haben, und erfahren einiges über die Konvertierung von LATEX-Dokumenten nach HTML und die Verwaltung von LATEX-Quelltext mit Subversion.
In diesem Buch verwendete Konventionen In diesem Buch gelten folgende typografische Konventionen: Kursivschrift Neue Begriffe, URLs, Dateinamen und -erweiterungen, Verzeichnisse und Ordner werden kursiv gedruckt. Nichtproportionalschrift
In diesem Schrifttyp werden Codebeispiele, Suchbegriffe, Befehle, Dateiinhalte und Befehlsausgaben dargestellt. Nichtproportionalschrift fett
Dient in Beispielen und Tabellen zur Kennzeichnung von Befehlen und anderem Text, der wortwörtlich eingegeben werden soll. Nichtproportionalschrift kursiv
Damit werden in Beispielen, Tabellen und Befehlen die Teile hervorgehoben, für die benutzerdefinierte Werte eingegeben werden sollen. Graue Schrift Graue Schrift kennzeichnet einen Querverweis innerhalb des Textes. Bitte achten Sie besonders auf Anmerkungen, die mit den folgenden Symbolen hervorgehoben werden: Dies ist ein Tipp, ein Vorschlag oder eine allgemeine Anmerkung. Hier finden Sie ergänzende Informationen zum jeweiligen Thema. Dies ist eine Warnung oder ein Hinweis, dass Sie vorsichtig sein sollten.
Vorwort
XVII
Die Thermometer-Symbole neben den einzelnen Hacks geben an, wie kompliziert der jeweilige Hack ist: leicht
mittel
schwer
Haben Sie einen guten Hack, den Sie mit anderen teilen möchten? Dann gehen Sie auf die O’Reilly-Hacks-Webseite: http://hacks.oreilly.com
XVIII
Vorwort
KAPITEL EINS
Texte Hacks #1–17
Texte sind das Brot- und Buttergeschäft von Programmen wie LATEX, aber die Anforderungen, mit denen Sie als Anwender konfrontiert werden, sind vielgestaltig – sie reichen von einfachen Fragen der Formatierung bis hin zu subtilen Tricks, mit denen Sie sich Arbeit sparen und gleichzeitig die Qualität Ihrer Dokumente erhöhen können. Das Thema bietet also genug Raum für diverse kleine und große Hacks. In diesem Kapitel lernen Sie nicht nur überraschende oder verbesserte Lösungen für einiges kennen, das LATEX scheinbar schon »ab Werk« beherrscht, sondern erfahren auch, wie Sie LATEX mit ein paar externen Programmen auf die Sprünge helfen können, etwa um effizient Ihre Silbentrennungen zu prüfen. Sie lernen einige versteckte Tugenden des verbatim-Pakets kennen, setzen mehrsprachige Texte parallel und drucken Übersichtstafeln für die Farben Ihres X11-Systems. Dies und noch einiges mehr . . .
HACK
Text rechts- oder linksbündig setzen
#1
Zwei rechts, zwei links, keine fallen lassen . . .
Normalerweise bemüht sich LATEX nach Kräften, Texte in ausgewogenem »Blocksatz« zu setzen – beide Ränder, links und rechts, werden »glatt« gemacht, indem die Wortabstände in jeder Zeile sorgfältig angepasst werden. Das wirkt elegant, ist aber in manchen Situationen unpraktisch (beispielsweise in engen Tabellenspalten) oder zu förmlich (in Briefen, obwohl die Ansichten da auseinandergehen), so dass »Flattersatz« angesagt ist: Der linke Rand ist glatt, alle Wortabstände sind gleich breit, und wenn ein Wort rechts überstehen würde, wird es an den Anfang der nächsten Zeile übernommen, gegebenenfalls nach dem Versuch einer Silbentrennung. Hin und wieder
1
HACK
#1
Text rechts- oder linksbündig setzen
möchte man Material auch »rechtsbündig« setzen, so dass der rechte Rand glatt ist und der linke »flattert«. LATEX sieht für Flattersatz die Kommandos \raggedright und \raggedleft vor, die respektive den rechten bzw. linken Rand »flattern« lassen. Beide gibt es auch als Umgebungen, namentlich flushleft (entsprechend \raggedright) und flushright (entsprechend \raggedleft). Damit passiert ungefähr das Richtige, bis auf ein Problem – eine Silbentrennung wird praktisch ausgeschlossen, so dass der Text zu sehr flattert: Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten August, meinen Geburtstag, auf eine sehr freundliche Weise feiern mochte, erwarb sich wohl dadurch ein Recht, mich festzuhalten; allein hier war nicht länger zu säumen.
\raggedright Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten August, meinen Geburtstag, auf eine sehr freundliche Weise feiern mochte, erwarb sich wohl dadurch ein Recht, mich festzuhalten; allein hier war nicht länger zu säumen.
Der Grund dafür ist, dass \raggedright Zeilen im Wesentlichen mit »nichts plus beliebig viel Leerraum« auffüllt und TEX mit dieser Einstellung sehr kurze Zeilen gegenüber Zeilen mit Silbentrennung bevorzugt. Bessere Resultate liefert das Paket ragged2e von Martin Schröder, das ein neues Kommando \RaggedRight definiert. Hier wird stattdessen mit »nichts plus maximal einer bestimmten Menge Leerraum« aufgefüllt, gemäß der Voreinstellung 2em (also zweimal die Breite eines »M« in der aktuellen Schrift); viel zu kurze Zeilen sind für TEX damit auch »schlecht«, und Silbentrennung wird attraktiver: Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten August, meinen Geburtstag, auf eine sehr freundliche Weise feiern mochte, erwarb sich wohl dadurch ein Recht, mich festzuhalten; allein hier war nicht länger zu säumen.
2
Kapitel 1: Texte
\RaggedRight Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten August, meinen Geburtstag, auf eine sehr freundliche Weise feiern mochte, erwarb sich wohl dadurch ein Recht, mich festzuhalten; allein hier war nicht länger zu säumen.
HACK
Die letzte Zeile eines Absatzes zentrieren
Das Paket ragged2e definiert außerdem noch das Kommando \RaggedLeft sowie die Umgebungen FlushLeft und FlushRight. Ähnliche Einschränkungen gelten übrigens auch für zentrierten Text, den LATEX über das Kommando \centering oder die Umgebung center ermöglicht (center fügt zusätzlichen Leerraum vor und nach den zentrierten Zeilen ein): Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten . . .
\centering Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten \dots
Zur Abhilfe hält ragged2e das Kommando \Centering und die Umgebung Center bereit: Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten . . .
\Centering Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten \dots
In Überschriften und an anderen exponierten Stellen kann es sein, dass eine Silbentrennung eher ungeschickt ausfällt. Dort sollten Sie sich nicht auf ragged2e verlassen, sondern lieber manuell eingreifen.
HACK
Die letzte Zeile eines Absatzes zentrieren
#2
Geschicktes Jonglieren mit \leftskip und \rightskip
Wollen Sie einen Absatz zwar im Blocksatz setzen, aber die letzte Zeile zentrieren? Dann ist etwas Handarbeit angesagt. Der Trick besteht in den folgenden Definitionen: \newenvironment{lcpar}{% \begingroup \setlength{\leftskip}{0pt plus 1fil}% \setlength{\rightskip}{-\leftskip}% \setlength{\parfillskip}{0pt plus 2fil} }{% \par\endgroup }
Hack #2: Die letzte Zeile eines Absatzes zentrieren
3
#2
HACK
#3
Trennstriche und Bindestriche differenzieren
Auf den ersten Blick wirkt das konterintuitiv, aber eigentlich ist es ganz einfach: TEX fügt am linken Ende jeder Zeile Leerraum im Wert von \leftskip und am rechten Ende im Wert von \rightskip ein. Bei unserer Definition heben sich \leftskip und \rightskip im Normalfall der ersten bis vorletzten Zeile eines Absatzes gerade gegenseitig auf, so dass sie keine sichtbare Wirkung haben. Nur bei der letzten Zeile eines Absatzes wird zusätzlich noch der \parfillskip hinzugefügt, also steht dort am Ende der \rightskip plus der \parfillskip im Gesamtwert von 0pt plus 1fil. Das wiederum entspricht gerade dem \leftskip der Zeile, ergo wird die letzte Zeile zentriert! Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten August . . .
\begin{lcpar} Früh drei Uhr stahl ich mich aus Karlsbad, weil man mich sonst nicht fortgelassen hätte. Die Gesellschaft, die den achtundzwanzigsten August \dots \end{lcpar}
HACK
Trennstriche und Bindestriche differenzieren
#3
Wie Sie LATEX beibringen, Wörter mit Bindestrich an allen möglichen Stellen zu trennen.
Es ist schon bemerkenswert, was ein kleiner Strich so alles hergibt: Die Standard-PC-Tastatur bietet gleich links von der rechten Umschalttaste ein Zeichen, das in guter Schreibmaschinen-Tradition je nach Bedarf als Trennstrich, Bindestrich, Gedankenstrich oder auch Minuszeichen auftreten kann. Da Sie anscheinend schönen Schriftsatz lieben, ist Ihnen natürlich klar, dass in ernstgemeinten Druckwerken große Unterschiede zwischen Trenn- und Bindestrich (»-«), Gedankenstrich (»–«) und Minuszeichen (»−«) bestehen. (Im angelsächsischen Schriftsatz ist der Gedankenstrich noch ein Stück länger, nämlich etwa »—«, aber hierzulande machen wir das nicht so. Unser Gedankenstrich dient hier wie dort noch als »Streckenstrich« zur Angabe von Zahlenbereichen wie in »11–15 Freunde müsst Ihr sein (wenn Ihr auch noch Ersatzspieler haben wollt)«.) In diesem Hack beschäftigen wir uns aber zunächst mit einer spitzfindigen Sache, die den Unterschied zwischen Trenn- und Bindestrich betrifft. »Da gibt es einen Unterschied?«, werden Sie fragen, und dieses Buch antwortet mit einem entschiedenen »Ja«. Zwar sehen die beiden Zeichen sehr ähnlich aus, aber das eine steht immer am Zeilenende und macht darauf aufmerksam, dass ein angefangenes Wort in der nächsten Zeile weitergeht, und das andere dient dazu, zwei oder mehr Wörter zu verbinden, die ansonsten nichts miteinander
4
Kapitel 1: Texte
HACK
Trennstriche und Bindestriche differenzieren
zu tun haben (»Schokoladen-Rollmops« oder »Konrad-Zuse-Straße«1 ). So viel zur deutschen Sprache. Was LATEX anbelangt, ist der Bindestrich der Bindestrich, und über den Trennstrich entscheidet der Wert eines Parameters namens \hyphenchar, der den Code des Zeichens angibt, das bei einer automatischen Silbentrennung von LATEX ins Dokument eingebaut wird. Genau genommen existiert sogar ein separater \hyphenchar für jede Schrift; ist für eine Schrift kein \hyphenchar definiert, gilt der Wert von \defaulthyphenchar. Hat der \hyphenchar für eine Schrift den Wert −1, findet gar keine Silbentrennung statt. Das ist zum Beispiel bei den Schreibmaschinenschriften der Fall (vermutlich weil man verwirrende Effekte in Programm-Listings vermeiden möchte). Mit »Code« ist übrigens nicht etwa der Zeichencode nach ASCII gemeint, sondern eine Position in der betreffenden Schrift, deren Codierung gemeinhin in weiten Teilen an den ASCII angelehnt ist, aber auch erheblich davon abweichen kann. Schriften, die der modernen TEX-Codierung T1 folgen, haben zum Beispiel an der Position 127 ein Zeichen, das einem Bindestrich verdächtig ähnlich sieht, aber via \hyphenchar als Trennstrich fungieren kann. Setzen Sie zum Beispiel \defaulthyphenchar=127
um ein Problem mit LATEX zu lösen, das vor allem die deutsche Sprache mit ihrem Hang zu Bandwurm-Wörtern auf Bindestrichbasis betrifft. LATEX weigert sich nämlich strikt, Wörter zu trennen, die den \hyphenchar der Schrift schon enthalten, außer direkt hinter dem betreffenden Zeichen. In Wortungetümen wie Donaudampfschifffahrts-Gesellschafterversammlung
kommt dadurch nur eine Trennstelle in Frage, nämlich hinter dem »-«, und das kann zu Problemen führen, die Sie elegant vermeiden können, wenn Bindestrich und Trennstrich aus LATEX-Sicht nicht dasselbe Zeichen sind. Das automatische Einfügen des \hyphenchar an Trennstellen ist ein Sonderfall eines allgemeineren Mechanismus. Bei der Berechnung von Silbentrennungen fügt LATEX intern an jeder möglichen Trennstelle ein \discretionary{\char\hyphenchar\font}{}{}
ein. Die drei Parameter von discretionary haben dabei die folgenden Bedeutungen:
1
Die heutzutage häufig anzutreffenden Entgleisungen »Konrad Zuse Straße« oder »Konrad ZuseStraße« lassen wir an dieser Stelle mal aus dem Spiel.
Hack #3: Trennstriche und Bindestriche differenzieren
5
#3
HACK
#3
Trennstriche und Bindestriche differenzieren
• Der Wert des ersten Parameters wird vor einer etwaigen Trennung an dieser Stelle eingefügt (am Ende der alten Zeile). • Der Wert des zweiten Parameters steht nach einer etwaigen Trennung (also am Anfang der neuen Zeile). • Der Wert des dritten Parameters wird benutzt, wenn an dieser Stelle gar keine Trennung stattfindet.
Dieses auf den ersten Blick etwas verwirrende Konstrukt erlaubt es LATEX, auf interessante Trennsituationen zu reagieren. Wenn Sie sich noch an die traditionelle deutsche Rechtschreibung erinnern, dann wissen Sie vielleicht noch, dass wir früher Wörter wie »Zuckerschlecken« als »Zuk-ker-schlek-ken« zu trennen pflegten (heute wäre »Zu-cker-schle-cken« richtig, was stupiden Computerprogrammen entgegenkommt, aber Vorlesern das Leben schwerer macht). Mit LATEX könnten Sie Folgendes verwenden (verwendet haben?): \newcommand{\ck}{\discretionary{k-}{k}{ck}} ... Zu\ck erschle\ck en
Während das nicht gerade schön aussieht, tut es doch das, was es tun soll. Pakete wie german oder babel haben dieselbe Funktionalität hinter etwas Gefälligerem wie Zu"ckerschle"cken
versteckt. Eine andere nützliche Anwendung ist etwa: \newcommand{\str}{\discretionary{/}{}{/}}
In Aufzählungen wie Rot\str Gelb\str Grün\str Blau
ermöglicht dies eine Ausgabe wie Rot/Gelb/Grün/Blau
oder (je nach Zeilenlänge) Rot/Gelb/ Grün/Blau
mit einer »Trennung« am Schrägstrich. Etwas un-LATEXnisch könnten Sie mit \catcode‘\/=\active \let/=\str
auch gleich in der Eingabe 6
Kapitel 1: Texte
HACK
Die Silbentrennung überprüfen
Rot/Gelb/Grün/Blau
schreiben, aber das ist möglicherweise mit Vorsicht zu genießen, wenn Sie auch noch »normale« Schrägstriche im Dokument haben (etwa als Bestandteil von expliziten Dateinamen). Die Regeln für »aktive Zeichen« sind etwas zu kompliziert, als dass man sie in diesem Hack erklären könnte! Gruppen und Umgebungen sind Ihre Freunde, um Zeichen nur da »aktiv« zu machen, wo Sie das wollen.
Siehe auch • Das Paket hyphenat von Peter R. Wilson erlaubt es, Silbentrennung im ganzen Dokument oder in Teilen davon zu unterdrücken oder Silbentrennung für Text einzuschalten, der in Schreibmaschinenschrift geschrieben ist (wo LATEX normalerweise keine macht). Es erleichtert auch Silbentrennung in Wörtern, die Nichtbuchstaben enthalten.
HACK
Die Silbentrennung überprüfen
#4
Vertrauen ist gut, Kontrolle mit hyphen_show ist besser . . .
Im Gegensatz zu vielen anderen Textverarbeitungsprogrammen verfügt LATEX über eine recht zuverlässige automatische Silbentrennung, die aber nicht unfehlbar ist. Sie ist nämlich eigentlich für Sprachen wie Englisch gedacht, die eher kurze Wörter verwenden. Bei den oft etwas längeren Wörtern der deutschen Sprache kann es sein, dass der Algorithmus einen Anfall von Übereifer bekommt und Trennstellen identifiziert, die offiziell keine sind. Außerdem gibt es natürlich Zweifelsfälle, die ohne künstliche oder natürliche Intelligenz nicht zu entscheiden sind – sprichwörtlich sind Paare wie »Stau-becken«/ »Staub-ecken« und »er-blassen«/»erb-lassen« – und Trennungen, die aus ästhetischen Gründen nicht in Frage kommen, etwa die nach dem ersten »n« in »Urinstinkt«. Hieraus ergibt sich, dass Sie LATEX beim Trennen nicht völlig freie Hand lassen sollten. Korrekturlesen ist natürlich immer wichtig, aber wenn Ihr Manuskript so weit fertig ist, dass sich vermutlich am Text nicht mehr viel ändert, sollten Sie sich ruhig einmal speziell auf die Silbentrennung konzentrieren (vorher hat es zumeist wenig Sinn). Eine nützliche Hilfestellung bietet hierbei das Programm hyphen_show von Günther Lamprecht, Wolfhard Lotz und Roland Weibezahn, das die Autoren unter der GPL freigegeben haben und das Sie zum Beispiel unter ftp://ftp.iwd.uni-bremen.de/pub/tex/hyphenation finden können. Außerdem ist es Bestandteil des LATEX-Editors xtem. (In gängigen Linux-Distributionen, etwa Debian GNU/Linux, ist es auch enthalten.)
Hack #4: Die Silbentrennung überprüfen
7
#4
HACK
#4
Die Silbentrennung überprüfen
hyphen_show versucht, aus einer DVI-Datei die Silbentrennungen zu rekon-
struieren. Ganz einfach ist das nicht, da in einer DVI-Datei keine Angaben über eine Zeilenstruktur des Dokuments enthalten sind. Stattdessen muss hyphen_show im Wesentlichen Wörter finden, die mit einem Trennstrich aufhören und rechts von denen nichts anderes mehr steht. Mit einiger Wahrscheinlichkeit kann es dann auch den zweiten Teil des Worts aufspüren, aber hin und wieder täuscht es sich leider auch – etwa bei einer Trennung in der letzten Zeile einer Seite, wenn es eine Fußzeile mit Text gibt. Aber es ist eine durchaus hilfreiche Sache. Um die Silbentrennungen in einer DVI-Datei zu überprüfen, übergeben Sie dem Programm hyphen_show deren Dateinamen: $ hyphen_show hytest.dvi
Die Ausgabe könnte dann so aussehen: hyphen_show version 25.4.2000 coding: T1 same words are given only once [1] Kraftfahr-zeugwerkstätzeugwerkstät-te Hundeku-chenfabrik Gurkensalat-schüssel Af-fenbrotbaumfenbrotbaum-wurzel Lager-hallenverwalhallenverwal-tung Marzi-panbrotmesser number of hyphenations: already known/multiple:
9 0
In eckigen Klammern ist jeweils die Seitennummer angegeben, gefolgt von den Trennungen auf der betreffenden Seite. Diese können Sie dann bequem prüfen, ohne vom Rest des Textes abgelenkt zu werden. hyphen_show schreibt außerdem eine Datei mit demselben Namen wie die Eingabedatei, aber mit der Endung .hyp, in der nur die gefundenen Silbentrennungen (ohne Seitenzahlen und das andere Drumherum) stehen. Tritt dieselbe Silbentrennung mehr als einmal auf, gibt hyphen_show sie nur einmal aus. Um lästige Wiederholungen zu vermeiden, können Sie in der .hyp-Datei alle falschen Silbentrennungen löschen (etwa parallel zum Reparieren in der LATEX8
Kapitel 1: Texte
HACK
Die Silbentrennung überprüfen
Eingabedatei) und die Datei anschließend umbenennen, etwa so, dass sie die Endung .hypc hat. Beim nächsten Durchlauf können Sie hyphen_show diese Datei mit übergeben, das dann in der Ausgabe alle Silbentrennungen unterdrückt, die schon darin vorkamen. Auf diese Weise werden nur noch »neue« Trennungen ausgegeben, die Sie wiederum prüfen und an die Positivliste anhängen können: $ cat hytest.hypc Hundeku-chenfabrik Af-fenbrotbaumfenbrotbaum-wurzel $ hyphen_show hytest.dvi hytest.hypc hyphen_show version 25.4.2000 coding: T1 same words are given only once [1] Kraftfahr-zeugwerkstätzeugwerkstät-te Gurkensalat-schüssel Lager-hallenverwalhallenverwal-tung Marzi-panbrotmesser number of hyphenations: 9 already known/multiple: 3 $ cat hytest.hyp >>hytest.hypc $ hyphen_show hytest.dvi hytest.hypc hyphen_show version 25.4.2000 coding: T1 same words are given only once [1] number of hyphenations: already known/multiple:
9 9
Das kleine Shell-Skript hy in Abbildung 1-1 hilft Ihnen dabei, gemäß der Beobachtung »Eine richtige Trennung in Dokument x ist auch in Dokument y richtig« die für gut befundenen Trennungen mehrerer Dateien in einer zentralen »Datenbank«, einer Datei namens hyphens, zu sammeln. Vor jedem Lauf von hyphen_show auf einer Datei bla.dvi werden die Trennungen aus bla.hyp, sofern vorhanden, in die Datei hyphens übernommen. Der hyphen_show-Lauf benutzt dann hyphens zum Ausschluss der bereits gesehenen Trennungen. Sie Hack #4: Die Silbentrennung überprüfen
9
#4
HACK
#4
Die Silbentrennung überprüfen
#!/bin/sh dvi=‘basename $1 .dvi‘ [ -f hyphens ] || touch hyphens if [ -f $dvi.hyp ]; then before=‘wc -l >hyphens.0 \ && mv hyphens.0 hyphens echo >&2 ‘expr \‘wc -l {\(}c{\(}r{...}« links von einem Spaltenkürzel kennzeichnet Material, das an den Anfang des Spalteninhalts gesetzt wird. Ein »{\(}c{\(}c{\(}r{\(}l{\(}c{\(}r{\tt}cl} \multicolumn{1}{c}{Befehl} & Bedeutung \\ \hline LDA & Lade Akkumulator \\ STX & Speichere X-Register\\ BCC & Verzweige, falls kein Übertrag \end{tabular}
Kapitel 4: Tabellen und Abbildungen
HACK
Noch mehr leidige Kommas HACK
#36
Noch mehr leidige Kommas Richten Sie Dezimalzahlen in Tabellen an ihrem Komma aus.
In der Tabelle aus dem vorigen Hack haben wir bei den Zahlen ein bisschen geschummelt – wir haben die Spalte rechtsbündig gesetzt und darauf geachtet, immer dieselbe Anzahl von Nachkommastellen anzugeben. Das funktioniert aus zwei Gründen: • Bei transzendenten Zahlen wie e und π haben wir die Wahl, wie viele Stellen wir angeben wollen (alle passen sowieso nicht ins Buch). • Die Ziffern in unserer »Brotschrift« sind alle gleich breit.
Die letztere Eigenschaft ist sehr wichtig; gut entworfene Schriften sollten zumindest wahlweise einen Satz »Tabellenziffern« bereithalten, um eben das Ausrichten von Zahlen in Tabellen zu erleichtern. Im wirklichen Leben hat man diesen Luxus nicht immer. Insbesondere steht es uns keineswegs frei, die Anzahl von angegebenen Ziffern zwecks Optik-Optimierung zu wählen: Aus der Sicht des Mathematikers sind 1 m und 1,000 m dasselbe. Physiker und Ingenieure sehen das aber überhaupt nicht so, denn »1 m« kann (in Abwesenheit genauerer Spezifikationen) für alles zwischen 50 cm und 1,50 m stehen, »1,000 m« dagegen impliziert Genauigkeit auf den Zehntelmillimeter. Das Auffüllen mit Nullen, damit alle Werte gleich breit sind, ist also ein absolutes No-No, wenn nicht ausdrücklich klar ist, dass es keine unangenehmen semantischen Nebeneffekte hat. Also müssen wir uns anders helfen. Der klassische Hack sieht ungefähr so aus: Stellen 1 2 3 4
Wert 1,1 2,22 33,333 444,4444
\begin{tabular}{cr@{,}l} Stellen & \multicolumn{2}{c}{Wert} \\ \hline 1 & 1&1 \\ 2 & 2&22 \\ 3 & 33&333 \\ 4 & 444&4444 \end{tabular}
Der Trick besteht darin, den Zahlenwert in zwei Teile (den ganzzahligen und den gebrochenen) aufzuteilen, die wir dann rechtsbündig respektive linksbündig in der Tabelle platzieren. Das Komma wird über das »@{,}« nachgetragen, mit dem Sie Material angeben können, das zwischen zwei Spalten landet. Dieser Ansatz funktioniert, ist aber aus verschiedenen Gründen unbequem. Zum einen ist es lästig, alle Zahlen anpassen zu müssen. Bei einer kleinen Ta-
Hack #36: Noch mehr leidige Kommas
109
#36
HACK
#36
Noch mehr leidige Kommas
belle wie dieser mag es noch angehen, aber wenn Sie eine große Tabelle haben, deren Einträge möglicherweise noch von einer anderen Software erzeugt wurden, grenzt das ans Menschenunwürdige. Zum anderen ist die Verwaltung der Spalten ein Ärgernis. Sie müssen daran denken, jede numerische Spalte durch die »r@{,}l«-Konstruktion zu ersetzen, und auch die Kopfzeile wird umständlicher (beachten Sie, dass wir im Beispiel oben wieder mal \multicolumn zu Hilfe nehmen mussten). Unschön ist auch, dass Werte ohne Komma auf jeden Fall eins angehängt bekommen, selbst wenn danach gar keine Stellen folgen. Ein Paket, das dieses Problem eleganter und vielseitiger löst, ist dcolumn von David Carlisle. Es stellt ein spezielles Spaltenkürzel zur Verfügung, mit dem wir die Tabelle wie folgt schreiben können: Stellen 1 2 3 4
Wert 1,1 2,22 33,333 444,4444
\begin{tabular}{cD{.}{,}{4}} Stellen & \multicolumn{1}{c}{Wert} \\ \hline 1 & 1.1 \\ 2 & 2.22 \\ 3 & 33.333 \\ 4 & 444.4444 \end{tabular}
Wie Sie sehen, funktioniert die Ausrichtung jetzt auch ohne eine spezielle Anpassung der Zahlenwerte. Wenn Sie genau hinschauen, sehen Sie auch einen weiteren Effekt: In der Eingabe für die Tabelle haben die Werte Dezimalpunkte, während in der LATEX-Ausgabe Dezimalkommas verwendet werden. Das macht es möglich, die Ausgabe von Tabellenkalkulations- oder ähnlichen Programmen unmodifiziert zu verwenden – eine gute Sache. Normalerweise möchten Sie alle numerischen Spalten in einer Tabelle mit demselben Dezimaltrenner ausstatten. Um diesen nicht immer wieder angeben zu müssen, können Sie eine Abkürzung für die »D«-Spaltendefinition einführen: \newcolumntype{d}[1]{D{.}{,}{#1}}
Das \newcolumntype-Kommando erlaubt wie \newcommand die Angabe von Parametern; hier akzeptiert es einen Parameter, der die Anzahl von Nachkommastellen angibt. Sie können hier (und bei »D«) übrigens auch einen negativen Wert oder zwei durch einen Punkt getrennte Werte angeben. Im ersten Fall wird der Dezimaltrenner in der Mitte einer Spalte zentriert, die breit genug ist, um alle Werte aufzunehmen, während im zweiten Fall eine Zahl mit der angegebenen Anzahl von Vor- und Nachkommastellen zentriert wird. Vergleichen Sie die drei Spalten im folgenden Beispiel:
110
Kapitel 4: Tabellen und Abbildungen
HACK
Tabellenspalten mit variabler Breite
1,23 234,5 9,8765 11 0,9
1,23 234,5 9,8765 11 0,9
1,23 234,5 9,8765 11 0,9
\begin{tabular}% {|d{4}|d{-1}|d{3.4}|} 1.23 & 1.23 & 1.23 \\ 234.5 & 234.5 & 234.5 \\ 9.8765 & 9.8765 & 9.8765 \\ 11 & 11 & 11 \\ 0.9 & 0.9 & 0.9 \end{tabular}
Die mittlere Spalte ist breiter als nötig, da sie auf vier Stellen links und rechts vom Dezimaltrenner geeicht ist. Die linke (rechtsbündige) Spalte sieht vernünftig aus, aber wenn Sie eine breite (zentrierte) Tabellenüberschrift und darunter viele kleine rechtsbündig formatierte Zahlen haben, kann das auch eigenartig wirken. In so einem Fall ist die Methode aus der rechten Spalte vorzuziehen.
Siehe auch • Es gibt auch noch das rccol-Paket von Eckhart Guthöhrlein. rccol unterstützt die Formatierungsmöglichkeiten von dcolumn, erlaubt aber außerdem das automatische Runden von Zahlen auf eine angegebene Anzahl von Dezimalstellen.
HACK
#37
Tabellenspalten mit variabler Breite Wie Sie Fließtext in Tabellen unterbringen, ohne graue Haare zu bekommen.
In LATEX-Tabellen konnten Sie schon immer Fließtext in »p«-Spalten unterbringen. Nur mussten Sie genau festlegen, wie breit diese Spalten sein sollten – eine lästige Sache. Das tabularx-Paket von David Carlisle führt die tabularx-Umgebung und ihre »X«-Spalten ein.
Flexible Spalten mit tabularx Die tabularx-Umgebung ähnelt tabular*, da Sie bei beiden die gewünschte Gesamtbreite der Tabelle angeben müssen. Während bei tabular* aber alle Spalten ihre »natürliche« Breite bekommen (die Breite des breitesten Inhalts bei »l«, »r« & Co., die vorher angegebene Breite bei »p«) und die gewünschte Gesamtbreite durch flexiblen Leerraum zwischen den Spalten erreicht wird, sollten Sie bei tabularx mindestens eine »X«-Spalte angeben, die dann genau die Breite zugeordnet bekommt, die nicht von anderen Spalten beansprucht wird. Material in »X«-Spalten wird behandelt, als ob es in einer »p«-Spalte stünde, also als Fließtext mit Umbruch gesetzt:
Hack #37: Tabellenspalten mit variabler Breite
111
#37
HACK
#37
Tabellenspalten mit variabler Breite
Deutsch
Englisch
Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz. She sells C shells by the sea shore.
\begin{tabularx}{5.5cm}{|l|X|} Deutsch & Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz. \\ Englisch& She sells C shells by the sea shore. \end{tabularx}
Sind in einer Tabelle mehrere »X«-Spalten enthalten, teilen sie sich gerecht den verfügbaren Platz: Deutsch
Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz.
Blaukraut bleibt Blaukraut und Brautkleid bleibt Brautkleid
\begin{tabularx}{5.5cm}{|l|X|X|} Deutsch & Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz. & Blaukraut bleibt Blaukraut und Brautkleid bleibt Brautkleid \\ \end{tabularx}
Aber Sie können dabei tricksen: Mit der Definition >{\setlength{\hsize}{.66\hsize}}X% >{\setlength{\hsize}{1.34\hsize}}X
erreichen Sie, dass die erste von zwei »X«-Spalten halb so breit ist wie die zweite. Sie können die Verhältnisse beliebig verschieben, solange sich die Anteile zur Gesamtbreite der »X«-Spalten aufaddieren. In diesem Beispiel sind zwei »X«-Spalten im Spiel, die Summe der Anteile muss also 2 ergeben. Der LATEX Companion von Frank Mittelbach u. a. (Addison-Wesley 2004), in dem diese Technik erklärt wird, rät außerdem dringend davon ab, \multicolumn-Kommandos zu benutzen, die solche Spalten überspannen. Noch ein Wort der Warnung: tabularx arbeitet, indem es die Tabelle mehrfach testhalber setzt, bis es eine Spaltenbreite findet, die passt. Nicht alles, was Sie in eine Tabelle schreiben können, freut sich darüber, mehrfach gesetzt zu werden. Wenn Sie zum Beispiel innerhalb der Tabelle etwas in eine externe Datei schreiben, könnte es sein, dass Sie es dann später mehrmals dort vorfinden.
112
Kapitel 4: Tabellen und Abbildungen
HACK
Tabellenspalten mit variabler Breite
Denn wer da hat, dem wird gegeben werden – tabulary Das tabulary-Paket, ebenfalls von David Carlisle, realisiert ein anderes Verfahren zur Aufteilung variabler Tabellenspalten. Es führt einige neue Spaltentypen ein (siehe Tabelle 4-1), die im Wesentlichen so funktionieren, dass Spalten mit langen Einträgen eine größere Breite zugesprochen bekommen und Spalten mit kurzen Einträgen schmaler ausfallen. Betrachten Sie das folgende Beispiel: 1
2
Deutsch Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz. Eng- She sells C shells by the lisch sea shore.
\begin{tabulary}{5.5cm}{|R|L|J|} 1 & Deutsch & Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz. \\ 2 & Englisch& She sells C shells by the sea shore. \end{tabulary}
Dabei kommt offenbar die zweite Spalte schlecht weg. Dieses Problem können Sie beheben, indem Sie entweder einen »normalen« Spaltentyp (etwa »c«) verwenden, damit die Spalte ihre »natürliche« Breite bekommt, oder Sie setzen den Parameter \tymin auf einen ausreichend großen Wert (Standard ist 10pt). \tymin gibt eine Grenze vor, so dass schmalere Spalten mit ihrer natürlichen Breite gesetzt werden. 1
Deutsch
2
Englisch
Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz. She sells C shells by the sea shore.
\setlength{\tymin}{5em} \begin{tabulary}{5.5cm}{|R|L|J|} 1 & Deutsch & Fischers Fritz fischt frische Fische. Frische Fische fischt Fischers Fritz. \\ 2 & Englisch& She sells C shells by the sea shore. \end{tabulary}
Tabelle 4-1: Spaltentypen für tabulary Zeichen J L C R
Bedeutung Umbrochener Text mit Blocksatz Linksbündig gesetzter umbrochener Text Zentriert gesetzter umbrochener Text Rechtsbündig gesetzter umbrochener Text
Hack #37: Tabellenspalten mit variabler Breite
113
#37
HACK
#38
Farblich passend
Umgekehrt gibt es einen Parameter \tymax, der verhindert, dass Spalten mit besonders langem Inhalt alle anderen Spalten platt drücken. Alle Spalten, die breiter als \tymax wären, wenn man sie in einer einzigen Zeile setzte, werden gleich breit gemacht, wobei sie in die Berechnung so eingehen, als sei ihre Breite genau \tymax. Der Standardwert für \tymax ist – etwas willkürlich – die doppelte Textbreite des Dokuments. Der Vorteil von tabulary gegenüber tabularx und tabular* ist, dass es mit sehr wenig Handarbeit auskommt. (tabularx ist da auch schon nicht schlecht, wenn Sie sich mit dem Gedanken anfreunden können, dass alle »X«-Spalten gleich breit sind – ansonsten wird es unappetitlich.) Es kommt daher Situationen entgegen, wo LATEX-Eingaben automatisch generiert werden, etwa aus einer Datenbank. Ganz wie tabularx setzt auch tabulary die Tabelle mehrmals, nämlich genau zweimal. Auch hier ist also Vorsicht mit Material angebracht, das Sachen in Dateien schreibt. Da tabularx seine Tabellen möglicherweise öfter als zweimal setzen muss, ist tabulary potenziell schneller.
HACK
#38
Farblich passend Unterlegen Sie Tabellenzeilen oder -spalten mit Farben.
Erschwingliche Farb-Tintenstrahl- und -Laserdrucker haben die farbige Ausgabe halbwegs bezahlbar gemacht, und auch Graustufen sind schon mehr »Farbe«, als TEX-Anwender traditionell gewöhnt sind. Als TEX neu war, war Farbe noch gar kein Thema, und die LATEX-Entwickler haben einige Mühe auf sich genommen, um LATEX an den Einschränkungen von TEX vorbei fit für Farbe zu machen. Auch beim Tabellensatz greift Farbe mehr und mehr um sich. Hier zeigen wir Ihnen einige grundlegende Techniken, mit denen Sie Ihre Tabellen hübscher (?) machen können.
Spalteninhalte färben Am einfachsten ist sicher das Färben von Spalteninhalten, wenn Sie sich an die Technik erinnern, mit der wir »mathematische« Spalten [Hack #35] realisiert haben. Fügen Sie einfach am Anfang des Spalteninhalts ein \color-Kommando mit der gewünschten Farbe ein:
114
Kapitel 4: Tabellen und Abbildungen
HACK
Farblich passend
Frucht Möhre Banane Pflaume Mango
Farbe orange gelb blau bunt
#38
\begin{tabular}{l>{\color{red}}l} Frucht & Farbe \\ \hline Möhre & orange \\ Banane & gelb \\ Pflaume& blau \\ Mango & bunt \end{tabular}
(Aus drucktechnischen Gründen erscheint die rechte Spalte hier nicht wirklich rot.) Wenn Sie den Hintergrund der Spalte färben wollen, sollten Sie das Paket colortbl von David Carlisle verwenden, das ein \columncolor-Kommando definiert: Frucht Möhre Banane Pflaume Mango
Farbe orange gelb blau bunt
\begin{tabular}{l% >{\columncolor{red}\color{white}}l} Frucht & Farbe \\ \hline Möhre & orange \\ Banane & gelb \\ Pflaume& blau \\ Mango & bunt \end{tabular}
colortbl kooperiert mit den meisten Tabellen-Paketen wie dcolumn, tabularx oder longtable. Bei tabular* ist mitunter ein manuelles Eingreifen angesagt – die colortbl-Dokumentation erklärt das ausführlicher.
Zeileninhalte färben Das Färben von Zeileninhalten ist etwas komplizierter, aber dank David Carlisle bekommen wir davon nicht wirklich etwas mit. Sie können die Hintergrundfarbe einer Zeile festlegen, indem Sie ein \rowcolor-Kommando an den Anfang setzen: Frucht Möhre Banane Pflaume Mango
Farbe orange gelb blau bunt
\begin{tabular}{l>{\color{red}}l} \rowcolor[gray]{0.6} Frucht & Farbe \\ \hline Möhre & orange \\ Banane & gelb \\ Pflaume& blau \\ Mango & bunt \end{tabular}
\rowcolor hat übrigens Vorrang gegenüber \columncolor, wenn ein Tabellen-
eintrag von beiden betroffen ist. Hack #38: Farblich passend
115
HACK
#38
Farblich passend
Modisch (wenn auch vom ästhetischen Standpunkt aus gesehen zumindest fragwürdig) sind Tabellen, bei denen die Zeilen abwechselnd mit verschiedenen Farben hinterlegt sind. Das funktioniert natürlich mit \rowcolor:
Frucht Möhre Banane Pflaume Mango
Farbe orange gelb blau bunt
\newcommand*{\oddrow}{\rowcolor[gray]{0.7}} \newcommand*{\evnrow}{\rowcolor[gray]{0.9}} \begin{tabular}{l>{\color{red}}l} \rowcolor[gray]{0.6} Frucht & Farbe \\ \hline \oddrow Möhre & orange \\ \evnrow Banane & gelb \\ \oddrow Pflaume & blau \\ \evnrow Mango & bunt \end{tabular}
Wirklich bequem einzugeben ist das aber nicht. Es wäre netter, wenn LATEX sich selbst um das Färben der Zeilen kümmern würde. Die Strategie, die wir dafür vorschlagen, fällt eindeutig in die Kategorie »fieser Hack«, aber sie ist wirkungsvoll. Sie beruht auf der Überlegung »Wie können wir am Anfang jeder Zeile etwas einbauen, das die passende Farbe setzt?« und bringt uns zu dem Schluss, dass wir nicht wirklich Zugriff auf den Anfang jeder Zeile haben, aber auf das Ende der Zeile davor. Entsprechend definieren wir »\\« so um, dass es außer seiner üblichen Aufgabe (eine Tabellenzeile abzuschließen) noch etwas für uns erledigt, nämlich eine neue Tabellenzeile mit einem passenden \rowcolor zu beginnen. Der Haken an der Sache ist, dass es sehr schwierig ist, sich so in »\\« einzuklinken, dass es noch als Zeilenende-Marke funktioniert, ohne es komplett umzudefinieren, und Letzteres ist aufgrund der Natur von LATEX nur »global« möglich – mit dem Nebeneffekt, dass die Neudefinition auch nach der Tabelle gültig bleibt und an anderen Stellen Ärger macht. Ebenso wenig ist es möglich, im Stil von \AtEndDocument Kommandos zur Ausführung am Ende einer Tabelle vorzumerken; \AtEndTabular ist leider noch nicht erfunden worden. Wir ziehen uns damit aus der Affäre, dass wir zwei Kommandos (\colorrows und \nocolorrows) definieren, die wie folgt zu verwenden sind: \begin{tabular}{l>{\color{red}}l} \rowcolor[gray]{0.6} Frucht & Farbe \colorrows Möhre & orange \\ Banane & gelb \\ Pflaume & blau \\ Mango & bunt \nocolorrows \end{tabular}
116
Kapitel 4: Tabellen und Abbildungen
HACK
Farblich passend
Das heißt, ab dem Auftreten von \colorrows werden die Zeilen alternierend gefärbt bis zum \nocolorrows, das unmittelbar vor dem Ende der Tabelle stehen muss. Die beiden Kommandos benehmen sich außerdem wie \\. (Man könnte das fast als Vorteil hinstellen.) Eine wichtige Einschränkung ist auch, dass das \\-Kommando innerhalb eines \colorrows. . . \nocolorrows kein optionales Argument unterstützt (eine Konsequenz der Neudefinition). Nun aber zum eigentlichen Code. Betrachten wir zunächst das \colorrowsKommando: \newcounter{rowcounter} \newcommand*{\colorrows}{ \setcounter{rowcounter}{0}% \global\let\crs@cr=\\% \gdef\\{\crs@nextrow}% \crs@nextrow }
Der Zähler \rowcounter wird, solange \colorrows aktiv ist, für jede Zeile der Tabelle erhöht. Wir reißen uns das \\-Kommando unter den Nagel, nachdem wir die aktuelle Bedeutung in \crs@cr zwischengespeichert haben. (Wenn wir im LATEX-Quellcode nachsehen, finden wir dort das Kommando \@tabularcr als eigentliche Bedeutung von \\ in Tabellen, aber darauf können wir uns nicht verlassen – wenn das array-Paket aktiv ist, wird \\ anders realisiert. Darum ist es sicherer, die im jeweiligen Moment gültige Bedeutung zu speichern.) Das Kommando \crs@nextrow übernimmt die Zeilenschaltung mit Einfärben: \newcommand{\crs@nextrow}{% \stepcounter{rowcounter}% \ifthenelse{\isodd{\value{rowcounter}}}% {\crs@cr\rowcolor[gray]{0.8}}% {\crs@cr\rowcolor[gray]{0.9}}}
Hier wird der \rowcounter zuerst erhöht und dann getestet. Da das \rowcolorKommando an erster Stelle am Anfang einer Tabellenzeile stehen muss, führen wir unmittelbar davor das gespeicherte \crs@cr aus. Schließlich fehlt uns noch \nocolorrows: \AtBeginDocument{\let\crs@dblbs=\\} \newcommand*{\nocolorrows}{\global\let\\=\crs@dblbs}
Wir merken uns das »globale« \\ am Anfang des Dokuments – in der Hoffnung, dass alle Pakete, die das Kommando noch umdefinieren wollten, dann ihre Änderungen angebracht haben. Da wir innerhalb einer Tabelle (wo wir
Hack #38: Farblich passend
117
#38
HACK
#39
Überlang und überbreit
\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{colorrows}% [2007/01/03 v0.1 Alternately-colored rows (AL)] \RequirePackage{colortbl} \RequirePackage{ifthen} \newcounter{crs@counter} \newcommand{\crs@nextrow}{% \stepcounter{crs@counter}% \ifthenelse{\isodd{\value{crs@counter}}}% {\crs@cr\rowcolor[gray]{0.8}}% {\crs@cr\rowcolor[gray]{0.9}}} \newcommand*{\colorrows}{ \setcounter{crs@counter}{0}% \global\let\crs@cr=\\% \gdef\\{\crs@nextrow}% \crs@nextrow } \let\crs@dblbs=\\ \newcommand*{\nocolorrows}{\global\let\\=\crs@dblbs\crs@cr} \endinput Abbildung 4-1: Das colorrows-Paket
\colorrows ausführen) nicht an die globale Bedeutung herankommen, können wir auch kaum anders. \nocolorrows setzt \\ wieder auf seine ursprüngliche
Bedeutung zurück. Abbildung 4-1 zeigt den kompletten Code als LATEX-Paket.
Siehe auch • Das xcolor-Paket von Uwe Kern unterstützt ein \rowcolors-Kommando, das die Verwendung alternierender Farben automatisiert: \rowcolors{2}{\rowcolor[gray]{0.8}}{\rowcolor[gray]{0.9}}
färbt alle Zeilen beginnend mit der zweiten abwechselnd hellgrau und dunkelgrau wie in unserem Beispiel.
HACK
#39
Überlang und überbreit Strategien für den Umgang mit Tabellen, die nicht passen wollen
Manchmal hat man es mit Tabellen zu tun, die einfach nicht passen wollen. Entweder sind sie zu hoch für eine Seite oder zu breit (oder, Horror, beides). 118
Kapitel 4: Tabellen und Abbildungen
HACK
Überlang und überbreit Tabelle 1: Die Staaten der Erde Land Afghanistan Ägypten Albanien Algerien Andorra Angola Antigua und Barbuda Äquatorialguinea Argentinien Armenien Aserbaidschan Äthiopien Australien Bahamas Bahrain Bangladesch Barbados Belgien Belize Benin Bhutan Bolivien Bosnien-Herzegowina Botswana Brasilien Brunei Bulgarien Burkina Faso Burundi Chile China Costa Rica Dänemark Deutschland Dominika Dominikanische Republik Dschibuti Ecuador El Salvador Elfenbeinküste Eritrea Estland Fidschi Finnland Frankreich Gabun
Hauptstadt Einwohner Fläche [km2 ] Kabul 31,1 Mio. 652.226 Kairo 77,5 Mio. 1.001.000 Tirana 3,6 Mio. 28.748 Algier 32,9 Mio. 2.380.000 Andorra la Vella 76.875 453 Luanda 14,0 Mio. 1.250.000 Saint John’s 69.108 442 Malabo 523.051 28.051 Buenos Aires 38,6 Mio. 2.780.000 Jerewan 3,0 Mio. 29.800 Baku 8,3 Mio. 86.600 Addis Abeba 73,1 Mio. 1.100.000 Canberra 20,6 Mio. 7.740.000 Nassau 303.770 13.878 Manama 688.345 694 Dhaka 147,4 Mio. 143.998 Bridgetown 279.912 430 Brüssel 10,4 Mio. 30.519 Belmopan 301.750 22.696 Porto Novo 7,3 Mio. 112.622 Thimphu 672.425 47.000 Sucre 9,0 Mio. 1.100.000 Sarajevo 4,0 Mio. 51.129 Gaborone 1,6 Mio. 581.730 Brasilia 184,3 Mio. 8.500.000 Bandar Seri Begawan 372.361 5.765 Sofia 7,7 Mio. 110.912 Ouagadougou 14,0 Mio. 274.000 Bujumbura 7,8 Mio. 27.834 Santiago de Chile 16,1 Mio. 756.626 Peking 1,314 Mrd. 9.560.000 San José 4,1 Mio. 51.100 Kopenhagen 5,6 Mio. 43.094 Berlin 82,4 Mio. 357.022 Roseau 68.910 751 Santo Domingo 9,2 Mio. 48.734 Dschibuti-Stadt 767.393 23.200 Quito 13,5 Mio. 283.561 San Salvador 6,8 Mio. 21.041 Yamoussoukro 17,7 Mio. 322.463 Asmara 4,4 Mio. 121.144 Tallinn 1,3 Mio. 45.100 Suva 898.354 18.274 Helsinki 5,2 Mio. 338.145 Paris 60,7 Mio. 543.965 Libreville 1,4 Mio. 267.668 Fortsetzung auf der nächsten Seite 1
Land Litauen Luxemburg Madagaskar Malawi Malaysia Malediven Mali Malta Marokko Marshallinseln Mauretanien Mauritius Mazedonien Mexiko Mikronesien Moldawien Monaco Mongolei Montenegro Mosambik Myanmar Namibia Nauru Nepal Neuseeland Nicaragua Niederlande Niger Nigeria Norwegen Oman Österreich Osttimor Pakistan Palau Panama Papua-Neuguinea Paraguay Peru Philippinen Polen Portugal Ruanda Rumänien Russland St. Kitts und Nevis Saint Lucia Saint Vincent & Grenadinen
Hauptstadt Einwohner Fläche [km2 ] Wilna 3,4 Mio. 65.200 Luxemburg-Stadt 474.413 2.586 Antananarivo 17,5 Mio. 587.041 Lilongwe 12,2 Mio. 118.484 Kuala Lumpur 24,0 Mio. 329.758 Malé 298.842 298 Bamako 12,3 Mio. 1.240.192 Valletta 398.534 316 Rabat 33,2 Mio. 446.550 Delap-Uliga-Darrit 61,963 181 Nouakchott 2,8 Mio. 1.025.520 Port Louis 1,2 Mio. 2.040 Skopje 2,1 Mio. 26.713 Mexiko-Stadt 106,2 Mio. 1.960.000 Palikir 108.105 702 Chi?in?u 4,5 Mio. 33.843 Monaco 32.300 2 Ulaanbaatar 2,8 Mio. 1.570.000 Podgorica 630.548 13.812 Maputo 19,4 Mio. 801.590 Pyinmana 54,0 Mio. 676.578 Windhoek 2 Mio. 824.292 Yaren 12.600 21 Kathmandu 25,2 Mio. 147.181 Wellington 4 116 900. 270.534 Managua 5,5 Mio. 130.000 Amsterdam 16,1 Mio. 41.500 Niamey 12 Mio. 1.270.000 Abuja 124 Mio. 923.768 Oslo 4,68 Mio. 323.877 Maskat 2,9 Mio. 212.457 Wien 8,1 Mio. 83.853 Dili 779.000 15.470 Islamabad 153,6 Mio. 796.095 Melekeok 19.717 487 Panama-Stadt 3,1 Mio. 75.517 Port Moresby 5,7 Mio. 462.840 Asunción 5,9 Mio. 406.752 Lima 27,2 Mio. 1.290.000 Manila 80 Mio. 300.000 Warschau 38,6 Mio. 312.685 Lissabon 10,1 Mio. 91.982 Kigali 8,4 Mio. 26.338 Bukarest 22,3 Mio. 238.391 Moskau 143,2 Mio. 17.000.000 Basseterre 38.800 261 Castries 162.000 622 Kingstown 116.812 388 Fortsetzung auf der nächsten Seite 3
Land Vietnam Weißrussland Zentralafrikan. Republik Zypern
Hauptstadt Hanoi Minsk Bangui Nikosia
Einwohner 81,4 Mio. 9,3 Mio. 3,9 Mio. 797.000
Fläche [km2 ] 331.689 207.600 622.984 9.251
5
Abbildung 4-2: Eine überlange Tabelle mit longtable
LATEX tut sich damit schwerer als manch andere Programme, da zumindest tabular-Umgebungen (und ihre Verwandten) aus der Sicht von LATEX so etwas sind wie große Buchstaben – unteilbare Kästen, die entweder ganz passen oder gar nicht.
Überlange Tabellen Tabellen, die länger sind als eine Seite, können Sie nicht mit tabular & Co. setzen, es sei denn, Sie teilen sie manuell auf. Selbst dann sehen sie wahrscheinlich eigenartig aus, da nicht garantiert ist, dass die Spalten in beiden Tabellen jeweils gleich breit sind – der Leser muss sich also erst vergewissern, dass es sich tatsächlich um zwei Stücke derselben Tabelle handelt. Andere Hilfsmittel sind gefragt, etwa das longtable-Paket von David Carlisle (ja, schon wieder) und David Kastrup. longtable kommt mit Tabellen zurecht, die länger als eine Seite sind, indem es von LATEX-Lauf zu LATEX-Lauf Informationen über die Spaltenbreiten in der aux-Datei sichert. Auf diese Weise kann es auch erreichen, dass die Spaltenbreiten der Tabelle auf allen Seiten, wo Stücke der Tabelle stehen, identisch sind. longtable-Tabellen sind eine Art Mittelding zwischen tabular-Tabellen und gleitenden Tabellen, wie Sie sie mit table definieren (die ja in der Regel auch etwas wie eine tabular-Umgebung enthalten). longtable-Tabellen können wie tables eine Legende (\caption) haben, werden wie tables gezählt und auch
Hack #39: Überlang und überbreit
119
#39
HACK
#39
Überlang und überbreit
ins Tabellenverzeichnis des Dokuments eingetragen, sofern Sie eins erzeugen lassen. Hier ist ein Beispiel für so eine Tabelle: \begin{longtable}{llrr} \caption{Die Staaten der Erde}\\ %% Quelle: Wikipedia. \bfseries Land & Hauptstadt & Einwohner & Fläche [km2] \\ \hline \endfirsthead \bfseries Land & Hauptstadt & Einwohner & Fläche [km2] \\ \hline \endhead \hline \multicolumn{4}{r}{\emph{Fortsetzung auf der nächsten Seite}} \endfoot \hline \endlastfoot Afghanistan & Kabul & 31,1 Mio. & 652.226 \\ Ägypten & Kairo & 77,5 Mio. & 1.001.000 \\ Albanien & Tirana & 3,6 Mio. & 28.748 \\ Algerien & Algier & 32,9 Mio. & 2.380.000 \\ Andorra & Andorra la Vella & 76.875 & 453 \\ ... Weißrussland & Minsk & 9,3 Mio. & 207.600 \\ Zentralafrikan. Republik & Bangui & 3,9 Mio. & 622.984 \\ Zypern & Nikosia & 797.000 & 9.251 \\ \end{longtable}
(Die entsprechende LATEX-Ausgabe sehen Sie in Abbildung 4-2.) Interessant bei longtable ist die Behandlung der Kopf- und Fußzeilen. Wenn Sie sich Abbildung 4-2 genau anschauen, sehen Sie (selbst bei dieser Verkleinerung), dass es zwei verschiedene Arten von Kopfzeilen wie auch zwei Arten von Fußzeilen gibt – eine Kopfzeile für die erste Seite und eine weitere für alle Folgeseiten sowie eine Fußzeile für die erste bis zur vorletzten Seite und eine weitere für die letzte Seite. Alle diese Kopf- und Fußzeilen (die gerne auch aus mehr als einer Zeile in der Tabelle bestehen dürfen) werden am Anfang der longtable-Umgebung definiert; die Zeilen vom Anfang der Umgebung bis zum \endhead bilden die Kopfzeile, alles von da bis zum \endfoot die Fußzeile. Der Kopf für die erste Seite endet mit \endfirsthead, der Fuß für die letzte Seite mit \endlastfoot. Das \caption-Kommando benimmt sich so ähnlich wie bei den Umgebungen figure und table. In unserem Beispiel erscheint die Legende nur auf der ersten Seite der Tabelle. Es ist aber durchaus möglich, sie auf jeder Seite zu haben:
120
Kapitel 4: Tabellen und Abbildungen
HACK
Überlang und überbreit
\begin{longtable}{llrr} \caption{Die Staaten der Erde}\\ \bfseries Land & Hauptstadt & Einwohner & Fläche [km2] \\ \hline \endfirsthead \caption[]{Die Staaten der Erde (Forts.)}\\ \bfseries Land & Hauptstadt & Einwohner & Fläche [km2] \\ \hline \endhead
Beachten Sie dabei die »[]« in der zweiten \caption-Zeile. Normalerweise können Sie zwischen die eckigen Klammern einen Kurztitel für die Tabelle schreiben, der dann statt der eigentlichen Legende ins Tabellenverzeichnis übernommen wird. Ist dieser Kurztitel leer, dann trägt dieses \caption-Kommando gar nichts zum Tabellenverzeichnis bei, und das ist sicher besser als die Alternative, nämlich fünf Einträge für dieselbe Tabelle, nur weil sie über fünf Seiten geht. Sie könnten übrigens auch \caption*{Die Staaten der Erde (Forts.)}\\
schreiben; dann würde nichts ins Tabellenverzeichnis eingetragen, und außerdem fehlt in den Legenden auf der zweiten und den Folgeseiten auch die Tabellennummer. (Wir finden den »\caption[]«-Ansatz aber schöner.) Sollten Sie es mit superriesenlangen Tabellen zu tun bekommen (unsere Beispieltabelle ist mit 194 Zeilen schon nicht von schlechten Eltern, aber gegenüber einem Brachiosaurus sieht auch ein Elefant winzig aus), kann es passieren, dass der Speicher Ihres TEX-Systems nicht ausreicht, um die Tabelle zu formatieren. In diesem Fall ist es möglich, den Zähler LTchunksize auf einen geeigneten Wert zu setzen (mit \setcounter), so dass LATEX nur LTchunksize Zeilen auf einmal verdauen muss statt der kompletten Tabelle. Je größer diese Happen sind, desto schneller arbeitet LATEX, und bei heutigen TEX-Systemen kann LTchunksize durchaus ein paar Hundert Zeilen betragen. Eine Untergrenze gibt es nicht wirklich, außer dass LATEX immer langsamer wird, je kleiner die Häppchen sind – aber Sie sollten darauf achten, dass LTchunksize größer ist als die Summe der Zeilen in Ihren Kopf- und Fußbereichen plus ein paar tatsächliche Tabellenzeilen. (In der Regel ist das kein Problem.)
Überbreite Tabellen Aber was tun im Fall einer Tabelle, die nicht zu hoch ist, sondern zu breit? Die erste Überlegung, die sich anbietet, ist, sie zu kippen – die Zeilen zu Spalten zu machen und umgekehrt – und zu schauen, ob sie dann passt. Natürlich geht das nicht mit jeder Tabelle. Als Nächstes könnten Sie auf die Idee kommen, zu prüfen, ob die Tabelle nicht im Querformat auf der Seite unterzubringen ist. Das rotating-Paket von Sebastian Rahtz und Leonor Barroca bietet unter Hack #39: Überlang und überbreit
121
#39
HACK
#39
Überlang und überbreit
anderem die Umgebungen sidewaysfigure und sidewaystable, die figure und table entsprechen, aber ihren Inhalt quer stellen können. Voraussetzung dafür, dass das tatsächlich klappt, ist ein Ausgabeprogramm, das damit zurechtkommt – in heutigen LATEX-Distributionen sind das in der Regel dvips und pdfLATEX. Wir beschäftigen uns im Rest dieses Abschnitts mit sidewaystable; alles, was wir darüber sagen, gilt sinngemäß auch für sidewaysfigure. Die sidewaystable-Umgebung nimmt immer eine komplette Seite für sich ein. Dabei ist der Fuß der Tabelle immer rechts, es sei denn, Sie verwenden die twoside-Option – dann zeigt der Fuß der Tabelle auf linken Seiten nach links und auf rechten nach rechts, damit man die Tabelle immer von der Außenseite des Druckwerks her lesen kann. (Möglicherweise sind mehrere LATEX-Läufe nötig, um das richtig hinzukriegen. Lesen Sie in Links vs. rechts [Hack #27] nach, warum.) Alternativ können Sie eine der Optionen figuresright oder figuresleft angeben, um eine einzige Richtung festzulegen. Hier ist der Anfang der LATEX-Eingabe für Tabelle 4-2: \begin{sidewaystable} \setlength{\tymax}{8em} \caption{Ein Beispiel für \Env{sidewaystable}} \begin{tabulary}{\textwidth}{|r|CCCCCCC|} \hline &Pension Berta&Gästehaus Schulz&Hotel »Hirsch«& Kategorie & & & & * ** *** Einzelzimmer & 3 & 5 & 4 & Doppelzimmer & 5 & 5 & 10 & ...
... ... ... ...
Sie müssen sich nicht um die Breite der sidewaystable-Umgebung kümmern, da sie sowieso über die ganze Seite geht. Was das Material innerhalb der Umgebung angeht, so sorgt LATEX dafür, dass \textwidth und \columnwidth entsprechend angepasst werden – Sie können also, wie in diesem Beispiel mit der tabulary-Umgebung gezeigt, auf diese Werte Bezug nehmen, um den vergrößerten Platz auszunutzen. sidewaysfigure dreht die Legende der Tabelle zusammen mit der Tabelle.
Sie können auch nur die Tabelle drehen und die Legende so lassen, wie sie ist. Dazu verwenden Sie die sideways-Umgebung in einer gewöhnlichen table-Umgebung: \begin{table} \caption{Eine gedrehte Tabelle innerhalb einer normalen \Env{table}-Umgebung} \begin{sideways} \begin{tabular}{ll}
122
Kapitel 4: Tabellen und Abbildungen
Tabelle 4-2: Ein Beispiel für sidewaystable
Sonstiges
Gästehaus Schulz
Hotel »Hirsch«
Pension Waldruh
Hotel »Zur Post«
Hotel »Kaiserhof«
Golf-Resorthotel Kontinental
Hotel Löwen
* 3 5 1 ja nein nein nein gemeinsam nein ja EZ 25/N. DZ 35/N. Einfach
** 5 5 – nein nein nein nein gemeinsam nein ja EZ 36–40/N. DZ 50–60/N. Ruhige Lage
*** 4 10 2 ja nein nein ja Zimmer nein nein EZ 55–65/N. DZ 75–85/N. Zentral
** 4 8 2 ja ja nein ja Zimmer nein ja EZ 45–50/N. DZ 60–65/N. Sehr ruhig
*** 8 12 2 ja nein nein ja Zimmer ja ja EZ 62–75/N. DZ 85–105/N. Solide
*** 10 15 – ja ja ja ja Zimmer ja nein EZ 60–70/N. DZ 90–110/N. Gutbürgerlich
***** 10 25 5 ja ja ja ja Zimmer ja Tiefgarage EZ 150/N. DZ 220/N. Nobel
*** 5 12 2 ja ja ja ja Zimmer ja ja EZ 58–67/N. DZ 85–95/N. Einladend
123
Überlang und überbreit
Hack #39: Überlang und überbreit
Kategorie Einzelzimmer Doppelzimmer Dreibettzimmer Frühstück Halbpension Vollpension Zimmertelefon Fernsehen Minibar Parkplatz Zimmerpreis (Euro)
Pension Berta
#39
HACK
HACK
CSV-Dateien als Tabellen setzen
Haus Gryffindor Slytherin Ravenclaw Hufflepuff
Tabelle 4-3: Eine gedrehte Tabelle innerhalb einer normalen table-Umgebung
Name Harry Potter Draco Malfoy Cho Chang Justin Finch-Fletchley
#40
\tablehead \thead Name Harry Potter Draco Malfoy Cho Chang Justin Finch-Fletchley \tablefoot \end{tabular} \end{sideways} \end{table}
& & & & &
\thead Haus \\ Gryffindor \\ Slytherin \\ Ravenclaw \\ Hufflepuff \\
Das Ergebnis finden Sie in Tabelle 4-3.
HACK
#40
CSV-Dateien als Tabellen setzen Wie Sie LATEX die Ausgabe Ihrer Tabellenkalkulation schmackhaft machen können.
Vielleicht unterstützt Ihr Tabellenkalkulationsprogramm direkte Ausgabe im LATEX-Format. Wenn ja, sind Sie fein raus. Wenn nicht, dann können Sie sich auch aus der Klemme helfen, etwa indem Sie LATEX die Rudimente des CSV-Formats beibringen (denn das kann Ihr Tabellenkalkulationsprogramm bestimmt). »CSV« ist die Abkürzung für comma-separated values, also etwa »durch Kommas getrennte Werte«. Dieser Begriff hat sich eingebürgert, auch wenn heute statt Kommas meistens Semikolons verwendet werden, damit die Werte bequemer Kommas enthalten dürfen – jedenfalls bei Zahlen in der hierzulande üblichen Dezimalschreibweise mit Komma ein wesentlicher Faktor. Eine einfache CSV-Datei könnte aussehen wie Nr;Name;Bahnradius/AE;Durchmesser/km 1;Merkur;0,39;4878
124
Kapitel 4: Tabellen und Abbildungen
HACK
CSV-Dateien als Tabellen setzen
2;Venus;0,72;12104 3;Erde;1,00;12756 4;Mars;1,52;6794
So eine Datei taugt fast schon als Inhalt einer LATEX-tabular-Umgebung. Wir müssen LATEX nur dazu bringen, die Semikolons als Spaltentrenner (analog zu »&«) und das Zeilenende als »\\« zu interpretieren. Für Letzteres erinnern wir uns daran, dass LATEX das Zeilenende als »^^M« liest. Wir müssen also ^^M »aktiv« machen, damit wir ihm die Bedeutung von \\ geben können (denken Sie an die zeilenweise Verarbeitung von Eingabe in Aufgaben und Musterlösungen setzen [Hack #14]). Auch hier ist wieder der Haken, dass wir nicht genau wissen, wie \\ überhaupt definiert ist – je nachdem, ob Sie die Standard-Tabellenumgebung oder das array-Paket benutzen. Wir ziehen uns aus der Affäre, indem wir LATEX fragen: \setbox0=\hbox{% \begin{tabular}{c} \global\let\CsvNewline\\% \end{tabular}}
Wir machen eine Tabelle, deren einziger Existenzgrund darin besteht, uns die Bedeutung von \\ in \CsvNewline einfangen zu lassen. Die Tabelle selbst landet in einer \hbox, die wir anschließend ignorieren, damit LATEX sich nicht über Text vor dem \begin{document} aufregt. \CsvNewline ziehen wir dann zur Definition des aktiven Zeilenendes heran: {\catcode‘\^^M=\active % \gdef\CsvObeylines{\catcode‘\^^M=\active \let^^M=\CsvNewline}}%
Damit wir ^^M mit \let eine Bedeutung geben können, muss das ^^M schon aktiv sein, wenn wir \let aufrufen. Deswegen definieren wir das \CsvObeylinesKommando global innerhalb einer Gruppe, in der das gilt (die Technik ist auch in der Definition des LATEX-Kommandos \obeylines zu sehen, das benutzt wird, um die verbatim-Umgebung zu realisieren). Anschließend müssen wir nur noch ein Kommando definieren, das die CSVDatei liest und mit einer passenden Spaltenfestlegung als Tabelle formatiert. Hier ist ein Vorschlag dafür: \newcommand{\csvtabular}[2]{% \begingroup \CsvObeylines \catcode‘\;=4 \begin{tabular}{#1} \input{#2}
Hack #40: CSV-Dateien als Tabellen setzen
125
#40
HACK
#40
CSV-Dateien als Tabellen setzen
\end{tabular} \endgroup}
Mit dem »\catcode‘\;=4« erklären wir »;« zu einem Synonym für »&« – Spaltentrenner in Tabellen haben den \catcode 4. Das erste Argument des Kommandos ist die Formatangabe für die Tabelle, das zweite der Name der zu lesenden Datei. Das Kommando \csvtabular{rlrr}{planeten.csv}
sollte also ein Ergebnis liefern wie Nr 1 2 3 4
Name Merkur Venus Erde Mars
Bahnradius/AE 0,39 0,72 1,00 1,52
Durchmesser/km 4878 12104 12756 6794
Mit diesem Ansatz können wir schon viele CSV-Dateien verarbeiten. Haarig wird es aber da, wo das Trennzeichen für die Spalten selbst im Inhalt einer Spalte vorkommen darf. Die Konvention sagt, dass in so einem Fall der Wert der betreffenden Spalte in doppelten Anführungszeichen steht, etwa wie 3;"Erde; Mond";1,00;12756
Praktisch gesehen müssen wir, wenn wir beim Lesen der Tabelle auf ein doppeltes Anführungszeichen stoßen, die Sonderbedeutung des »;« zeitweilig aufheben. Beim nächsten doppelten Anführungszeichen schalten wir sie dann wieder ein. Die Definitionen dafür könnten zum Beispiel so aussehen: {\catcode‘\"=\active \gdef\CsvMagicQuote{\catcode‘\"=\active \let"=\CsvSepOff}% \gdef\CsvSepOff{\catcode‘\;=12 \let"=\CsvSepOn}% \gdef\CsvSepOn{\catcode‘\;=4 \let"=\CsvSepOff}}%
Das Kommando \CsvSepOff macht »;« zum normalen Zeichen und sorgt dafür, dass das nächste doppelte Anführungszeichen »;« wieder zum Spaltentrenner erklärt. Umgekehrt macht \CsvSepOn »;« zum Spaltentrenner und arrangiert, dass das nächste doppelte Anführungszeichen »;« wieder zum normalen Zeichen macht. Auch hier gilt, dass das doppelte Anführungszeichen zum Zeitpunkt der Definition dieser Kommandos schon »aktiv« sein muss. Das Kommando \CvsMagicQuote spielt eine ähnliche Rolle wie \CvsObeylines, indem es zum Einschalten der Funktion unmittelbar vor dem Einsatz dient – gerade im Fall des doppelten Anführungszeichens ist das wichtig, da sonst Pakete wie babel oder german es monopolisieren. So wie die Dinge hier stehen, sollten 126
Kapitel 4: Tabellen und Abbildungen
HACK
CSV-Dateien als Tabellen setzen
die CSV-Dateien keine Babel-Funktionen für deutsche Umlaute und Ähnliches in Anspruch nehmen; innerhalb einer CSV-Datei gehört das doppelte Anführungszeichen der CSV-Datei! Etwas wie 1;"W"are katastrophal";4711
ist weder korrektes CSV noch korrektes Babel. Am besten verwenden Sie eine Eingabekodierung, die es Ihnen erlaubt, Umlaute und andere Sonderzeichen direkt zu tippen, denn damit hat Babel kein Problem. Das \csvtabular-Kommando sieht jetzt aus wie \newcommand{\csvtabular}[2]{% \begingroup \CsvObeylines \CsvMagicQuote \catcode‘\;=4 \begin{tabular}{#1} \input{#2} \end{tabular} \endgroup}
und transformiert die Eingabedatei Nr;Name;Bahnradius (AE);Durchmesser (km) 1;Merkur;0,39;4878 2;Venus;0,72;12104 3;"Erde; Mond";1,00;12756 4;"Mars; Phobos; Deimos";1,52;6794
in Nr 1 2 3 4
Name Merkur Venus Erde; Mond Mars; Phobos; Deimos
Bahnradius/AE 0,39 0,72 1,00 1,52
Durchmesser/km 4878 12104 12756 6794
Hundertprozentig ausreichend ist auch das leider noch nicht – es fehlt noch eine Vorgehensweise für den Fall, dass ein Tabelleneintrag ein doppeltes Anführungszeichen enthält(!). Unglücklicherweise gibt es keine offizielle Methode, die vorschreibt, wie mit diesem Fall umzugehen ist. Eine Möglichkeit besteht darin, das doppelte Anführungszeichen zu verdoppeln(!!), eine andere, ein Zeichen wie \ davorzusetzen. Mit dem ersteren Ansatz könnten wir umgehen, indem wir im \CsvSepOn-Kommando prüfen, ob das nächste Zeichen ein doppeltes Anführungszeichen ist: \gdef\CsvSepOn{\futurelet\CsvNext\CsvSepOn@}
Hack #40: CSV-Dateien als Tabellen setzen
127
#40
HACK
#40
CSV-Dateien als Tabellen setzen
Das \futurelet-Kommando »spickt« quasi nach vorne und weist \CsvNext das nächste Eingabezeichen zu. Anschließend wird \CsvSepOn@ aufgerufen. Ist das Folgezeichen auch ein Anführungszeichen, fügen wir ein doppeltes Anführungszeichen in den Text ein, sonst machen wir weiter wie gehabt. Aufpassen müssen wir nur mit dem Semikolon: Wenn wir das schließende Anführungszeichen einer Spalte bearbeiten und dafür den nachfolgenden Semikolon lesen, der eigentlich als Spaltentrenner gemeint ist, wird er noch als normales Zeichen gelesen, und es ist nicht möglich, ihm seine Sonderbedeutung zurückzugeben. Hier ist die Definition für \CsvSepOn@: \gdef\CsvSepOn@{\relax \if\noexpand\CsvNext; \let\CsvNext=\CsvNewCol% \let"=\CsvSepOff% \else \ifx\CsvNext\CsvSepOn% \char‘\"% \fi \let\CsvNext=\relax% \fi \CsvNext}% \gdef\CsvNewCol#1{&}%
Der erste Vergleich prüft, ob \CsvNext ein (normales) Semikolon ist. Wenn ja, beginnen wir eine neue Spalte mit \CsvNewCol – das Semikolon, das für uns nutzlos geworden ist, wird verschluckt und dafür ein »richtiger« Spaltentrenner verarbeitet. Haben wir kein Semikolon vor uns, sollte ein Anführungszeichen kommen, was der zweite Vergleich prüft (das doppelte Anführungszeichen ist ja gerade äquivalent zu \CsvSepOn). In diesem Fall wird ein doppeltes Anführungszeichen eingebaut und \CsvNext neutralisiert (es steht ja sowieso noch einmal in der Eingabe). Auf diese Weise wird aus Nr;Name;Bahnradius (AE);Durchmesser (km) 1;"Merkur (""Götterbote"")";0,39;4878 2;Venus;0,72;12104 3;"Erde; Mond";1,00;12756 4;"Mars; Phobos; Deimos";1,52;6794
die Ausgabe
128
Kapitel 4: Tabellen und Abbildungen
HACK
Alles am rechten Platz
Nr 1 2 3 4
Name Merkur ("Götterbote") Venus Erde; Mond Mars; Phobos; Deimos
Bahnradius/AE 0,39 0,72 1,00 1,52
Durchmesser/km 4878 12104 12756 6794
(beachten Sie die »geraden« Anführungszeichen rund um »Götterbote«). Wohlgemerkt funktioniert dieses Verfahren nicht für alle CSV-Dateien, da das Format nicht vollständig genormt ist. Probleme hat es auch bei Feldern, die Zeilenumbrüche enthalten – hier müßten Sie ähnlich wie bei den Semikolons dafür sorgen, dass statt »\\« etwas anderes Passendes aufgerufen wird (ist im Vergleich nicht schwierig).
Siehe auch • Serienbriefe für Serientäter [Hack #62] stellt ein »offizielles« Paket zum Umgang mit CSV-Dateien vor.
HACK
#41
Alles am rechten Platz Bestimmen Sie die Position von Abbildungen und Tabellen.
Normalerweise können Sie die Positionierung von gleitenden Abbildungen und Tabellen LATEX überlassen. Das Programm tut im Großen und Ganzen das Richtige, und Sie können über die Platzierungsparameter für Gleitobjekte (siehe Tabelle 4-4) eine allgemeine Richtung vorgeben. Dazu sollten Sie allerdings ein paar Punkte beachten, damit sich der Gleitobjekt-Mechanismus von LATEX nicht »verklemmt« – der typische Effekt ist, dass alle Gleitobjekte eines Kapitels auf eigenen Seiten am Ende des Kapitels auftauchen statt über den Text verteilt. Bei Gleitobjekten können Sie hinter dem \begin{...}-Kommando eine optionale Platzierungs-Spezifikation angeben, die besagt, wo das Gleitobjekt landen darf. Diese Spezifikation ist eine beliebige Kombination der Buchstaben »t« (oben auf der Seite), »b« (unten auf der Seite), »p« (auf einer eigenen Gleitobjekt-Seite oder float page), oder »h« (hier, wo das Gleitobjekt im Text steht). Der Vorgabewert für die eingebauten Gleitobjekt-Typen ist bei den StandardDokumentklassen (article, report und book) »tbp«. Die Reihenfolge der Buchstaben ist völlig egal – »btp« heißt also nicht »unten, und wenn das nicht geht, oben, und wenn das nicht geht, auf einer eigenen Seite«, sondern ist genau dasselbe wie »tbp«, der Standardwert. LATEX versucht Gleitobjekte immer erst »hier« zu platzieren (falls »h« explizit angegeben wurde), dann oben, dann unten und dann gegebenenfalls auf einer eigenen Seite. Hack #41: Alles am rechten Platz
129
#41
HACK
#41
Alles am rechten Platz Tabelle 4-4: Platzierungsparameter für Gleitobjekte (Auswahl) Parameter
\topfraction
* * * **
Standard 2 1 3 0.7
\bottomfraction
**
0.3
\textfraction
**
0.2
\floatpagefraction
**
0.5
\floatsep
***
12pt plus 2pt minus 2pt
\textfloatsep
***
20pt plus 2pt minus 4pt
topnumber bottomnumber totalnumber
siehe \floatsep
\intextsep \topfigrule
**
\botfigrule
**
Bedeutung Maximale Anzahl von Gleitobjekten oben auf der Seite Maximale Anzahl von Gleitobjekten unten auf der Seite Maximale Anzahl von Gleitobjekten pro Seite Maximaler Anteil der Seitenhöhe, der von Gleitobjekten oben auf der Seite belegt werden kann Maximaler Anteil der Seitenhöhe, der von Gleitobjekten unten auf der Seite belegt werden kann Minimaler Anteil einer »normalen« Seite, der mit Text belegt sein muss Minimaler Anteil einer Gleitobjekt-Seite, der mit Gleitobjekten belegt sein muss Vertikaler Platz zwischen Gleitobjekten oben oder unten auf einer Seite Vertikaler Platz zwischen Gleitobjekten oben oder unten auf einer Seite und dem Text Platz vor und hinter einem Gleitobjekt im Text (mit [h]) Kommando, das eine Linie zwischen Gleitobjekten oben auf der Seite und dem Text erzeugt Kommando, das eine Linie zwischen dem Text und Gleitobjekten unten auf der Seite erzeugt
Ändern mit: * = \setcounter, ** = \renewcommand, *** = \setlength
Sie können den tbp-Standardwert für die Platzierung einer Klasse von Gleitobjekten ändern, indem Sie den LATEX-Parameter »\fps@Klasse« umdefinieren. Das ist nicht ganz bequem, aber mit etwas wie \makeatletter \@namedef{fps@table}{tp} \makeatother
können Sie zum Beispiel verhindern, dass Tabellen am unteren Seitenrand auftauchen, solange keine expliziten Platzierungs-Spezifikationen angegeben werden. Ein gängiger Fehler besteht darin, ausschließlich die Platzierungs-Spezifikation »b« zu verwenden, um eine relativ große Tabelle oder ein Bild am unteren Seitenrand unterzubringen. Das Problem dabei ist, dass der Parameter \bottomfraction, der angibt, wie viel Platz am unteren Seitenrand für Gleitobjekte zur Verfügung steht, relativ knapp bemessen ist. Wenn Ihre Tabelle mehr Platz benötigt als die standardmäßig vorgesehenen 30% der Texthöhe, dann kann sie dort nicht platziert werden – und blockiert auch alle folgenden gleitenden Tabellen. Dasselbe gilt für andere restriktive Vorgaben wie »t«, wenn auch nicht im selben Maße, da die \topfraction wesentlich größer ist als die
130
Kapitel 4: Tabellen und Abbildungen
HACK
Gruppendynamik
\bottomfraction. Es ist sinnvoll, zu »t« oder »b« immer noch »p« dazuzuneh-
men. Ein anderes Problem ist das der weitgehend leeren Gleitobjekt-Seiten (float pages). LATEX versucht, alle anstehenden Gleitobjekte, die es nicht bei der Ausgabe einer Seite loswird, auf eine oder mehrere Gleitobjekt-Seiten zu verlagern. Dabei bestimmt der Parameter \floatpagefraction, wie groß der Gesamtwert von ausstehenden Gleitobjekten sein muss, damit LATEX eine Gleitobjekt-Seite in Betracht zieht. Der Standardwert von 0,5 bedeutet, dass ein Gleitobjekt, das knapp über 50% der Seitenhöhe hoch ist, für eine Gleitobjekt-Seite in Frage kommt, wenn es nicht auf der aktuellen Seite im Text platziert werden kann – was zu einer beinahe halb leeren Gleitobjekt-Seite führt, wenn nicht noch ein anderes Gleitobjekt übrig ist, das in den verfügbaren Platz passt. Sie können versuchen, dieses Problem abzumildern, indem Sie \floatpagefraction erhöhen, müssen dabei aber aufpassen, dass Sie den neuen Wert nicht zu hoch ansetzen, sonst kann es passieren, dass sich die Gleitobjekte aufstauen, weil LATEX sich schwerer damit tut, sich zu Gleitobjekt-Seiten durchzuringen. In besonders harten Fällen können Sie LATEX anweisen, seine eigenen Regeln zu ignorieren. Wenn Sie in die Platzierungs-Spezifikation ein »!« einbauen, setzt LATEX für dieses Gleitobjekt die üblichen Parametereinstellungen außer Kraft und platziert es am gewünschten Ort, solange überhaupt Platz auf der Seite ist und keine anderen Gleitobjekte desselben Typs ausstehen, die eher platziert werden müssten. Wenn zum Beispiel ein großes Bild am unteren Seitenrand stehen soll und \bottomfraction das verhindert, dann können Sie mit \begin{figure}[!b]
dafür sorgen, dass das Bild trotzdem ausgegeben wird und nicht alle anderen Bilder hinter sich aufstaut.
HACK
#42
Gruppendynamik Platzieren Sie mehrere Tabellen oder Abbildungen im selben gleitenden Objekt.
Grundsätzlich zwingt Sie niemand, Tabellen in table-Umgebungen und Bilder in figure-Umgebungen zu platzieren. Na ja, außer dem gesunden Menschenverstand vielleicht. Wenn Sie sich aber eines Tages in einer Situation befinden, wo Sie ein Bild und eine kleine Tabelle haben, die beide nicht ganz halb so breit sind wie die Seite . . . dann gibt es wirklich keinen vernünftigen Grund, warum die beiden nicht nebeneinanderstehen sollten. Probieren Sie etwa Folgendes: \begin{figure} % oder table \begin{minipage}{.6\textwidth}
Hack #42: Gruppendynamik
131
#42
HACK
#42
Gruppendynamik
\centering \begin{tabular}{ll} Felsenpinguin & Eudyptes chrysocome \\ Kaiserpinguin & Aptenodytes forsteri \\ Königspinguin & Aptenodytes patagonicus\\ Linux-Pinguin & Harengiphagus torvaldsi \\ Zügelpinguin & Pygoscelis antarctica \end{tabular} \caption{Pinguinarten} \end{minipage} \hspace{\fill} \begin{minipage}{.35\textwidth} \centering \includegraphics[width=\textwidth]{tux-logo} \caption{Tux der Pinguin} \end{minipage} \end{figure}
Wenn Sie das tatsächlich testen, dürfte Ihnen auffallen, dass die Ausgabe fast so aussieht wie in Abbildung 4-3 – mit einem winzigen Unterschied: Unter der Tabelle steht »Abbildung 1«. Das liegt daran, dass das \caption-Kommando von der um es herum stehenden Umgebung mitgeteilt bekommt, ob es eine Legende für eine Tabelle oder eine Abbildung erzeugen soll. In unserem Beispiel ist die Umgebung eine figure, also steht dort zweimal »Abbildung« – wäre sie eine table, dann stünde dort zweimal »Tabelle«.
Felsenpinguin Kaiserpinguin Königspinguin Linux-Pinguin Zügelpinguin
Eudyptes chrysocome Aptenodytes forsteri Aptenodytes patagonicus Harengiphagus torvaldsi Pygoscelis antarctica
Tabelle 1: Pinguinarten
Abbildung 1: Tux der Pinguin
Abbildung 4-3: Eine Tabelle und ein Bild im selben Gleitobjekt
132
Kapitel 4: Tabellen und Abbildungen
HACK
Gruppendynamik
(a) Links
(b) Rechts
Abbildung 4-4: Eine Abbildung mit zwei »Unterabbildungen«
Das ist allerdings nichts, was wir nicht mit einem Blick in den LATEX-Quellcode und etwas Umdefiniererei in den Griff bekommen könnten. \caption und die drumherum stehenden Umgebungen verwenden das Kommando \@captype zur Kommunikation, indem sie es nach Bedarf auf »figure« oder »table« setzen, und das können wir natürlich auch, wenn wir müssen: Ein kleines \newcommand{\setcaptype}[1]{\renewcommand{\@captype}{#1}}
in der Präambel (gegebenenfalls von \makeatletter und \makeatother umgeben wegen des »@«), und schon sind wir im Geschäft: \setcaptype{table} \caption{Pinguinarten} ... \setcaptype{figure} \caption{Tux der Pinguin}
sorgen für die korrekte Beschriftung unserer Objekte.
Gleitobjekte und Unterobjekte Eine andere Situation finden Sie in Abbildung 4-4 illustriert. Dort haben wir eine Abbildung, die aus zwei zusammengehörenden »Unterabbildungen« besteht. Im Abbildungsverzeichnis taucht nur die Legende der »Hauptabbildung« auf, aber wir können uns auch auf die Unterabbildungen beziehen:
Hack #42: Gruppendynamik
133
#42
HACK
#42
Gruppendynamik
(a)
(d) (b)
(c)
Abbildung 4-5: Der Salto seitwärts, einfach gesessen: (a) Ausgangsposition, (b) Aufschwung, (c) Abschwung, (d) Endposition.
Abbildung 4-4a steht auf Seite 133.
\figurename~\ref{fig:subfloat-left} steht auf Seite~\pageref{fig:subfloat-left}.
Realisiert wird das mit dem subfig-Paket von Steven Cochran. Dieses Paket stellt das \subfloat-Kommando zur Verfügung, mit dem Sie innerhalb eines Gleitobjekts mehrere Unterobjekte einführen können. Die Eingabe für Abbildung 4-4 sieht ungefähr so aus: \begin{figure} \centering \subfloat[Links]{% \reflectbox{\includegraphics[width=.4\textwidth]{tux-logo}} \label{fig:subfloat-left} } \qquad \subfloat[Rechts]{% \includegraphics[width=.4\textwidth]{tux-logo} \label{fig:subfloat-right} } \caption{Eine Abbildung mit zwei »Unterabbildungen«} \label{fig:subfloat} \end{figure}
Das \subfloat-Kommando übernimmt den Inhalt des Gleitobjekts als Argument und eine Legende als optionales Argument. Standardmäßig werden die Unterobjekte mit Kleinbuchstaben »nummeriert« (wie in Abbildung 4-4 zu sehen). Verweise auf Unterobjekte mit \ref werden zu etwas wie »4-4a« expandiert. Das ist normalerweise das, was man will, aber es ist in einem speziellen Fall
134
Kapitel 4: Tabellen und Abbildungen
HACK
Do-it-yourself-Gleitobjekte
lästig: Wenn Sie in Ihrer »Abbildung« eine Reihe von Bildern zeigen – die keine eigenen Legenden haben, sondern nur (zum Beispiel) durch Buchstaben markiert sind – und in der Hauptlegende der Abbildung die verschiedenen Bilder erklären (siehe Abbildung 4-5). Für diesen Fall sieht subfig das Kommando \subref vor, das einfach nur den Namen des Unterobjekts liefert, ohne die Nummer des übergeordneten Objekts davor. Die Eingabe für Abbildung 4-5 sieht auszugsweise so aus: \begin{figure} \subfloat[]{% \includegraphics[width=.2\textwidth]{tux-logo}% \label{aa} }% ... \caption[Der Salto seitwärts]{Der Salto seitwärts, einfach gesessen: \subref{aa} Ausgangsposition, \subref{bb} Aufschwung, ...} \end{figure}
HACK
#43
Do-it-yourself-Gleitobjekte Wie Sie Ihre eigenen Gleitobjekte definieren können
Von Haus aus kennt LATEX nur die beiden gleitenden Objekte figure und table. Allerdings könnte man durchaus auf die Idee kommen, dass sich auch andere Bestandteile eines Dokuments gut als Gleitobjekte machen würden: Beispiele, Programmlistings, Einwürfe und ähnliches. Ihnen fallen sicher spontan noch einige weitere Kandidaten ein. Der Gleitobjekt-Mechanismus von LATEX ist allgemein genug, dass das ohne großen Aufwand möglich ist, aber die tatsächliche Durchführung, wenn Sie es »mit bloßen Händen« machen wollen, ist wieder mal etwas umständlich. Das Ziel des float-Pakets von Anselm Lingnau (töröö!) besteht darin, die Definition eigener Gleitobjekte zu vereinfachen.1 Statt in den Innereien von LATEX herumwühlen zu müssen, genügt ein \newfloat{algorithm}{tbp}{alg}[chapter]
um eine neue Klasse von Gleitobjekten namens algorithm zu definieren, deren Mitglieder (wie table & Co.) standardmäßig oben und unten auf einer 1
Die Existenz dieses Pakets verdanken wir übrigens einem besonders langweiligen Weihnachten irgendwann in den 1990er-Jahren.
Hack #43: Do-it-yourself-Gleitobjekte
135
#43
HACK
#43
Do-it-yourself-Gleitobjekte Algorithmus 4.1: Der Elefanten-Schnitz-Algorithmus
1. Ein Stück Holz nehmen. 2. Alles abschneiden, was nicht nach einem Elefanten aussieht. 3. Ende. Tabelle 4-5: Gleitobjekt-Stile von float Stil plain plaintop boxed ruled
Beschreibung Der LATEX-übliche Stil für Gleitobjekte, mit der Legende unten Der LATEX-übliche Stil für Gleitobjekte, mit der Legende oben Das Gleitobjekt wird eingerahmt und die Legende steht darunter (die Abbildungen in diesem Buch sind mit dem boxed-Stil formatiert) Die Legende steht oben, mit Linien darüber und darunter, und darunter steht das Gleitobjekt, gefolgt von einer weiteren Linie. Dieses Format ist angelehnt an die Tabellen in Concrete Mathematics von Ronald Graham, Donald E. Knuth und Oren Patashnik.
Seite oder auf einer eigenen Gleitobjekt-Seite platziert werden können und innerhalb von Kapiteln nummeriert werden (das heißt, der erste algorithm in einem neuen Kapitel bekommt die Nummer 1, der nächste die 2 und so weiter). In einer Datei mit der Endung .alg werden Informationen zur Erzeugung eines Algorithmenverzeichnisses gesammelt. Das Kommando \floatname{algorithm}{Algorithmus}
bestimmt den Namen der Klasse aus der Sicht von \caption; wenn Sie kein \floatname-Kommando angeben, wird der bei \newfloat angegebene Klassenname verwendet, so dass Sie ursprünglich auch Folgendes hätten schreiben können: \newfloat{Algorithmus}{tbp}{alg}[chapter]
Nach dieser Definition können Sie die algorithm-Umgebung verwenden: \begin{algorithm} \begin{enumerate} \item Ein Stück Holz nehmen. \item Alles abschneiden, was nicht nach einem Elefanten aussieht. \item Ende. \end{enumerate} \caption{Der Elefanten-Schnitz-Algorithmus} \end{algorithm}
liefert das in Algorithmus 4.1 gezeigte Ergebnis. Das float-Paket führt das Konzept eines »Gleitobjekt-Stils« (float style) ein. Über Gleitobjekt-Stile können Sie bestimmen, wie Ihre Gleitobjekte forma136
Kapitel 4: Tabellen und Abbildungen
HACK
Do-it-yourself-Gleitobjekte
tiert werden sollen. Wenn Sie nichts anderes angeben, bekommen Sie einen Stil, der dem LATEX-üblichen Aussehen sehr nahe kommt (bis auf einen Unterschied, den wir gleich noch erwähnen werden), aber Sie können sich über das Kommando \floatstyle einen anderen Stil wünschen. Dieser Stil wird dann für darauffolgende \newfloat-Kommandos herangezogen. Wenn Sie auch figure und table mit Gleitobjekt-Stilen aus float ausstatten wollen, haben Sie das Problem, dass diese Klassen nicht mit \newfloat angelegt werden, sondern schon von Haus aus in LATEX vorhanden sind. Verwenden Sie stattdessen das \restylefloat-Kommando, um eine existierende Klasse von Gleitobjekten umzudefinieren: \floatstyle{ruled} \restylefloat{table}
Das funktioniert auch mit anderen, schon mit \newfloat definierten Gleitobjekt-Klassen, obwohl Sie es nicht zur Gewohnheit werden lassen sollten. Eine Eigenschaft, die die Gleitobjekt-Stile von float gegenüber dem LATEXStandard haben, besteht darin, dass sie die Position der Legende diktieren. Nach einem \restylefloat{table} werden Sie feststellen, dass es unerheblich ist, wo in der table-Umgebung Ihr \caption-Kommando steht – die Legende steht immer unter dem eigentlichen Gleitobjekt.2 Dies ist eine Konsequenz der Tatsache, dass float das für Stile wie boxed oder ruled machen muss. Wenn es Ihnen gegen den Strich geht oder Sie aus Kompatibilitätsgründen beim Standardverhalten bleiben müssen, können Sie Folgendes schreiben: \restylefloat*{table}
Dieser Aufruf lässt das Standard-\caption-Kommando in Kraft. Um einen neuen Gleitobjekt-Stil zur Verfügung zu stellen, müssen Sie ein Kommando namens \fs@stil definieren. LATEX konstruiert das Gleitobjekt, und über den Stil können Sie es verbrämen und mit der Legende zusammenbauen. Wie das genau passiert, regeln die Definitionen, die Sie innerhalb von \fs@stil vornehmen. In diesem »Stil-Kommando« belegen Sie einige weitere Kommandos vor, namentlich: \@fs@pre Dieses Kommando wird am Anfang des Zusammensetzens ausge-
führt. \@fs@post Dieses Kommando wird am Ende des Zusammensetzens ausge-
führt. 2
Die landläufige Typografie schreibt vor, dass die Legenden für Bilder unter dem Bild und die für Tabellen über der Tabelle stehen. Mit float lässt sich das leicht erreichen, aber es ist nicht die Standardvoreinstellung.
Hack #43: Do-it-yourself-Gleitobjekte
137
#43
HACK
#43
Do-it-yourself-Gleitobjekte
\@fs@iftopcapt Gibt an, ob in diesem Stil die Legende oben oder unten steht. Kann einen der Werte \iftrue oder \iffalse annehmen. \@fs@mid Dieses Kommando wird in »der Mitte« des Zusammensetzens aus-
geführt. In diesem Moment ist entweder die Legende eingebaut worden (wenn \@fs@iftopcapt wahr ist) oder das eigentliche Gleitobjekt wurde geholt (sonst). Als Nächstes nach dem \@fs@mid passiert dann jeweils das, was bisher nicht passiert ist – wenn \@fs@iftopcapt wahr ist, wird zum Beispiel das eigentliche Gleitobjekt geholt. \@fs@capt Dieses Kommando formatiert die Legende. Es wird mit zwei Argu-
menten aufgerufen, nämlich dem Gleitobjekt-Namen und der Nummer einerseits und der vom Benutzer angegebenen Legende andererseits. \@fs@cfont Kommandos, die eine passende Schrift für das erste Argument von \@fs@capt einstellen. Ob diese Einstellung beachtet wird, hängt davon ab, wie \@fs@capt definiert ist, aber die Standard-Gleitobjekt-Stile tun es.
Hier ist zum Beispiel die Definition des ruled-Stils: \newcommand\floatc@ruled[2]{{\@fs@cfont #1} #2\par} \newcommand\fs@ruled{\def\@fs@cfont{\bfseries}% \let\@fs@capt\floatc@ruled \def\@fs@pre{\hrule height.8pt depth0pt \kern2pt}% \def\@fs@post{\kern2pt\hrule\relax}% \def\@fs@mid{\kern2pt\hrule\kern2pt}% \let\@fs@iftopcapt\iftrue}
Um zu zeigen, wie Sie einen neuen Gleitobjekt-Stil definieren können, ziehen wir das fancybox-Paket von Timothy Van Zandt heran. Dieses Paket enthält unter anderem ein Kommando namens \shadowbox, das wie \makebox funktioniert, aber eine Umrahmung mit »Schlagschatten« um den resultierenden Kasten malt:
Shadow Boxing for Fun and Profit
\shadowbox{% \begin{minipage}{4cm} \centering Shadow Boxing\\ for Fun and Profit \end{minipage}}
Hier ist ein Gleitobjekt-Stil, der \shadowbox verwendet: \newcommand{\fs@shadow}{% \fs@plain \def\@fs@pre{% \setbox\@currbox\vbox{\shadowbox{\box\@currbox}}%
138
Kapitel 4: Tabellen und Abbildungen
HACK
Do-it-yourself-Gleitobjekte
} \let\@fs@iftopcapt=\iffalse}
Wir rufen zuerst \fs@plain auf und setzen dadurch die Einstellungen für jenen Stil in Kraft. Diese sind sorgfältig so ausgesucht, dass sie nichts Besonderes machen, und eignen sich dadurch als Standardwerte. Die Definition von \@fs@pre erledigt die eigentliche Arbeit: LATEX hinterlässt das ansonsten fertige Gleitobjekt im Box-Register \@currbox, das wir nur noch an \shadowbox übergeben, damit der Schatten angehängt wird. Ein einfaches Beispiel für diesen Stil finden Sie in Lied 4.1: \floatstyle{shadow} \newfloat{song}{tbp}{sng}[chapter] \floatname{song}{Lied} ... \begin{song} \caption{Ein kleines Lied (nach \TeX\ Stevens)} \label{song:fshadow} \begin{verse} I’m being followed by a float shadow,\\ \quad Float shadow, float shadow\\ Skipping and kerning for a float shadow,\\ \quad Float shadow, float shadow\\ \end{verse} \end{song} Wenn Sie hyperref verwenden, kann es sein, dass LATEX beim Verlinken von Querverweisen eine Fehlermeldung der Form ! Undefined control sequence. <argument> song.\theHsong
ausspuckt. Fügen Sie in diesem Fall etwa Folgendes zum Kommando \newfloat{song}. . . hinzu, um hyperref glücklich zu machen: \newcommand{\theHsong}{\arabic{song}} % oder was auch immer
I’m being followed by a float shadow, Float shadow, float shadow Skipping and kerning for a float shadow, Float shadow, float shadow Lied 4.1: Ein kleines Lied (nach TEX Stevens)
Hack #43: Do-it-yourself-Gleitobjekte
139
#43
KAPITEL FÜNF
Gliederung und Verzeichnisse Hacks #44–55
LATEX ist von Haus aus relativ eng mit wissenschaftlichen Artikeln und Büchern verbunden. Bücher bestehen aus Kapiteln, diese aus Abschnitten, diese wiederum aus Unterabschnitten und so weiter (bei Artikeln fallen die Kapitel weg, aber sonst bleibt alles gleich). Die Standardformatierung von Kapitelund anderen Überschriften ist eher nüchtern und dem amerikanischen typografischen Geschmack angepasst. Das ist für uns mehr als genug Grund, dem Thema »Dokumentgliederung in LATEX« ein Kapitel zu widmen. Hier werden Sie nicht nur sehen, wie Sie das Inhaltsverzeichnis kontrollieren und die verschiedenen Kapitel- und Abschnittsanfänge an Ihre Vorstellungen anpassen können, sondern wir beschäftigen uns auch mit Stichwort- und Literaturverzeichnissen und bibliografischen Zitaten.
HACK
#44
Variabler Tiefgang Bestimmen Sie, welche Abschnittstitel nummeriert werden und ihren Weg ins Inhaltsverzeichnis finden.
LATEX nummeriert Kapitel, Abschnitte und andere »Gliederungseinheiten« automatisch durch, wobei die Zählung immer dann auf eins zurückgesetzt wird, wenn die nächste Gliederungseinheit auf der Ebene darüber anfängt. (Alles andere wäre wohl auch wunderlich – aber siehe Der Unterzeichnete . . . [Hack #47]!) Allerdings gibt LATEX die so erzielte Nummer nicht immer mit dem Titel aus, sondern ausgehend von der höchsten Ebene – \chapter bei book und report, \section bei article – nur bis zu der Ebene, die der Zähler secnumdepth angibt. Die Nummerierung der Ebenen ist in Tabelle 5-1 aufgelistet; sie stimmt bei den Standard-Dokumentklassen weitgehend überein, wobei der konstante Faktor ist, dass \section die Stufe 1 haben soll. secnumdepth gibt die Stufe an, die gerade noch nummeriert werden soll – der Standard-
140
Kapitel 5: Gliederung und Verzeichnisse
HACK
Variabler Tiefgang Tabelle 5-1: Gliederungstiefen der Standard-Dokumentklassen Einheit \part \chapter \section \subsection \subsubsection \paragraph \subparagraph
book und report −1 0 1 2 3 4 5
article 0 — 1 2 3 4 5
wert 2 führt also zu nummerierten \subsections, aber nicht nummerierten \subsubsections, \paragraphs und \subparagraphs. Den Wert von secnumdepth ändern Sie wie üblich mit \setcounter: \setcounter{secnumdepth}{-2} Gar keine Nummerierung \setcounter{secnumdepth}{5} Nummerierung für Juristen Unabhängig von secnumdepth können Sie immer von Fall zu Fall die Nummerierung einer Überschrift unterdrücken, indem Sie die »Sternform« des betreffenden Kommandos benutzen: \section*{Anonymer Abschnitt}
Wenn Sie sich aber dabei ertappen, dass jedes Ihrer \sectionKommandos einen Stern hat, dann ist secnumdepth sicherlich die bessere Option. Das andere Problem ist, dass die Sternform nicht nur eine Nummerierung unterdrückt, sondern die Überschrift auch nicht ins Inhaltsverzeichnis einträgt. Dass diese beiden Aktionen gekoppelt sind, ist im Allgemeinen eher hinderlich denn nützlich.
Sie müssen die Stufennummern nicht auswendig kennen; statt eine explizite Nummer anzugeben, können Sie auch einfach zum Beispiel den Zähler erhöhen, um die nächste Gliederungsstufe in die Nummerierung aufzunehmen: \addtocounter{secnumdepth}{1} Tabelle 5-1 erwähnt auch \part. \part spielt eine Sonderrolle, da es »über« den anderen Gliederungsebenen steht und diese von ihm unabhängig sind. Wenn ein neuer \part anfängt, werden die Zähler für die anderen Gliederungsebenen nicht zurückgesetzt.
Der Zähler tocdepth gibt an, bis zu (einschließlich) welcher Stufe die Überschriften ins Inhaltsverzeichnis eingetragen werden. Sein Standardwert ist 2 für book und report und 3 für article – Sie bekommen also in jedem Fall als Inhaltsverzeichnis eine bis zu drei Ebenen tiefe Liste. Auch hier können Sie die Tiefe mit \setcounter oder \addtocounter ändern.
Hack #44: Variabler Tiefgang
141
#44
HACK
#45
Überschriften erzeugen mit Stil HACK
#45
Überschriften erzeugen mit Stil Passen Sie die Formatierung von Kapitel- und Abschnittsüberschriften an Ihre Wünsche an.
LATEXs eingebaute Formatierung von Überschriften für Kapitel und Abschnitte könnte man als öde und langweilig bezeichnen, auch wenn sie dem eingeweihten Auge sofort verrät, dass es sich bei einem Druckwerk um ein LATEX-Erzeugnis handelt. Tatsache ist: Mit so etwas lockt man im modernen Verlagswesen keinen Hund hinter dem Ofen hervor. Sie können sich spaßeshalber ja mal überlegen, wie Sie die Kapitelanfänge dieses Buchs mit LATEX erzeugen würden . . . Bevor wir aus dem Nähkästchen plaudern, werfen wir aber einmal einen kurzen Blick auf die LATEX-Bordmittel. Die Standard-Dokumentklassen erzeugen alle Überschriften unterhalb von \chapter mit einem ziemlich generischen Kommando namens \@startsection. Es erlaubt sowohl frei stehende Überschriften wie die von \section und \subsection als auch Überschriften, die Teil des ersten Absatzes sind wie bei \paragraph. Hier ist – etwas leserlicher gemacht – die Definition von \section aus article.cls: \newcounter{section} \renewcommand{\thesection}{\arabic{section}} \newcommand{\section}{% \@startsection{section}{1}{0mm}% Zähler, Ebene, Einrückung {-3.5ex plus -1ex minus -.2ex}% Platz davor {2.3ex plus .2ex}% % Platz dahinter {\normalfont\Large\bfseries}} % Formatierung
Interessant ist vor allem der Aufruf von \@startsection in den letzten vier Zeilen des Beispiels. Das erste Argument des Kommandos ist der Name eines Zählers, der an dieser Stelle hochgezählt werden soll. In unserem Fall ist das section, denn die Zähler für Gliederungseinheiten heißen laut Konvention so wie die Gliederungseinheiten selbst. Als Nächstes kommt die numerische Stufe der Gliederungseinheit (hier 1, siehe Tabelle 5-1). Das dritte Argument gibt die Einrückung des Titels vom linken Rand an. Sein Wert darf negativ sein, dann ragen die Titel in den Rand hinaus. Das vierte Argument spielt eine Doppelrolle: Zum einen entscheidet es darüber, ob die erste Zeile des Absatzes, der der Überschrift folgt, eingerückt werden soll oder nicht – ist der Wert des Arguments positiv, dann wird die Zeile eingerückt, ist er negativ, dann nicht. Der Betrag des Werts (ohne ein etwaiges Vorzeichen) dagegen bestimmt den vertikalen Leerraum, den LATEX über der Überschrift lässt. Dieser Wert hat in der Regel eine gewisse Elastizität (eine plus- und/oder minus-Komponente), damit überschüssiger vertikaler 142
Kapitel 5: Gliederung und Verzeichnisse
HACK
Überschriften erzeugen mit Stil
Leerraum auf der Seite aufgefangen werden kann. Auch das fünfte Argument hat zwei Bedeutungen: Ist sein Wert größer oder gleich null, beschreibt es den vertikalen Leerraum unter der Überschrift – es wird also eine frei stehende Überschrift erzeugt. Ist er dagegen kleiner als null, entsteht eine Überschrift im Absatz, und der Betrag des Werts gibt an, wie viel horizontaler Leerraum zwischen der »Überschrift« und dem Beginn des eigentlichen Textes gelassen werden soll. Bei frei stehenden Überschriften fängt hinter der Überschrift ein neuer Absatz an, und darum wird zusätzlicher vertikaler Leerraum im Wert von \parskip hinzugefügt. Ein ärgerlicher Effekt der parametersparenden Positiv-Negativ-Methode ist, dass es nicht möglich ist, frei stehende Überschriften zu haben, deren Abstand zum folgenden Text kleiner ist als \parskip – theoretisch könnte man versuchen, \parskip durch einen negativen vertikalen Leerraum hinter der Überschrift zu neutralisieren, aber \@startsection interpretiert solche Längenangaben als Wunsch nach einer Überschrift im Absatz.
Der letzte Parameter schließlich enthält Formatierungskommandos für die Überschrift. In unserem Beispiel verwenden wir die »Hauptschriftfamilie« für das Dokument, fett und ein gutes Stück größer als der Haupttext. Sie könnten aber zum Beispiel Folgendes schreiben \normalfont\Huge\sffamily\bfseries
um eine sehr große fette serifenlose Schrift zu bekommen. Sie könnten hier auch \centering sagen, um eine zentrierte Überschrift zu bekommen, mit \newpage eine neue Seite anfangen oder mit \rule eine Linie ziehen. Die Kommandos \part und (bei den Dokumentklassen book und report) \chapter verwenden nicht \@startsection, sondern ein allgemeineres Kommando namens \secdef, das zumindest die Interpretation von \part bzw. \chapter übernimmt, komplett mit dem optionalen Argument. Die eigentliche Arbeit müssen Sie selbst erledigen. Das \chapter-Kommando in book.cls zum Beispiel ist beispielsweise folgendermaßen definiert (wenn man etwas uninteressanten Kram weglässt): \newcommand{\chapter}{\secdef\@chapter\@schapter}
Das Kommando \@chapter kümmert sich dabei um »vollständige« Kapiteltitel mit Kapitelnummer und dem optionalen Argument für das Inhaltsverzeichnis. Sie sollten es über \newcommand{\@chapter}[2][]{...}
definieren. \@schapter (»s« wie »starred«) dagegen ist zuständig für \chapter*Kapitel und hat kein optionales Argument:
Hack #45: Überschriften erzeugen mit Stil
143
#45
HACK
#45
Überschriften erzeugen mit Stil
\newcommand{\@schapter}[1]{...}
(Sie werden sich jetzt vielleicht fragen, warum man dann nicht einfach von vornherein zwei verschiedene Kommandos definiert. Die Antwort lautet: Schauen Sie doch mal nach der echten Definition von \chapter in book.cls – dort finden vor dem \secdef noch diverse Initialisierungen statt, die man sonst zweimal haben müsste.) Die Definitionen für \@chapter und \@schapter müssen Sie selber liefern, wenn Sie mit dem, was LATEX Ihnen bietet, nicht zufrieden sind. Sie haben dabei alle denkbaren Freiheiten, müssen sich aber auch um jede Menge Details kümmern, etwa korrekt mit den secnumdepth- und tocdepth-Zählern umgehen und auch im Falle von twoside oder twocolumn das Richtige tun (was auch immer das dann im Einzelfall sein mag).
Überschriften leicht gemacht: titlesec Wenn Sie keine Lust haben, alles selbst zu machen, aber trotzdem das Aussehen Ihrer Überschriften in weiten Grenzen modifizieren wollen, dann ist das titlesec-Paket von Javier Bezos genau das Richtige für Sie. Es ist de facto ein Ersatz für die Teile von LATEX, die sich mit Überschriften beschäftigen, und exportiert eine umfassende Programmierschnittstelle, die Ihnen Zugriff auf einen bunten Strauß an Formatierungsmöglichkeiten gibt. Nebenbei werden einige Einschränkungen und Fehler des Standardmechanismus behoben. Das Paket ist sehr umfangreich dokumentiert, und wir beschränken uns deshalb darauf, Ihnen zu zeigen, wie es bei der Definition der Dokumentklasse für das vorliegende Buch eingesetzt wurde. Wenn Sie sich ein paar Kapiteleingangsseiten genauer anschauen, fallen Ihnen sicher einige Dinge auf: • Die Seite beginnt mit der Kapitelnummer in ausgeschriebener Form. Darunter steht ein Strich, der über die ganze Seitenbreite geht. • Danach folgt der Titel des Kapitels und eine Angabe darüber, welche Hacks in diesem Kapitel zu finden sind. • Der »drittelbreite« graue Kasten oben außen und die Fußzeile sind nicht direkt Bestandteile der Kapiteldefinition, aber trotzdem charakteristisch für die Kapiteleingangsseiten.
Um mit titlesec das Aussehen einer Überschrift vorzugeben, rufen wir das Kommando \titleformat für das betreffende Gliederungskommando auf, hier \chapter: \definecolor{titlegray}{gray}{0.4} \definecolor{chaptergray}{gray}{0.5}
144
Kapitel 5: Gliederung und Verzeichnisse
HACK
Überschriften erzeugen mit Stil
\RequirePackage{soul}
% Sperren und Schafe stehlen
\titleformat{name=\chapter}[display]{} {\filinner\Large\sffamily\fontseries{c}\selectfont \color{chaptergray}% \so{\MakeUppercase{\chaptertitlename~\cdeutsch{chapter}}}} {0cm}% {\chapterformat}
Das zweite Argument (in eckigen Klammern) gibt an, dass es sich um eine abgesetzte Überschrift, ähnlich der normalen \chapter-Überschrift, handeln soll. titlesec unterstützt insgesamt neun Geschmacksrichtungen von Überschriften, die in der Dokumentation des Pakets erklärt sind. Das dritte Argument (hier leer) dient zur Formatierung des kompletten Titels (Kapitelnummer und Überschrift) und kann Material enthalten, das unmittelbar vor dem Titel ausgegeben wird. Das vierte Argument ist die Kapitelnummer und verdient eine genauere Betrachtung; wir nehmen es uns gleich vor. Das fünfte Argument ist der Platz zwischen Kapitelnummer und Überschrift; die genaue Interpretation hängt vom Stil (dem zweiten Argument) ab. Wir benutzen es nicht, aber da man es auch nicht leer lassen darf, hat es hier den Wert 0cm. Das letzte Argument schließlich bekommt den Kapiteltitel (das eigentliche Argument von \chapter) übergeben und dient dazu, diesen zu setzen, gegebenenfalls geeignet verbrämt. Es gäbe noch ein allerletztes, optionales Argument, mit dem Sie Material angeben können, das nach dem Titel gesetzt wird, aber das brauchen wir hier nicht. Jetzt aber zurück zu unserer Kapitelnummer. Der betreffende Code lautete: \filinner\Large\sffamily\fontseries{c}\selectfont \color{chaptergray}% \so{\MakeUppercase{\chaptertitlename~\cdeutsch{chapter}}}
Mit \filinner (das von titlesec mitgebracht wird) legen wir fest, dass die Kapitelnummer immer an den äußeren Seitenrand rücken soll. Linke und rechte Seiten verschieden behandeln [Hack #27] hat dies etwas ausführlicher behandelt. Der Rest der ersten Zeile wählt die korrekte Schrift und Farbe aus, und die zweite Zeile schreibt »KAPITEL XY«. Dabei ist \chaptertitlename, das ebenfalls von titlesec definiert wird, der landessprachlich korrekte Ausdruck für »Kapitel« oder aber »Anhang« (je nachdem, wo im Buch wir uns befinden). \MakeUppercase sorgt dafür, dieses Wort und den Wert des Kapitelzählers, ebenfalls als Wort, in Großbuchstaben zu konvertieren, und \so aus dem soul-Paket sperrt diesen Text leicht (d. h. fügt zusätzlichen Leerraum zwischen den einzelnen Buchstaben ein).
Hack #45: Überschriften erzeugen mit Stil
145
#45
HACK
#45
Überschriften erzeugen mit Stil
Hier noch ein kurzer Blick darauf, wie aus dem Zähler chapter ein deutsches Zahlwort wird. Wir haben es uns einfach gemacht und die Technik aus Die Nummerierung von Listen ändern [Hack #8] aufgegriffen: \newcommand*\@cdeutsch[1]{\ifcase #1\or eins\or zwei\or drei\or vier\or fünf\or sechs\or sieben\or acht\or neun\or zehn\or elf\or zwölf\or dreizehn\else\@ctrerr\fi} \newcommand*\cdeutsch[1]{\expandafter\@cdeutsch \csname c@#1\endcsname}
(Die Tatsache, dass wir wissen, wie viele Kapitel das Buch maximal haben wird, verschafft uns hier natürlich einen unfairen Vorteil. Wenn Sie die volle Allgemeinheit brauchen: Das Paket zahl2string von Jonathan Sauer versorgt Sie von 0 bis 999 999 999.) Um die Konstruktion unserer Kapiteltitel zu verstehen, müssen wir uns noch das \chapterformat-Kommando anschauen, das wir am Schluss der Definition von \titleformat{\chapter} erwähnt haben: \newcommand{\chapterformat}[1]{% \thispagestyle{chap}% \textcolor{chaptergray}{\titlerule}% \vspace{1cm}% \filinner% \Huge\sffamily\fontseries{bc}\selectfont \textcolor{titlegray}{#1}\\ \LARGE\fontseries{c}\selectfont \textcolor{chaptergray}{% Hacks \#\firsthack{\value{chapter}}% --\lasthack{\value{chapter}}}% }
Dieses Kommando übernimmt das Ruder unmittelbar nach der »Kapitelnummer«, die bei uns ja Text ist. Es zeichnet die Linie darunter, lässt etwas Freiplatz und gibt dann den Titel des Kapitels aus, den es als Parameter übergeben bekommen hat. Danach kommt noch die Hack-Übersicht, deren Funktion auf den Kommandos \firsthack und \lasthack basiert – \firsthack liefert immer die Nummer des ersten Hacks im Kapitel, dessen Nummer als Argument übergeben wird, und Entsprechendes gilt für \lasthack. (Wie das genau funktioniert, bleibt für den Moment unser kleines Geheimnis, jedenfalls bis Von \sections und Hacks [Hack #46].)
146
Kapitel 5: Gliederung und Verzeichnisse
HACK
Von \sections und Hacks
Siehe auch • Seitenstile al Gusto [Hack #29] beschreibt einige der Möglichkeiten von titlesec zur Gestaltung von Seitenstilen. Dort werden die Seitenstile dieses Buchs erklärt.
HACK
#46
Von \sections und Hacks Noch mehr über die Innereien dieses Buchs
Damit Sie noch mehr über die Praxis mit titlesec [Hack #45] erfahren, erklären wir Ihnen hier noch schnell, wie die Überschriften der einzelnen Hacks in diesem Buch formatiert werden. Die Hacks sind in diesem Buch das, was in anderen Büchern die Abschnitte sind, also die Gliederungsebene direkt unterhalb von \chapter – es überrascht also nicht, dass sie durch kreative Zweckentfremdung von \section entstehen. Einer der wesentlichen Unterschiede zwischen normalen \sections und unseren Hacks ist, dass die Hacks fortlaufend durch das ganze Buch nummeriert sind – der Hack-Zähler (section) wird nicht am Kapitelanfang auf null zurückgesetzt. Damit das klappt, müssen wir die Kopplung von section an chapter aufheben, die die book-Dokumentklasse vorsieht (mit den besten Absichten natürlich, sie kann es ja nicht besser wissen). Ulkigerweise kann LATEX das nicht ohne fremde Hilfe, und die kommt von David Carlisle in Gestalt des remreset-Pakets, das ein Kommando namens \@removefromreset definiert: \RequirePackage{remreset} \@removefromreset{section}{chapter}
Wir müssen nicht nur den Zähler section von chapter trennen, sondern auch dafür sorgen, dass die Kapitelnummer nicht mehr mit dazugenommen wird, wenn wir den section-Zähler ausgeben: \renewcommand{\thesection}{\arabic{section}}
Was die tatsächlichen Hacks angeht, haben wir ein kleines Problem mit der Benutzerschnittstelle. Das normale \section-Kommando hat ein Argument, den Abschnittstitel (das optionale Argument mit dem »kurzen« Abschnittstitel für das Inhaltsverzeichnis lassen wir für den Moment mal aus dem Spiel), aber unsere Hack-Überschriften haben drei Elemente, die der Autor angeben muss: die Überschrift, die »Unterüberschrift« und das Thermometer links vom Kasten mit der Hack-Nummer, das die Komplexität des Abschnitts andeuten soll (die Hack-Nummer erzeugen wir automatisch). Wir schummeln hier, indem wir ein \hack-Kommando definieren, das diese drei Argumente einsammelt und anschließend das eigentliche \section-Kommando aufruft.
Hack #46: Von \sections und Hacks
147
#46
HACK
#46
Von \sections und Hacks
Wenn wir die Hack-Überschrift formatieren, können wir dann auf die eingesammelten Argumente zurückgreifen: \newcommand{\hack}[3]{% \def\@hacklevel{#1}% \def\@hacksubtitle{#3}% \section{#2}}
Aufgerufen wird das zum Beispiel wie \hack{expert}{Von \Cmd{section}s und Hacks} {Noch mehr über die Innereien dieses Buchs}
und als Benutzer muss man halt wissen, dass die Komplexitätsstufen beginner, moderate und expert heißen. Von hier ab weiter ist es klassisches titlesec-Futter: \titleformat{\section}[block]{}{}{0pt}{\hackformat} \titlespacing{\section}{13mm}{\baselineskip}{-7mm}
Der block-Stil von titlesec betrachtet den Titel als Absatz ohne eine eventuelle Nummerierung à la das übliche \section (jener Stil heißt bei titlesec übrigens hang). Die Formatierung und Nummerierung übernehmen wir selbst, also können alle Argumente leer bleiben bis auf das letzte, das für die tatsächliche Formatierung sorgt. Um der Klarheit willen haben wir das entsprechende Kommando \hackformat und nicht \sectionformat genannt: \newcommand{\hackformat}[1]{% \raisebox{-6.5mm}[0pt][0pt]{% \makebox[0cm][r]{% \raisebox{2mm}{\includegraphics[height=7mm]{\@hacklevel}}% \hacknum{\thesection}\hspace*{1mm}}}% {\sffamily\parskip=1pt {\fontseries{bc}\Large\filright\textcolor[gray]{0.4}{#1}\par}% {\fontseries{mc}\selectfont\filright\@hacksubtitle\par}}}
Für die Hack-Überschrift müssen wir verschiedene Elemente zusammenbringen. Die ersten paar Zeilen (beginnend mit \raisebox) kümmern sich um die Positionierung des Thermometers und des grauen Kastens mit der Hack-Nummer (den grauen Kasten selbst erzeugt das Kommando \hacknum). \includegraphics erhält als Argument die Schwierigkeitsstufe des Hacks, denn wie der Zufall es will, hat der O’Reilly-Verlag uns die drei Grafikdateien beginner.pdf, moderate.pdf und expert.pdf zur Verfügung gestellt. Der Rest des Kommandos ab \sffamily positioniert den eigentlichen Abschnittstitel (#1) und den vom \hack-Kommando gespeicherten Untertitel (\@hacksubtitle).
148
Kapitel 5: Gliederung und Verzeichnisse
HACK
Von \sections und Hacks
Als Letztes bleibt uns die Lüftung des Geheimnisses der Hack-Nummern im Untertitel jeder Kapitelüberschrift. Woher weiß das \chapter-Kommando, welche Hacks in seinem Kapitel stehen? Die Antwort darauf lautet: Hacks schreiben Informationen über das Kapitel, zu dem sie gehören, in die .aux-Datei des Dokuments. Diese Informationen werden beim nächsten Programmlauf gelesen und für die Kapitelüberschriften verfügbar gemacht. Und das geht so: Die Definition für \hack ist tatsächlich etwas komplexer als oben gezeigt, nämlich \newcommand{\hack}[3]{% \def\@hacklevel{#1}% \def\@hacksubtitle{#3}% \section{#2}% \protected@write\@auxout{}% {\string\chapterhack{\thechapter}{\thesection}}}
In den letzten beiden Zeilen wird für jeden Hack etwa Folgendes in die .aux-Datei geschrieben: \chapterhack{4}{39}
(für Hack Nr. 39 in Kapitel 4). Das \chapterhack-Kommando wird dann beim Lesen der .aux-Dateien am Anfang des nächsten Programmlaufs ausgeführt. Es ist wie folgt definiert: \newcommand*{\chapterhack}[2]{% \@ifundefined{ora@fh@\romannumeral#1}% {\global\@namedef{ora@fh@\romannumeral#1}{#2}}\relax \global\@namedef{ora@lh@\romannumeral#1}{#2}% }
In einer »normalen« Programmiersprache würde man vielleicht zwei Felder (Arrays) verwenden, um die Nummer des ersten und des letzten Hacks in jedem Kapitel zu speichern. TEX kennt keine Felder, so dass wir stattdessen einfach eine Folge von Kommandos verwenden, deren Namen die Kapitelnummer enthalten – bis auf das Problem, dass die Namen von TEX-Kommandos eigentlich auch keine Mischung von Ziffern enthalten dürfen.1 Wir helfen uns darum mit einem ganz gemeinen Hack: Das Kommando \romannumeral wandelt einen numerischen Wert in seine Darstellung als römische Zahl (!) um, und römische Zahlen bestehen aus der Sicht von TEX aus Buchstaben, kommen also als Bestandteile von Kommandonamen in Frage: \ora@fh@i, \ora@fh@ii, \ora@fh@iii, \ora@fh@iv, . . . 1
Abgesehen von Tricks mit \@namedef bzw. \csname. . . \endcsname natürlich – aber das würde voraussetzen, dass die Darstellung der Kapitelnummer etwas ist, was in so einer Konstruktion auftauchen darf. Die hier gezeigte Methode verwendet nur den numerischen Wert des Zählers und ist von seiner Darstellung unabhängig.
Hack #46: Von \sections und Hacks
149
#46
HACK
#47
Der Unterzeichnete . . .
Das Ganze passiert beim Einlesen (in TEXs »Mund«, wie die Terminologie ist . . . ), so dass die entsprechende Ersetzung auch innerhalb von \@namedef und \@nameuse erlaubt ist. Der erste Hack eines Kapitels steht immer in \ora@fh@. . . (für first hack), der letzte in \ora@lh@. . . (last hack) – jeder neue Hack überschreibt \ora@lh@. . . für dieses Kapitel, während \ora@fh@. . . nur gesetzt wird, wenn das Kommando vorher nicht definiert war, also beim ersten Hack im betreffenden Kapitel. Die Kapitelüberschrift bezieht sich danach einfach über die folgenden Kommandos auf die Hack-Nummern: \newcommand{\firsthack}[1]{\@nameuse{ora@fh@\romannumeral#1}} \newcommand{\lasthack}[1]{\@nameuse{ora@lh@\romannumeral#1}}
HACK
#47
Der Unterzeichnete . . . Wie Sie Vertragstexte mit LATEX setzen können
Als weiteres Beispiel dafür, wie Sie die Abschnittstitel von LATEX an Ihre Bedürfnisse anpassen können, folgt hier ein Beispiel aus der juristischen Welt. In Gesetzes- oder Vertragstexten wünscht man gerne eine fortlaufende Nummerierung von Artikeln oder Paragrafen auch über die Grenzen von »Abschnitten« hinweg, wie in Abbildung 5-1 zu sehen. Das dort gezeigte Dokument verwendet eine kleine Klasse namens contract, die die notwendige Formatierung realisiert. Hier werden kurz die wichtigsten Punkte daraus beschrieben: Der eigentliche Vertragstext beginnt mit der üblichen Präambel: \documentclass[12pt]{contract} \usepackage[latin1]{inputenc} \usepackage[T1]{fontenc} \usepackage[ngerman]{babel} \begin{document} \startcontract{Hägar dem Schrecklichen}{Hägar} {Kunibert dem Furchtsamen}{Kunibert}
Dabei ist das \startcontract-Kommando verantwortlich für die Überschrift und den Anfang des Vertrags. In contract.cls ist es wie folgt definiert: \RequirePackage{setspace} \newcommand*{\hereafter}[2]{#1, im Folgenden ‘‘#2’’ genannt} \newcommand*{\startcontract}[4]{% \begin{center} \begin{doublespace} {\LARGE\textbf{VERTRAG}}\\[1cm] Zwischen\\ \emph{\hereafter{#1}{#2}}\\
150
Kapitel 5: Gliederung und Verzeichnisse
HACK
Der Unterzeichnete . . .
VERTRAG Zwischen Hägar dem Schrecklichen, im Folgenden “Hägar” genannt und Kunibert dem Furchtsamen, im Folgenden “Kunibert” genannt wird Folgendes vereinbart:
Liegenschaften §1 Schiffsanleger Kunibert gestattet Hägar, seinen Schiffsanleger bei Burg Furchtsam zu benutzen. Im Gegenzug verpflichtet sich Hägar, diesen pfleglich zu behandeln und von willkürlichen Beschädigungen abzusehen.
§2 Burggarten Hägar verpflichtet sich, den Burggarten von Kunibert nicht öfter als viermal im Jahr zu verwüsten. Im Gegenzug stellt Kunibert ihm und seinen Mannen kostenlos seine Bocciakugeln zur Verfügung.
Tributleistungen §3 Naturalien Kunibert verpflichtet sich, . . .
§4 Gold Kunibert verpflichtet sich, . . .
Abbildung 5-1: Ein Vertrag
Hack #47: Der Unterzeichnete . . .
151
#47
HACK
#47
Der Unterzeichnete . . .
\ProvidesClass{contract}[2007/02/18 v0.1 "Contract" class (AL)] \LoadClassWithOptions{article} \RequirePackage[noindentafter]{titlesec} \RequirePackage{remreset} \RequirePackage{setspace} \pagestyle{empty} \titleformat{\section}[block] {\filcenter\Large\normalfont\bfseries} {}{0em}{} \titlespacing{\section}{5pc}{*3}{*1}[5pc] \titleformat{\subsection}[block] {\filcenter\large\normalfont\itshape} {\S\thesubsection}{1em}{} \titlespacing{\subsection}{5pc}{*2}{*1}[5pc] \@removefromreset{subsection}{section} \renewcommand*{\thesubsection}{\arabic{subsection}} \newcommand*{\hereafter}[2]{#1, im Folgenden ‘‘#2’’ genannt} \newcommand*{\startcontract}[4]{% \begin{center} \begin{doublespace} {\LARGE\textbf{VERTRAG}}\\[1cm] Zwischen\\ \emph{\hereafter{#1}{#2}}\\ und\\ \emph{\hereafter{#3}{#4}}\\ wird Folgendes vereinbart:\\ \end{doublespace} \end{center}} \endinput Abbildung 5-2: Die contract-Klasse
und\\ \emph{\hereafter{#3}{#4}}\\ wird Folgendes vereinbart:\\ \end{doublespace} \end{center}}
Das setspace-Paket [Hack #9] sorgt dabei für die zweizeilige Formatierung. Der Rest des Vertragstextes ist eigentlich eine ganz normale Abfolge von Abschnitten und Unterabschnitten:
152
Kapitel 5: Gliederung und Verzeichnisse
HACK
Der Unterzeichnete . . .
\section{Liegenschaften} \subsection{Schiffsanleger} Kunibert gestattet Hägar, seinen Schiffsanleger bei Burg Furchtsam zu benutzen. Im Gegenzug verpflichtet sich Hägar, diesen pfleglich zu behandeln und von willkürlichen Beschädigungen abzusehen.
Die Formatierung der Überschriften erledigen wir bequem über das titlesecPaket [Hack #45]. Hier ist wieder contract.cls: \titleformat{\section}[block] {\filcenter\Large\normalfont\bfseries} {}{0em}{} \titlespacing{\section}{5pc}{*3}{*1}[5pc] \titleformat{\subsection}[block] {\filcenter\large\normalfont\itshape} {\S\thesubsection}{1em}{} \titlespacing{\subsection}{5pc}{*2}{*1}[5pc]
Das vierte Argument von \titleformat gibt normalerweise an, wie und wo die Nummerierung erscheinen soll. Bei unserer Definition von \section ist es leer, so dass Abschnitte gar nicht nummeriert werden. Bei der \subsection setzen wir das Paragrafenzeichen (LATEXnisch »\S«, auch wenn Sie unter inputenc das Zeichen direkt eingeben können – aber wenn die Klassendatei gelesen wird, ist inputenc noch nicht aktiv). Die Notation »*3« in \titlespacing ist eine Abkürzung für »dreimal die x-Höhe der Schrift plus/minus ein bisschen was«. Fast der letzte interessante Punkt ist die Zählerverwaltung. Wir möchten vermeiden, dass mit dem Beginn einer neuen \section der \subsection-Zähler auf null zurückgesetzt wird. Dazu benutzen wir David Carlisles Paket remreset [Hack #46] und achten darauf, auch die Abschnittsnummer aus der formatierten Darstellung der Unterabschnittsnummer zu entfernen: \RequirePackage{remreset} \@removefromreset{subsection}{section} \renewcommand*{\thesubsection}{\arabic{subsection}}
Damit wissen Sie also alles, was Sie zur Erstellung Ihrer Tributverträge benötigen. Die komplette contract-Klasse sehen Sie noch einmal in Abbildung 5-2. Wir wünschen Ihnen fröhliches Plündern . . .
Hack #47: Der Unterzeichnete . . .
153
#47
HACK
#48
Inhaltlich korrekt HACK
#48
Inhaltlich korrekt Wie Sie das Inhaltsverzeichnis Ihres Dokuments manipulieren können
LATEX erstellt automatisch Inhaltsverzeichnisse (und andere einem Inhaltsverzeichnis ähnliche Listen, etwa eine Tabellen- und eine Abbildungsliste) aus den angegebenen Überschriften (oder Tabellen- und Abbildungslegenden). Dazu müssen Sie nur das Kommando \tableofcontents dort in Ihrem Dokument platzieren, wo Sie das Inhaltsverzeichnis später gerne vorfinden wollen. Zum Erstellen des Inhaltsverzeichnisses schreibt LATEX die Überschriften in eine Datei, die so heißt wie die Eingabedatei, deren Name aber auf .toc statt .tex endet. Diese Datei wird beim nächsten Lauf gelesen und als Inhaltsverzeichnis benutzt, während LATEX eine neue Version derselben Datei schreibt. Wenn Sie wollen, dass Ihr Inhaltsverzeichnis stimmt, müssen Sie also unter Umständen mehrere LATEX-Läufe durchführen, bis sich nichts mehr ändert. LATEX kennt im Wesentlichen zwei Kommandos, um Material in ein Inhaltsverzeichnis zu bringen. \addcontentsline fügt eine Zeile mit einer Überschrift ein, die aus einem Gliederungs- oder \caption-Kommando kommt: \addcontentsline{toc}{section} {\protect\numberline{\thesection}Einleitung}
Dabei ist das erste Argument die Endung der Datei, in der die Zeile landen soll (»toc« steht für das Inhaltsverzeichnis, »lof« und »lot« respektive für das Abbildungs- und Tabellenverzeichnis). Das nächste Argument gibt die Gliederungsstufe an, für die eine Zeile geschrieben wird, und das dritte ist die Zeile selbst mit einer etwas umständlichen Konstruktion, die die korrekte Nummer ins Verzeichnis schreibt. Das Ganze sieht dann ungefähr so aus: \contentsline{section}{\numberline{1.1}Einleitung}{3}
Dabei ist die letzte »{3}« die Seitennummer, die von \addcontentsline hinzugefügt wird. Das zweite Kommando, \addtocontents, dient dazu, beliebiges Material in ein Inhaltsverzeichnis zu schreiben. Es hilft nicht nur bei der Implementierung von \addcontentsline, sondern kann zum Beispiel dafür sorgen, dass zwischen den Inhaltsverzeichnis-Einträgen von zwei Kapiteln etwas zusätzlicher Freiplatz erzeugt wird: \addcontentsline{toc}{\addvspace{.5\baselineskip} Das \addvspace-Kommando dient dazu, vertikalen Leerraum hinzuzufügen, und zwar – im Gegensatz zu \vspace – in Abhängigkeit von anderem vertikalen Leerraum, der vielleicht schon unmittelbar davor existiert. Die genaue Funktionsweise von
154
Kapitel 5: Gliederung und Verzeichnisse
HACK
Inhaltlich korrekt \addvspace ist ein bisschen vertrackt, aber im Großen und Ganzen läuft es darauf hinaus, dass \addvspace dafür sorgt, dass an der betreffenden Stelle so viel Leerraum steht, wie sein Argument angibt, oder aber so viel, wie schon unmittelbar davor eingefügt wurde, je nachdem, welche der beiden Möglichkeiten größer ist.
Das könnten Sie zum Beispiel in ein selbst definiertes \chapter-Kommando einbauen (siehe Überschriften mit Stil [Hack #45]). Sie müssen dabei aufpassen: Die Kommandos \addcontentsline, \addtocontents und \addvspace sehen aus wie Benutzerkommandos, sind aber nicht wirklich als solche gedacht – ihre Verwendung kann fremdartige und wundersame Nebenwirkungen haben. Sie sollten sie sicherheitshalber nur in Klassen oder Paketen verwenden, und dort auch nur, wenn Sie sich etwas mit ihnen auskennen.
Um das tatsächliche Inhaltsverzeichnis zu setzen, ruft \contentsline jeweils ein Kommando der Form l@Typ auf. Typ entspricht dabei dem ersten Argument des Kommandos \contentsline. Eine Zeile der Form \contentsline{section}{...}{...}
wird also zu einem Aufruf von \l@section{...}{...}
Der Autor der Dokumentklasse muss für jede Gliederungsstufe im Dokument ein solches l@. . . -Kommando vorsehen. LATEX bietet dazu ein Kommando namens \@dottedtocline, das die üblichen Dokumentklassen für die Gliederungsstufen \section und darunter verwenden (article: \subsection und darunter). \part und \chapter sind normalerweise speziell definiert. \@dottedtocline hat fünf Parameter, die letzten beiden davon übernimmt es eins zu eins von \contentsline. Die ersten drei bestimmen respektive die Ebene des Eintrags (dabei kommt die tocdepth-Einstellung [Hack #44] zum Tragen: \contentsline-Einträge, deren erster Parameter größer als der Wert von tocdepth ist, werden ignoriert), den Einzug am linken Rand und die Menge an Platz, die für die Gliederungsnummer (im Verzeichniseintrag der Parameter von \numberline) zur Verfügung steht.
Der häufigste Fall, warum Sie an den Vorgaben für das Inhaltsverzeichnis etwas ändern wollen, tritt auf, wenn Sie viele Kapitel mit vielen Abschnitten haben. Sind sowohl die Kapitelnummer als auch die Abschnittsnummer zweistellig, stößt die letzte Ziffer der Abschnittsnummer unmittelbar an den Text des Eintrags oder kann diesen sogar überlappen. Hier sollten Sie das \l@section-Kommando so anpassen, dass der dritte Parameter etwas größer
Hack #48: Inhaltlich korrekt
155
#48
HACK
#48
Inhaltlich korrekt
ist. Vermutlich müssen Sie auch \l@subsection und tiefere Ebenen modifizieren – hier den zweiten Parameter, die Einrückung –, damit das Ganze wieder harmonisch aussieht. Ebenfalls Probleme machen kann kapitelweise Seitennummerierung [Hack #26], und zwar wenn Sie Seitennummern bekommen wie »5–103«, die den für Seitennummern vorgesehenen Platz überschreiten. In diesem Fall sollten Sie den globalen Parameter \@pnumwidth so anpassen, dass der breiteste Eintrag hineinpasst: \makeatletter \settowidth{\@pnumwidth}{\textbf{99--99}} \makeatother
Andere möglicherweise interessante Parameter sind \@tocrmarg, der rechte Rand für die erste bis vorletzte Zeile von mehrzeiligen Verzeichniseinträgen, und \@dotsep, der Abstand der Punkte zwischen dem Verzeichniseintrag und der Seitennummer. \@tocrmarg ist eine Länge und \@dotsep eine Zahl, aber beide müssen mit \renewcommand geändert werden.
Das titletoc-Paket Das Paket titletoc von Javier Bezos arbeitet mit titlesec (Überschriften erzeugen mit Stil [Hack #45]) zusammen, kann aber auch alleine verwendet werden. Wie titlesec versucht es nicht, LATEX-Interna umzudefinieren, sondern stellt neue generische Kommandos zur Formatierung von Inhaltsverzeichnissen zur Verfügung. Dabei behebt es auch einige Probleme der LATEX-eigenen Implementierung, zum Beispiel vermeidet es einen Seitenumbruch zwischen einem Verzeichniseintrag für ein Kapitel und dem für dessen ersten Abschnitt. Die zwei wesentlichen Kommandos, die titletoc zur Formatierung von Inhaltsverzeichnissen verwendet, sind \titlecontents und \dottedcontents. Dabei dient \dottedcontents zur Formatierung von Einträgen, bei denen der Titel und die Seitenzahl mit Punkten verbunden sind. \titlecontents macht das nicht automatisch. (\dottedcontents ist ein Sonderfall von \titlecontents.) In Abbildung 5-3 sehen Sie ein typisches Inhaltsverzeichnis, wie es die LATEXKlasse book liefern würde; die Eingabe dafür lautet: \titlecontents{chapter}[1.5em]{\addvspace{1em}\bfseries} {\contentslabel{1.5em}}{\hspace*{-1.5em}} {\hfill\contentspage}} \dottedcontents{section}[3.8em]{}{2.3em}{1pc} \dottedcontents{subsection}[7.0em]{}{3.2em}{1pc}
»\titlecontents{chapter}« gibt dabei die Formatierung für die Kapitelzei156
Kapitel 5: Gliederung und Verzeichnisse
HACK
Inhaltlich korrekt
Inhaltsverzeichnis Vorwort
3
1
5 5 6
2
Erstes Kapitel 1.1 Erster Abschnitt . . . . . . . . . . . . . . . . . . 1.2 Zweiter Abschnitt. . . . . . . . . . . . . . . . . . 1.2.1 Erster Unterabschnitt, mit einer überaus langen und trotzdem fast völlig nichtssagenden Überschrift, die vor allem dazu gedacht ist, eine Menge Platz einzunehmen . . . . 1.2.2 Zweiter Unterabschnitt . . . . . . . . . . . . . 1.3 Dritter Abschnitt . . . . . . . . . . . . . . . . . . Zweites Kapitel, ebenfalls mit einer langen und Platzverbrauch komplett nutzlosen Überschrift 2.1 Erster Abschnitt . . . . . . . . . . . . 2.1.1 Erster Unterabschnitt . . . . . . . 2.1.2 Zweiter Unterabschnitt . . . . . . . 2.2 Zweiter Abschnitt. . . . . . . . . . . . 2.3 Dritter Abschnitt . . . . . . . . . . . .
6 6 6
bis auf ihren . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
7 7 7 8 8 8
Abbildung 5-3: Inhaltsverzeichnis mit titletoc
len an. Das nächste Argument, »[1.5em]«, ist entgegen dem, was die eckigen Klammern suggerieren, nicht optional und gibt die Einrückung vom linken Rand aus an, und zwar für den kompletten Eintrag (Sie sehen das an der zweiten Zeile des Titels des zweiten Kapitels). Das zweite Argument, »{\addvspace{1em}}«, enthält Code, der vor der eigentlichen Kapitelzeile ausgegeben wird – hier erzeugen wir eine Leerzeile vor dem Eintrag und sorgen dafür, dass der komplette Eintrag fett gedruckt wird. Sie könnten hier auch Kommandos wie \filleft oder \filcenter verwenden, die Sie aus titlesec kennen. Die Kapitelnummer ist in diesem Moment bekannt und steht in \thecontentslabel zur Verfügung, so dass Sie auch Fallunterscheidungen (etwa mit dem ifthen-Paket) vornehmen könnten. Die nächsten beiden Argumente von \titlecontents beschreiben die Formatierung von Zeilen mit respektive ohne Kapitelnummer. Bei einer Zeile ohne Kapitelnummer machen wir einfach die Einrückung rückgängig, damit der Titel dort beginnt, wo sonst die Kapitelnummer steht (beachten Sie die Zeile Hack #48: Inhaltlich korrekt
157
#48
HACK
#48
Inhaltlich korrekt
»Vorwort«). Ginge die Überschrift über zwei oder mehr Zeilen, würden die Folgezeilen eingerückt anfangen. Wenn dagegen eine Kapitelnummer ausgegeben werden muss, sorgt das Kommando \contentslabel{1.5em} dafür, dass die Kapitelnummer linksbündig in einem Feld der angegebenen Breite untergebracht wird. Das letzte Argument schließlich (\hfill\contentspage) erklärt die Formatierung der Seitennummer am Ende des »Absatzes« – wir füllen die Zeile nach rechts auf und platzieren die Seitennummer ganz am rechten Rand. Theoretisch gäbe es noch ein optionales Argument ganz am Schluss, mit dem Sie Code angeben können, der nach dem Eintrag ausgeführt wird, aber das kommt in unserem Beispiel nicht vor. Die Formate für Abschnitte und Unterabschnitte im Inhaltsverzeichnis definieren wir über das \dottedcontents-Kommando. Das »optionale« Argument (das in Wirklichkeit genauso wenig optional ist wie sein Pendant bei \titlecontents) gibt wieder die Gesamteinrückung des Absatzblocks an, in dem jeder Abschnitts- oder Unterabschnittstitel formatiert wird. Das nächste Argument (hier leer) gibt ebenfalls wie bei \titlecontents Code für die globale Formatierung des Eintrags an, und das darauffolgende Argument enthält die Breite des Felds für die Nummer. Beachten Sie dabei, dass die Einrückung der Kapitelzeilen (1.5em) und die Breite des Nummernfelds für Abschnittszeilen (2.3em) genau die Einrückung der Abschnittszeilen (3.8em) ergibt – auf diese Weise erscheinen die Abschnittsnummern bündig mit den Kapitelnamen. (Für Abschnitte und Unterabschnitte gilt sinngemäß dasselbe.) Das letzte Argument – »{1pc}« – gibt den Abstand der Punkte an, die den Abschnitts- oder Unterabschnittstitel mit der Seitennummer verbinden. Hier sind zur Illustration noch die Definitionen für das Inhaltsverzeichnis in diesem Buch: \definecolor{tocgray}{gray}{0.5} \RequirePackage{titletoc} \contentsmargin{7mm} \titlecontents{chapter}[0pt]{\addvspace{4mm}% \large\sffamily\fontseries{bc}\selectfont \color{tocgray}} {Kapitel \thecontentslabel.\hspace{.5em}}{} {\titlerule*[.5pc]{.}\tocchap\contentspage} \titlecontents{section}[1.5cm]{}% {\contentslabel[\hfill\thecontentslabel.\hspace{.5em}]{3em}} {}{\hfill\contentspage}
Bemerkenswert an diesen Kommandos ist zunächst die Umkehrung der Punkte – LATEX-Standard sind Punkte hinter Abschnitts- und Unterabschnitts-Einträgen, damit das Auge leicht zur Seitenzahl am rechten Rand findet, während 158
Kapitel 5: Gliederung und Verzeichnisse
HACK
Inhaltlich korrekt
die Seitenzahl zu einem Kapiteltitel schon durch ihre Formatierung ins Auge sticht (Verwechslungen sind da kaum möglich). In O’Reilly-Hacks-Büchern haben die Kapiteleinträge Punkte und die Abschnitte keine, eine Entscheidung, über die sich durchaus streiten lässt. Wir müssen uns auf Kapiteleinträge mit und ohne Kapitelnummer vorbereiten (Letztere für »Credits«, »Einleitung« und so weiter), so dass wir trotz der Punkte nicht \dottedcontents, sondern \titlecontents verwenden müssen. Kapiteleinträge werden offiziell gar nicht eingerückt, was wir uns leisten können, da es keine mehrzeiligen Kapitelnamen gibt; diese Abkürzung erspart uns das erneute Ausrücken der Kapitelüberschriften im Inhaltsverzeichnis.
Ganz andere Inhaltsverzeichnisse Manchmal bietet es sich an, ein Inhaltsverzeichnis nicht mit einem Eintrag pro Zeile zu setzen, sondern eine Reihe von Einträgen fortlaufend in einem Absatz unterzubringen. titletoc unterstützt auch das, nämlich mit dem Kommando \titlecontents*. \titlecontents* übernimmt dieselben Argumente wie \titlecontents (ohne Stern), außer dass am Ende statt einem optionalen Argument für den Abschlusscode bis zu drei optionale Argumente stehen können, die steuern, wie die Einträge im Absatz aneinandergehängt werden: \titlecontents*...{Seitenformat}[Zwischen] \titlecontents*...{Seitenformat}[Zwischen][Ende] \titlecontents*...{Seitenformat}[Start][Zwischen][Ende]
Diese Kommandos werden wie folgt verwendet: Ein Eintrag im Inhaltsverzeichnis ist entweder • der erste Eintrag. In diesem Fall wird das Start-Kommando ausgeführt und dann der Eintrag gesetzt. • ein Eintrag, der einem anderen Eintrag folgt. Dabei gibt es die folgenden Fälle:
– Die beiden Einträge stehen auf derselben Stufe. Das Zwischen-Kommando wird ausgeführt und der neue Eintrag gesetzt. – Der neue Eintrag steht auf einer tieferen Stufe (etwa ein Unterabschnitt gegenüber einem Abschnitt). In diesem Fall wird das StartKommando ausgeführt, der neue Eintrag gesetzt und es geht auf dessen Stufe weiter. – Der neue Eintrag steht auf einer höheren Stufe (etwa ein Abschnitt gegenüber einem Unterabschnitt). Dabei können auch mehrere Abschnitte übersprungen werden! Für alle Stufen – beginnend mit der-
Hack #48: Inhaltlich korrekt
159
#48
HACK
#48
Inhaltlich korrekt
Inhaltsverzeichnis Vorwort
3
1
5
Erstes Kapitel §1.1. Erster Abschnitt, 5 – §1.2. Zweiter Abschnitt, 6 – §1.3. Dritter Abschnitt, 6
2
Zweites Kapitel, ebenfalls mit einer langen und bis auf ihren Platzverbrauch komplett nutzlosen Überschrift
7
§2.1. Erster Abschnitt, 7 – §2.2. Zweiter Abschnitt, 8 – §2.3. Dritter Abschnitt, 8
Abbildung 5-4: Inhaltsverzeichnis mit Absatzformatierung
jenigen des vorigen Eintrags und endend mit derjenigen direkt unterhalb der des aktuellen Eintrags – wird das Ende-Kommando ausgeführt. Wenn der neue Eintrag selber noch im Absatz formatiert werden soll, wird anschließend das Zwischen-Kommando ausgeführt, um die Verbindung zwischen diesem Eintrag und dem vorigen Eintrag auf derselben Stufe (den es geben sollte) herzustellen. Anschließend wird der neue Eintrag gesetzt. Alle Änderungen an Absatzformaten müssen Sie im Start-Kommando der äußersten Gliederungsebene angeben, die an dem Absatz beteiligt ist. Da bei der Absatzformatierung immer diejenigen Werte angenommen werden, die am Absatzende gelten, ist dies die einzige Möglichkeit um sicherzustellen, dass sie tatsächlich beachtet werden.
Abbildung 5-4 zeigt ein Beispiel für ein Inhaltsverzeichnis mit Absatzformatierung. Die entsprechenden Kommandos dafür lauten: \titlecontents{chapter}[1.5em]{\addvspace{1em}\bfseries} {\contentslabel{1.5em}} {\hspace*{-1.5em}}{\hfill\contentspage}[\addvspace{3pt}] \titlecontents*{section}[1.5em]{\filright\itshape} {\S\thecontentslabel.~}{}{,~\thecontentspage}[ -- ] \setcounter{tocdepth}{1}
160
Kapitel 5: Gliederung und Verzeichnisse
HACK
Inhaltlich korrekt
Inhaltsverzeichnis Vorwort
3
1
Erstes Kapitel §1.1. Erster Abschnitt, 5 – §1.2. Zweiter Abschnitt, 6 (Unterabschnitte: §1.2.1. Erster Unterabschnitt, mit einer überaus langen und trotzdem fast völlig nichtssagenden Überschrift, die vor allem dazu gedacht ist, eine Menge Platz einzunehmen, 6; §1.2.2. Zweiter Unterabschnitt, 6) – §1.3. Dritter Abschnitt, 6
5
2
Zweites Kapitel, ebenfalls mit einer langen und bis auf ihren Platzverbrauch komplett nutzlosen Überschrift
7
§2.1. Erster Abschnitt, 7 (Unterabschnitte: §2.1.1. Erster Unterabschnitt, 7; §2.1.2. Zweiter Unterabschnitt, 8) – §2.2. Zweiter Abschnitt, 8 – §2.3. Dritter Abschnitt, 8
Abbildung 5-5: Inhaltsverzeichnis mit Absatzformatierung und Unterabschnitten
Das etwas konstruierte Beispiel in Abbildung 5-5 zeigt den Einsatz der Start-, Zwischen- und Ende-Kommandos bei verschachtelten Absätzen. Hier sind die dazugehörigen Definitionen: \titlecontents*{section}[1.5em]{\filright\itshape} {\S\thecontentslabel.~}{}{,~\thecontentspage} [ -- ] \titlecontents*{subsection}[0pt]{} {\S\thecontentslabel.~}{}{,~\thecontentspage} [ (\textbf{Unterabschnitte:} ][; ][)]
(Die Kapitelebene ist dieselbe.) Wie Sie sehen, setzt das titletoc-Paket Ihrer Kreativität kaum Grenzen. Lassen Sie Ihre Fantasie spielen!
Siehe auch • Die Dokumentation zu titlesec enthält noch mehr Beispiele für den Umgang mit titletoc.
Hack #48: Inhaltlich korrekt
161
#48
HACK
#49
Sneak Preview HACK
#49
Sneak Preview Platzieren Sie am Kapitelanfang ein Mini-Inhaltsverzeichnis des folgenden Kapitels.
Gerade in großen Dokumenten kann es nützlich sein, am Anfang jedes Kapitels eine kurze Übersicht über die Inhalte des Kapitels zu platzieren, eine Art »Mini-Inhaltsverzeichnis«. LATEX unterstützt auch das über das Paket titletoc. Sie müssen nur dafür sorgen, dass etwa für kapitelweise Inhaltsverzeichnisse am Anfang jedes Kapitels das Kommando \startcontents
ausgeführt wird – wenn Sie Ihre Kapitelanfänge ohnehin mit titlesec formatieren, ist das kein Problem: \titleformat{\chapter}[...] {...}{...}{...} % Was auch immer [\startcontents \printcontents{1}{\setcounter{tocdepth{1}}]
Hier sehen Sie auch gleich, wie Sie das Mini-Inhaltsverzeichnis ausgeben können: Darum kümmert sich das Kommando \printcontents. Das erste Argument – hier »1« – legt die oberste Gliederungsebene im Inhaltsverzeichnis fest; »1« entspricht Abschnitten (siehe Tabelle 5-1). Das zweite Argument gibt Code an, der vor der Erzeugung des Inhaltsverzeichnisses ausgeführt wird. So sorgen wir dafür, dass nur Abschnitte im Inhaltsverzeichnis erscheinen. Ein Beispiel für ein solches Mini-Inhaltsverzeichnis zeigt Abbildung 5-6. Wir haben es mit der folgenden Kapiteldefinition angelegt: \titleformat{\chapter}[display] {\normalfont\Large\filcenter\sffamily} {\titlerule[1pt]\vspace{1pt}% \titlerule\vspace{1pc}% \LARGE\MakeUppercase{\chaptertitlename} \thechapter} {1pc}{\titlerule\vspace*{1pc}\Huge} [\normalsize\normalfont\vspace*{1cm}% \startcontents \printcontents{}{1}{\setcounter{tocdepth}{2}}]
(Das Format für die Kapitelüberschrift haben wir aus der Dokumentation zum titlesec-Paket geliehen.) Interessant ist vor allem das letzte (optionale) Argument. Dort müssen wir auf die normale Schrift und Größe zurückschalten (ansonsten gilt das für die Überschrift eingestellte »\Huge« weiter), lassen etwas vertikalen Platz frei und starten dann das Mini-Inhaltsverzeichnis neu. Als Nächstes geben wir das Mini-Inhaltsverzeichnis vom vorigen LATEX-Lauf
162
Kapitel 5: Gliederung und Verzeichnisse
HACK
Sneak Preview
KAPITEL 1
Erstes Kapitel 1.1 1.2
1.3
Erster Abschnitt . . . . . . . . . . . . . . . . . . Zweiter Abschnitt. . . . . . . . . . . . . . . . . . 1.2.1 Erster Unterabschnitt, mit einer überaus langen und trotzdem fast völlig nichtssagenden Überschrift, die vor allem dazu gedacht ist, eine Menge Platz einzunehmen . . . . 1.2.2 Zweiter Unterabschnitt . . . . . . . . . . . . . Dritter Abschnitt . . . . . . . . . . . . . . . . . .
6 7
7 7 7
Abbildung 5-6: Kapitelanfang mit Mini-Inhaltsverzeichnis
aus, und zwar die Abschnitts- und Unterabschnittseinträge (dies diktiert die tocdepth-Definition). Natürlich funktioniert das auch für absatzbasierte Inhaltsverzeichnisse mit \titlecontents*. Die Grundregel ist, dass im Mini-Inhaltsverzeichnis immer genau die Formatierung verwendet wird, die für dieselbe Gliederungsstufe auch für das Haupt-Inhaltsverzeichnis gilt. Allerdings können Sie im
KAPITEL 1
Erstes Kapitel Erster Abschnitt, 6 — Zweiter Abschnitt, 7 — Dritter Abschnitt, 7
Abbildung 5-7: Kapitelanfang mit Mini-Inhaltsverzeichnis im Absatzstil
Hack #49: Sneak Preview
163
#49
HACK
#50
Auf dem Index
\printcontents-Kommando als ersten Parameter ein Präfix angeben, das dann
allen Formatnamen für dieses Inhaltsverzeichnis vorangestellt wird. Mit \printcontents{para}{1}{...}
zum Beispiel würden nicht wie üblich die Formate section, subsection usw. herangezogen, sondern parasection, parasubsection und so weiter. Natürlich sollten Sie dafür sorgen, dass diese mit \titlecontents, \titlecontents* oder \dottedcontents definiert sind, damit der Versuch nicht ins Leere läuft. Hier ist ein Beispiel: \titleformat{\chapter}[display] ... [\normalsize\normalfont\vspace*{1cm}% \startcontents \printcontents{p}{1}{\setcounter{tocdepth}{1}}] \titlecontents*{psection}[1.5em]{\filcenter} {}{}{,~\thecontentspage} [ --- ]
Das \printcontents-Kommando spezifiziert hier das Präfix »p«, und entsprechend wird das Format psection verwendet. Andere Formate müssen wir nicht definieren, da im Verzeichnis nur Abschnitte auftauchen.
HACK
#50
Auf dem Index Generieren Sie ein Stichwortverzeichnis.
Fachbücher und ähnliche Werke mit Nachschlagecharakter profitieren oft von einem Index oder Stichwortverzeichnis, das für interessante Begriffe aus dem Buch von irgendeiner leicht auffindbaren Stelle (etwa einer alphabetischen Liste am Schluss des Buchs) auf Plätze weiter vorne zurückverweist, wo der Begriff vorkommt. Die Erstellung eines guten Index ist und bleibt in weiten Teilen Handarbeit, da es in der Regel nicht reicht, auf alle Plätze zu verweisen, wo der Suchbegriff auftritt – es müssen schon die sein, wo wirklich etwas Interessantes gesagt wird. Aber immerhin kann LATEX dafür sorgen, dass die Seitennummern im Index stimmen (und das ist ja auch schon mal was). Um einen Index zu erstellen, müssen Sie LATEX zunächst mitteilen, dass Sie das vorhaben. Das erreichen Sie mit dem Kommando \makeindex in der Präambel Ihres Dokuments. Mit dem Kommando \index können Sie innerhalb Ihres Dokuments Indexeinträge setzen: ... Albert Einstein\index{Einstein, Albert} postulierte ...
164
Kapitel 5: Gliederung und Verzeichnisse
HACK
Auf dem Index
Diese werden in eine Datei geschrieben, die so heißt wie Ihre LATEX-Quellcodedatei, aber die Endung .ind hat. Diese Datei wird auf irgendeine magische Weise in eine Datei mit der Endung .idx überführt, die dann mit dem Kommando \printindex dort in Ihr Dokument eingebaut wird, wo Sie den Index gerne haben möchten. Die »magische Weise« ist übrigens in der Regel ein Programm namens makeindex, das sich um die korrekte Sortierung und sonstige Aufbereitung des Index kümmert. makeindex hat schon etliche Jahre auf dem Buckel und leidet an diversen Gebrechen, stellt aber nach wie vor den Standard dar – ein Nachfolgeprogramm namens xindy wurde zwar entwickelt, hat sich aber aus verschiedenen Gründen noch nicht weithin durchgesetzt. Es gibt einige Konventionen, wie Indexeinträge aussehen sollen, damit makeindex die besten Resultate liefert (siehe dazu Tabelle 5-2). makeindex rufen Sie einfach mit dem Namen der idx-Datei auf: $ makeindex buch.idx
Manche Bücher enthalten mehrere Indizes, etwa einen Personenindex und einen für die Sachbegriffe. Das gibt LATEX aus dem Stand nicht her – Sie brauchen das index-Paket von David M. Jones, das die entscheidenden Kommandos \makeindex, \index und \printindex in erweiterter Form neu implementiert. Damit können Sie einen separaten Personenindex etwa so deklarieren: \newindex{per}{pdx}{pnd}{Personenindex} per dient dabei zum Identifizieren des Personenindex; die unsortierten Einträge landen in einer Datei mit der Endung .pdx, \printindex erwartet die
sortierten Einträge in einer Datei mit der Endung .pnd und überschreibt den Index mit dem Titel »Personenindex«. Der entsprechende makeindex-Aufruf lautet dann $ makeindex -o buch.pnd buch.pdx
(beachten Sie die explizite Angabe des Namens der Ausgabedatei). Einträge in den Personenindex machen Sie mit Tabelle 5-2: Indexeintragsformate für makeindex Eintrag Wort Wort!Buchstaben von Wort@xxx Wort|( Wort|) Wort|α
Bedeutung Eintrag erscheint als »Wort«. Eintrag erscheint als »Buchstaben von« unter dem Eintrag »Wort«. Geht auch über mehr als zwei Stufen. Eintrag erscheint als »xxx« an der Position von »Wort«. Beginnt einen Seitenbereich für »Wort«. Beendet einen Seitenbereich für »Wort«. Formatiert die Seitennummer für den Eintrag als \α{n}.
Hack #50: Auf dem Index
165
#50
HACK
#51
Bibliografiestile testen
... Albert Einstein\index[per]{Einstein, Albert} ...
wobei per das Kürzel ist, das Sie auch im \newindex verwendet haben. Wenn Sie kein Kürzel angegeben haben, wird default angenommen, das entspricht dem »Standardindex«. Das index-Paket greift in diverse andere Bereiche von LATEX ein, auch solche, wo Sie das vielleicht nicht erwarten. Deswegen kann es zu Inkompatibilitäten mit anderen Paketen kommen.
HACK
#51
Bibliografiestile testen Probieren Sie Bibliografiestile aus und vergleichen Sie sie miteinander – ohne viel Aufwand.
BibTEX ist ein nützliches Werkzeug für alle, die Publikationen mit ausführlichen Quellenangaben verfassen. Es ermöglicht das Sammeln aller relevanten Quellen in »Datenbanken« (speziell formatierten Dateien mit der Endung bib) und kann anhand der \cite-Kommandos in einer LATEX-Datei – oder streng genommen den Einträgen in der aux-Datei eines Dokuments, die sich aus dem LATEX-Lauf ergibt – eine thebibliography-Umgebung zusammenstellen, die genau die im betreffenden Dokument zitierten Quellen enthält. Diese Umgebung schreibt es in eine Datei mit dem Namen des betrachteten Dokuments und der Endung bbl. Über Bibliografiestile (in Dateien mit der Endung bst) können Sie das Aussehen der Quellen in der Liste sowie deren Sortierung manipulieren. BibTEX und LATEX bieten vorgefertigte Unterstützung für einfache in der Reihenfolge des Zitiertwerdens nummerierte Listen bis hin zu komplexen namensbasierten Verweisen der Form »Schlaumeier und Ausgefuchst (2007)«, und Sie selbst haben bei Bedarf die genaue Kontrolle über das Erscheinungsbild der verschiedenen Quellen – jedenfalls wenn Sie bereit sind, sich auf die etwas verquere Programmiersprache einzulassen, in der die bstDateien verfasst sind. In diesem Hack werden wir darüber nicht ins Detail gehen, sondern zeigen Ihnen lieber, wie Sie sich ohne viel Aufwand ein Bild davon verschaffen können, was ein Bibliografiestil aus Ihrer Literaturliste macht, und wie Sie die Ergebnisse mehrerer verschiedener Bibliografiestile bequem vergleichen. Das ist nützlich, um den geeigneten Bibliografiestil für ein Dokument auszuwählen, und hilft auch beim Erstellen und Debuggen eigener Bibliografiestile (für die Mutigen). Uns geht es darum, ein LATEX-Dokument zu erzeugen, das die Quellen in einer gegebenen bib-Datei mehrere Male gemäß unterschiedlicher Bibliografiestile formatiert enthält. Der Einfachheit halber verwenden wir ein Perl-Skript, bstsample, das die Fußarbeit übernimmt – die Idee ist dabei, Aufwand zu ver166
Kapitel 5: Gliederung und Verzeichnisse
HACK
Bibliografiestile testen
1
plain
\cite{0.tagungsband}: [1] \cite{0.article}: [2] \cite{0.tagungsbeitrag}: [3] \cite{0.inbook}: [4]
References [1] John Doe, editor. A Conference Proceedings, volume 2 of Conferences on Whatever, Sampleville, YY, May 2005. Conference Organizer, Publisher. [2] John Doe. A journal article. Journal of the ACM, 12(3):456–467, January 2007. A note. [3] Susan McSample and John Doe. A conference contribution. In Doe [1]. [4] Jane Roe. A Book, chapter 12, pages 789–890. Number 2 in Book Series. Publisher, Anywhere, XX, second edition, 2006.
2
abbrv
\cite{1.tagungsband}: [1] \cite{1.article}: [2] \cite{1.tagungsbeitrag}: [3] \cite{1.inbook}: [4]
References [1] J. Doe, editor. A Conference Proceedings, volume 2 of Conferences on Whatever, Sampleville, YY, May 2005. Conference Organizer, Publisher. [2] J. Doe. A journal article. J. ACM, 12(3):456–467, Jan. 2007. A note. [3] S. McSample and J. Doe. A conference contribution. In Doe [1]. [4] J. Roe. A Book, chapter 12, pages 789–890. Number 2 in Book Series. Publisher, Anywhere, XX, second edition, 2006.
Abbildung 5-8: Zwei Bibliografiestile zum Vergleich, mit bstsample
Hack #51: Bibliografiestile testen
167
#51
HACK
#51
Bibliografiestile testen
meiden, indem bstsample direkt eine aux-Datei schreibt, die bei einem LATEXLauf hätte entstanden sein können. Auf diese aux-Datei wendet es BibTEX an und fügt den Inhalt der resultierenden bbl-Datei dem Gesamtdokument hinzu. Außerdem baut es noch die \cite-Kommandos ein, damit Sie auch deren Ausgabe prüfen und vergleichen können. bstsample übernimmt von der Kommandozeile eine Reihe von Namen von Bibliografiestilen, die herangezogen werden, um eine BibTEX-Datenbank namens bibsample.bib zu formatieren. Die Ausgabe landet dabei in einer Datei namens bibsample.tex, die Sie anschließend mit LATEX bearbeiten können (zweimal, damit die Querverweise stimmen). Ein Beispiel für die Ausgabe von bstsample sehen Sie in Abbildung 5-8; sie enthält das Resultat von $ bstsample plain abbrv
Beachten Sie die Unterschiede zwischen den Bibliografiestilen – in beiden sind die Zitate fortlaufend in der Reihenfolge des Auftretens nummeriert. Allerdings werden in abbrv die Vornamen der Autoren, Zeitschriftennamen (falls bekannt), Monatsnamen usw. abgekürzt, während sie in plain ausgeschrieben werden. In Abbildung 5-9 sehen Sie den Anfang des Perl-Skripts. Es unterstützt die Optionen »--bib« und »--out«, mit denen Sie respektive den Namen der zu bearbeitenden BibTEX-Datenbank (standardmäßig bstsample) und den Namen der Ausgabedatei (ohne .tex, standardmäßig ebenfalls bstsample) angeben können. Die Option »--class« dient zur Spezifikation der Dokumentklasse. Mit »--packages« können Sie weitere LATEX-Pakete einbinden, wobei Sie mit ... --packages="url babel:english,ngerman" ...
dafür sorgen können, dass die Ausgabe die Zeilen \usepackage{url} \usepackage[english,ngerman]{babel}
enthält. Die Option »--preamble« wiederum übernimmt Zeilen, die dann direkt in die Ausgabe-LATEX-Datei geschrieben werden. Um die Interpretation dieser Optionen kümmert sich der Code ab der foreach-Schleife im unteren Teil von Abbildung 5-9. Hier ist noch ein etwas involvierteres Beispiel, mit Optionen: $ bstsample -b bstsample -pkgs=natbib \ # -o bst-natbib plainnat:citet,citep abbrvnat:
Dieser Aufruf formatiert die Literaturliste in bstsample.bib gemäß der Bibliografiestile plainnat und abbrvnat. Die Ausgabe landet in bst-natbib.tex. Für je-
168
Kapitel 5: Gliederung und Verzeichnisse
HACK
Bibliografiestile testen
#!/usr/bin/perl # bstsample: Formatiere eine bib-Datei mit verschiedenen # Bibliografie-Stilen use strict; use Getopt::Long; my my my my
($bib, $out) = (’bstsample’, ’bstsample’); ($aux, $bbl) = ("bstsample.aux", "bstsample.bbl"); ($cls) = (’article’); (@pkgs, @pre);
GetOptions("bib=s" => \$bib, "out=s" => \$out, "class=s" => \$cls, "packages=s" => \@pkgs, "preamble|P=s" => \@pre); open TEX, "> $out.tex"; print TEX \cite{...}, stil:x,y => \x{...}, \y{...} # stil: => was auch immer beim vorigen Stil war my @c; ($bst, @c) = $bst =~ /:/ ? split (/[:,]/, $bst) : ($bst, ’cite’); @ccmds = @c if @c; # Fälsche eine .aux-Datei für diesen Stil, rufe BibTeX auf open F, "> $aux" or die "open $aux: $!\n"; print F "\\bibstyle{$bst}\n"; print F "\\citation{*}\n"; print F "\\bibdata{$bib}\n"; close F; !system "bibtex", $aux or die "bibtex error\n"; # Lies das Ergebnis und hänge es an die Ausgabe an # (mit \cite-Kommandos und deren Ausgabe) open F, $bbl or die "open $bbl: $!\n"; $_ = ; close F; my @cites = (); push @cites, map { "\\${_}{$count.$2}" } @ccmds while s s; s/\\cite(t?)\{(.*?)\}/\\cite${1}{$count.$2}/gs; print TEX "\\section{$bst}\n"; print TEX "\\verb|$_|: $_\\\\\n" foreach @cites; print TEX $_; print TEX "\n"; $count++; } print TEX "\\end{document}\n"; Abbildung 5-11: Das Perl-Skript bstsample (Schluss)
Hack #51: Bibliografiestile testen
171
#51
HACK
#52
Literaturverzeichnisse mit Turbolader
setzt bstsample an den Anfang jedes Verweises eine laufende Nummer. Dies geht von der Annahme aus, dass die Namen von Einträgen in der Regel nicht mit einer Ziffer anfangen. Sollten Sie das anders sehen, dann hilft Ihnen möglicherweise eine Anpassung des regulären Ausdrucks im while-Teil von »push @cites, ...« – dieser Ausdruck prüft zur Sicherheit genau das. An diesem Skript ließe sich sicher noch einiges verbessern (beispielsweise könnte man die Ausgabe auf einige Einträge aus der bib-Datei beschränken). Aber so ist es auch schon recht nützlich, und die nächsten verregneten Winternachmittage kommen bestimmt. Wenn Sie gute Vorschläge haben, dann lassen Sie es uns wissen!
Siehe auch • Wir verraten Ihnen fast nichts darüber, welche Bibliografiestile es gibt oder wie Sie Ihren eigenen machen können. Einen Einstieg in ersteres gibt Ihnen BibTEXing von Oren Patashnik, das unter dem Namen btxdoc.pdf Bestandteil Ihrer TEX-Distribution sein sollte (ansonsten holen Sie es sich von CTAN). Auf CTAN finden Sie auch diverse Bibliografiestile, schauen Sie zum Beispiel nach in biblio/bibtex/contrib. • Die BibTEX-Programmiersprache ist dokumentiert in Oren Patashniks Designing BibTEX Styles, das ebenfalls mit BibTEX mitgeliefert wird. Sie ist nichts für zart besaitete Gemüter. • Einen etwas leichteren Einstieg in die Erstellung von Bibliografiestilen bietet custom-bib von Patrick Daly. Hierbei handelt es sich um ein TEX-Dokument, das über interaktive Menüs einen angepassten Bibliografiestil aus einer von zahlreichen Vorlagen erzeugt. Mit etwas Glück müssen Sie sich also gar nicht mit BibTEX-Programmierung beschäftigen. HACK
#52
Literaturverzeichnisse mit Turbolader Wie Sie aus Ihrer Literaturliste auf die Zitatstellen zurückverweisen
Ein cooler Effekt und bei »normalen« Publikationen mit riesigem Aufwand verbunden, darum selten gesehen, ist eine Rückverweisliste im Literaturverzeichnis, die angibt, wo im Buch die betreffenden Quellen zitiert wurden. Mit LATEX ist das ganz einfach, denn es gibt ja das Paket backref von Heiko Oberdiek, das diesen Vorgang automatisiert. backref ist Teil des hyperref-Bündels von Paketen [Hack #82], kommt aber auch ohne hyperref aus. Mit hyperref erzeugt es sogar anklickbare Verweise auf die Stellen, von denen aus die Quellen zitiert werden.
172
Kapitel 5: Gliederung und Verzeichnisse
HACK
Literaturverzeichnisse mit Turbolader
Literaturverzeichnis [LR89] Don Libes and Sandy Ressler. Life with UNIX: A Guide for Everyone. Prentice-Hall, April 1989. Seiten 5, 7 [Ste94] W. Richard Stevens. TCP/IP Illustrated, Volume 1: The Protocols. Addison-Wesley Professional Computing Series. Addison-Wesley, Boston etc., 1994. Seiten 5, 6, 8
Abbildung 5-12: Ein Literaturverzeichnis mit Rückverweisen
In einem deutschsprachigen Dokument genügt eine einfache Deklaration wie \usepackage[ngerman]{backref}
für eine Ausgabe wie in Abbildung 5-12. Normalerweise wird auf Seiten zurückverwiesen; mit \usepackage[ngerman,ref]{backref}
verweist backref nur auf die Abschnitte, in denen die Verweise vorkommen. Die Verweise werden mit dem Kommando \backref erzeugt, das die Verweis-
Literaturverzeichnis [AKW88] Alfred V. Aho, Brian W. Kernighan, and Peter J. Weinberger. The AWK Programming Language. Addison-Wesley, Reading, MA, 1988. Nicht direkt zitiert.
[LR89]
Don Libes and Sandy Ressler. Life with UNIX: A Guide for Everyone. Prentice-Hall, April 1989. Einmal zitiert, im Abschnitt 1.1.
[Ste94]
W. Richard Stevens. TCP/IP Illustrated, Volume 1: The Protocols. Addison-Wesley Professional Computing Series. Addison-Wesley, Boston etc., 1994. 3 Zitate in den Abschnitten 1.1, 1.2.1 und 2.1.2.
Abbildung 5-13: Anders formatierte Rückverweise
Hack #52: Literaturverzeichnisse mit Turbolader
173
#52
HACK
#53
Literaturverweise im Text mit BIBTEX
liste als Argument übernimmt. Über das Kommando \backrefpagesname können Sie steuern, wie die Verweisliste eingeleitet wird: \renewcommand{\backrefpagesname}{Zitiert auf S.}
Sie müssen allerdings dafür sorgen, dass das Kommando erst nach dem »\begin{document}« ausgeführt wird – stellen Sie es dahinter oder benutzen Sie \AtBeginDocument. Außer \backref gibt es in neueren Versionen von backref noch einen weiteren Mechanismus zur Erzeugung der Verweisliste: Das Kommando \backrefalt bekommt vier Parameter übergeben, namentlich die Anzahl der Verweise ohne Duplikate (also Verweise auf dieselbe Seite oder in denselben Abschnitt), die Verweisliste ohne Duplikate, die Verweisanzahl mit Duplikaten und die Verweisliste mit Duplikaten. Sie können \backrefalt so definieren, dass der Text von der Anzahl der Verweise abhängt, etwa wie folgt: \usepackage[ngerman,ref]{backref} \renewcommand*{\backref}[1]{} \renewcommand*{\backrefalt}[4]{% {footnotesize \ifcase #1 Nicht direkt zitiert.% \or Einmal zitiert, im Abschnitt #2.% \else #1 Zitate in den Abschnitten #2.% \fi}}
Ein Beispiel für die Ausgabe sehen Sie in Abbildung 5-13. Wenn Sie hyperref verwenden und eine der Optionen backref, backref=section, backref=slide, backref=page oder pagebackref angeben, wird backref automatisch mit den passenden Optionen eingebunden. hyperref sorgt für anklickbare Verweise.
HACK
#53
Literaturverweise im Text mit BIBTEX Streuen Sie Quellenangaben in den Text Ihres Dokuments ein und lassen Sie BIBTEX die Arbeit machen.
Während es in manchen wissenschaftlichen Veröffentlichungen üblich ist, alle Quellenangaben am Ende des Dokuments zu bündeln und im eigentlichen Text nur Verweise auf dieses Literaturverzeichnis zu platzieren, ist es anderswo Usus, die kompletten Quellenangaben in den Text einzustreuen oder in Fußnoten unterzubringen. Auf den ersten Blick läuft das der Idee zuwider, BibTEX zur Verwaltung und Formatierung der Quellenangaben zu verwenden, da BibTEX bekanntlich nur die thebibliography-Umgebung erzeugt, die Sie sonst manuell anlegen müssten – und es liegt in der Natur der Sache, dass diese sich immer nur an einem einzigen Platz im Dokument befinden kann! 174
Kapitel 5: Gliederung und Verzeichnisse
HACK
Literaturverweise im Text mit BIBTEX
bibentry Das bibentry-Paket von Patrick Daly finden Sie in der Distribution des natbibPakets desselben Autors. Es ist genau dafür gemacht, das zu ermöglichen, was eigentlich nicht geht – die Verwaltung von Quellenangaben im Text mit BibTEX. Und dazu benutzt es den folgenden Trick: Mit einem speziellen Kommando (\nobibliography) wird am Anfang des Dokuments die bbl-Datei eingelesen und die einzelnen Einträge gespeichert. Später im Dokument können Sie analog zum Kommando »\cite{blafasel}« mit »\bibentry{blafasel}« den kompletten Eintrag für die betreffende Quelle im Text platzieren. Aus \nobibliography{articles} ... Siehe hierzu auch \bibentry{thompson-ritchie:unix-acm}.
wird also Siehe hierzu auch Ritchie, Dennis M. und Ken Thompson: »The Unix Timesharing System«, Comm. ACM 17(7):365-73, Juli 1974. (eine geeignete bst-Datei mal vorausgesetzt). Sie können in einem Dokument, das bibentry verwendet, auch normale \citeKommandos benutzen und sogar parallel eine Literaturliste am Ende ausgeben. Allerdings müssen Sie dann statt \nobibliography das Kommando \nobibliography* einsetzen: \nobibliography*{articles}
Diese Version vermeidet LATEX-Fehlermeldungen über doppelt definierte Bibliografieeinträge und Ähnliches. Ein Problem dieses Ansatzes ist allerdings, dass beide Literaturlisten – die über den Text verstreute und die am Schluss – sich dieselbe bst-Datei teilen, so dass jede Quelle, die im Text zitiert wird, auch in der Literaturliste am Schluss auftaucht, obwohl das mitunter gar nicht erwünscht ist. Da es aber normalerweise nur eine bbl-Datei gibt, führt daran kein Weg vorbei, der nicht mit sehr tiefen Eingriffen in LATEX verbunden wäre.
Quellenangaben in Fußnoten Oftmals ist es üblich, Quellenangaben zu einem Dokument in Fußnoten unterzubringen. Mit bibentry ist das kein Problem – schreiben Sie einfach Folgendes: Wie schon anderswo beschrieben% \footnote{\bibentry{thompson-ritchie:unix-acm}} ...
Hack #53: Literaturverweise im Text mit BIBTEX
175
#53
HACK
#53
Literaturverweise im Text mit BIBTEX Wie schon anderswo1 beschrieben, ist Unix ein Betriebssystem mit einer Tradition, die bis in die 1960er Jahre zurückgeht.
1 Ritchie, D. M. und K. Thompson: »The Unix Time-sharing System«. Comm. ACM, 16(7):365–73, Juli 1974.
Abbildung 5-14: Quellenangabe in einer Fußnote, mit bibentry
Das führt zu dem in Abbildung 5-14 dargestellten Ergebnis. Wenn Sie das öfter machen wollen, hilft Ihnen vielleicht folgende Definition: \newcommand*\bibfootnote[2][]{% \footnote{#2% \def\@tempa{#1}% \ifx\@tempa\@empty\else, #1\fi.}}
Sie müssen dann nur noch folgende Kommandos schreiben: \bibfootnote{thompson-ritchie:unix-acm} \bibfootnote[S.~370]{thompson-ritchie:unix-acm}
Aus Gründen der Bequemlichkeit und Übersichtlichkeit ersetzen viele Veröffentlichungen bei zwei aufeinanderfolgenden Zitaten derselben Quelle die zweite Quellenangabe durch etwas wie »Ebenda«. Auch das können Sie LATEX natürlich beibringen: \newcommand*\bibebdname{Ebenda} \newcommand*\bibfootnote[2][]{% \def\@tempa{#2}% \ifx\@tempa\bib@prev \def\@tempa{\bibebdname}% \else\def\@tempa{\bibentry{#2}}\fi \gdef\bib@prev{#2}% \footnote{\@tempa% \def\@tempa{#1}% \ifx\@tempa\@empty\else, #1\fi.}} \newcommand*\bib@prev{}
In den letzten drei Zeilen von \bibfootnote sollten Sie unsere ursprüngliche Definition wiedererkennen. Der Rest des Codes befasst sich damit, den BibTEXSchlüssel der Quelle mit dem der vorigen Quelle zu vergleichen und den korrekten Text für die Fußnote zu finden: ein »Ebenda« (aus \bibebdname, also leicht umdefinierbar) oder das komplette Zitat via \bibentry.
176
Kapitel 5: Gliederung und Verzeichnisse
HACK
Literatur pro Kapitel
#!/bin/bash # chapterbibtex: Wende bibtex auf jede AUX-Datei an, die die # als Parameter übergebene Datei einliest main=‘basename $1 .tex‘.aux aux= for a in $(perl -ne ’print "$1\n" if /^\\\@input\{(.*)\.aux\}$/’ $main) do bibtex $a done Abbildung 5-15: chapterbibtex – rufe BibTEX für chapterbib auf
Siehe auch • Eine komplette Lösung des Problems »Bibliografie in Fußnoten« bietet das Paket opcit von Federico Garcia.
HACK
#54
Literatur pro Kapitel Teilen Sie Ihre Literaturliste kapitelweise auf.
Normalerweise erzeugt BibTEX eine Literaturliste für das gesamte Dokument. Manchmal – etwa in klugen Anthologien, wo jedes Kapitel von einer anderen Koryphäe der Disziplin beigesteuert wird – ist es aber wünschenswert, eine Literaturliste pro Kapitel (Abschnitt usw.) zu haben. Dazu verwenden Sie das Paket chapterbib von Donald Arseneau. Damit es seine Arbeit machen kann, braucht BibTEX eine aux-Datei mit den entsprechenden Verweisen, die sich aus den \cite-Kommandos im Dokument ergeben. Wenn Sie für verschiedene Teile Ihres Dokuments eigene von BibTEX angelegte Literaturlisten haben wollen, dann müssen diese Teile also ihre eigenen aux-Dateien haben. Ergo müssen diese Teile in eigene Dateien ausgelagert und mit \include ins Hauptdokument eingebaut werden. Daraus folgt, dass Sie mit chapterbib trotz des Namens gar nicht mal auf eine kapitelweise Aufteilung angewiesen sind, denn das Paket erlaubt eine Literaturliste für jede \include-Datei. Sie müssen in jede mit \include eingebundene Datei die beiden Kommandos \bibliographystyle und \bibliography einbauen, damit BibTEX weiß, was es
tun muss. Nach einem LATEX-Lauf wenden Sie dann BibTEX auf die einzelnen \include-Dateien (ohne die Endung tex) an (in Abbildung 5-15 finden Hack #54: Literatur pro Kapitel
177
#54
HACK
#54
Literatur pro Kapitel
Sie ein Shell-Skript, das diesen Vorgang automatisiert). Nach zwei weiteren LATEX-Läufen sollte eigentlich alles stimmen. Es kann sein, dass Ihr Bibliografiestil Kommandodefinitionen mit \newcommand in die bbl-Datei mit der fertigen Literaturliste schreibt. Solange Sie nur eine Literaturliste im Dokument haben (der Standardfall), ist das kein Problem – aber wenn es mehrere gibt, kollidieren die Definitionen. Sie können diesem Problem aber abhelfen, indem Sie statt \bibliography{xxx}
lieber {\bibliography{xxx}}
(mit zusätzlichen Klammern) schreiben. Normalerweise erscheint die Bibliografie als unnummeriertes Kapitel, was etwas ungeschickt ist, wenn es eine Bibliografie pro Kapitel geben soll. Mit \usepackage[sectionbib]{chapterbib}
können Sie dafür sorgen, dass die Bibliografie stattdessen zu einem unnummerierten Abschnitt gemacht wird. Natürlich können Sie auch direkt die thebibliography-Umgebung neu definieren – je nachdem, welche Änderungen Sie sonst noch vorhaben, ist das vielleicht sogar der gangbarere Weg. Mit \usepackage[gather]{chapterbib}
können Sie eine Bibliografie am Ende des Dokuments haben, die in Kapitel (oder was auch immer) unterteilt ist. Ansonsten bleibt alles beim Alten: Sie müssen nach wie vor BibTEX auf jede aux-Datei anwenden. Über die Einleitung jeder einzelnen Kapitel-Bibliografie entscheidet das Kommando \StartFinalBibs, das normalerweise folgendermaßen definiert ist: \newcommand{\StartFinalBibs}{% \renewcommand{\bibname}{Bibliography for Chapter \thechapter}}
Für ein deutschsprachiges Dokument wollen Sie das wahrscheinlich ändern.
Siehe auch • Eine flexiblere, aber auch kompliziertere Alternative zu chapterbib ist bibunits von Thorsten Hansen.
178
Kapitel 5: Gliederung und Verzeichnisse
HACK
Internationale Buchhandlung HACK
#55
Internationale Buchhandlung Nehmen Sie in Ihrer Literaturliste Rücksicht auf die Sprache der zitierten Werke.
BibTEX tut sich – wie viele Programme aus dem US-amerikanischen Kulturkreis – schwer mit dem Gedanken, Sprachen außer Englisch unterstützen zu müssen – die Standard-Bibliografiestile enthalten zum Beispiel jede Menge hart codierte Zeichenketten der Form editor oder PhD thesis, die für deutschsprachige Bücher und Doktorarbeiten nicht unbedingt passen. Sie könnten natürlich in den bst-Dateien, die die Bibliografiestile definieren, alle diese Zeichenketten übersetzen, aber das würde das Problem nur verlagern, nicht lösen. Offensichtlich ist ein Ansatz notwendig, der etwas umfassender gedacht ist. Eine mögliche Lösung des Problems ist das Paket babelbib von Harald Harders. Es setzt auf babel auf und erlaubt neben einer flexibleren Sprachbehandlung auch die Anpassung verschiedener typografischer Feinheiten, ohne dass dafür die dazugehörigen bst-Dateien geändert werden müssten. Die Voraussetzung ist allerdings, dass die Einträge in den bib-Dateien ein Feld namens language enthalten, das die Sprache des Dokuments in einer Form angibt, die auch von babel verwendet wird, etwa language = {english}
Sie müssen alle in der Literaturliste vorkommenden Sprachen mit babel laden, also zum Beispiel \usepackage[english,frenchb,spanish,german]{babel} Bei Deutsch ergibt sich ein Problem, weil das naheliegende language = {german}
die Tatsache verkennt, dass wir seit der Rechtschreibreform \usepackage[ngerman]{babel}
schreiben müssen, ergo auch in bib-Dateien ein language = {ngerman}
angebracht wäre. In jedem Fall sollte das, was in der bib-Datei steht, zu dem passen, was im \usepackage-Kommando für babel steht – schlimmstenfalls müssen Sie also \usepackage[english,german,ngerman]{babel}
schreiben. Zur Erinnerung: Sie dürfen für babel beliebig viele Sprachen angeben, aber die letzte in der Liste ist diejenige, die standardmäßig für das Dokument aktiv ist.
Außerdem sollten Sie es sich verkneifen, die Auflage etwa als
Hack #55: Internationale Buchhandlung
179
#55
HACK
#55
Internationale Buchhandlung
@Book{ts03:samba, author = {Jay Ts and Robert Eckstein and David Collier-Brown}, title = {Samba}, publisher = {O’Reilly Verlag GmbH \& Co. KG}, year = 2003, address = {Köln}, edition = 2, month = mar, language = {ngerman}, isbn = "3-89721-359-1", url = "http://www.oreilly.de/catalog/samba2ger/" } @Book{ts03:samba:en, author = {Jay Ts and Robert Eckstein and David Collier-Brown}, title = {Using Samba}, publisher = {O’Reilly \& Associates}, year = 2003, address = {Sebastopol, CA}, edition = 2, month = feb, language = {english}, isbn = "0-596-00256-4", url = "http://www.oreilly.com/catalog/samba2/" } Abbildung 5-16: Bibliografiedatenbank für babelbib
Literaturverzeichnis [TECB03a] Ts, Jay, Robert Eckstein und David Collier-Brown: Samba. O’Reilly Verlag GmbH & Co. KG, Köln, 2. Auflage, März 2003, ISBN 389721-359-1. http://www.oreilly.de/catalog/samba2ger/. [TECB03b] Ts, Jay, Robert Eckstein, and David Collier-Brown: Using Samba. O’Reilly & Associates, Sebastopol, CA, 2nd edition, February 2003, ISBN 0-596-00256-4. http://www.oreilly.com/catalog/ samba2/.
Abbildung 5-17: Ein »gemischtes« Literaturverzeichnis mit babelbib
180
Kapitel 5: Gliederung und Verzeichnisse
HACK
Internationale Buchhandlung
Literaturverzeichnis [TECB03a] Ts, Jay, Robert Eckstein und David Collier-Brown: Samba. O’Reilly Verlag GmbH & Co. KG, Köln, 2. Auflage, März 2003, ISBN 389721-359-1. http://www.oreilly.de/catalog/samba2ger/. [TECB03b] Ts, Jay, Robert Eckstein und David Collier-Brown: Using Samba. O’Reilly & Associates, Sebastopol, CA, 2. Auflage, Februar 2003, ISBN 0-596-00256-4. http://www.oreilly.com/catalog/ samba2/.
Abbildung 5-18: Einsprachiges Literaturverzeichnis mit babelbib
edition = {Zweite}
anzugeben. Schreiben Sie einfach edition = 2
und lassen Sie babelbib die Arbeit machen. (Abbildung 5-16 zeigt eine für babelbib angepasste bib-Datei.) Wenn Sie jetzt noch einen zu babelbib kompatiblen Bibliografiestil wählen – babelbib bringt unter anderem die Stile bababbrv, babalpha, babplain und babunsrt mit, die mit den jeweiligen Standard-Stilen korrespondieren –, bekommen Sie quasi von ganz alleine ein Literaturverzeichnis, wie es in Abbildung 5-17 zu sehen ist. Dort wird die Sprache im Literaturverzeichnis der Sprache des zitierten Werks angepasst. Zum Beispiel heißt es im Eintrag für das deutsche Buch »2. Auflage« und »März«, wo beim englischen Buch »2nd edition« und »February« steht.3 Auch die Verfasserliste folgt im deutschen Eintrag deutschen Konventionen (mit »und« und ohne Komma nach dem zweiten Autor) und im englischen Eintrag englischen Gepflogenheiten (mit »and« und Komma). Sie könnten jetzt den Standpunkt vertreten, dass in einem deutschsprachigen Buch alle Literaturangaben deutschen Gepflogenheiten entsprechen sollten. Ohne das hier debattieren zu wollen, weisen wir darauf hin, dass Sie nur \usepackage[fixlanguage]{babelbib} 3
Kenner des O’Reilly-Verlagsprogramms werden protestieren, dass die deutsche Ausgabe von Using Samba nicht im März, sondern im September 2003 erschienen ist. Das stimmt, aber dann würde man den Unterschied in den Monatsnamen nicht sehen.
Hack #55: Internationale Buchhandlung
181
#55
HACK
#55
Internationale Buchhandlung
schreiben müssen, um die Sprache der Literaturliste auf die Standardsprache festzulegen, die mit babel eingestellt wurde. Das Resultat von \usepackage[english,ngerman]{babel} \usepackage[fixlanguage]{babelbib}
sehen Sie in Abbildung 5-18. Sie können auch eine andere babel-Sprache wählen, indem Sie ein Kommando wie \selectbiblanguage{english}
hinzufügen. Hat ein Eintrag in der bib-Datei kein language-Feld, wird die Standardsprache des Dokuments verwendet, es sei denn, Sie definieren mit folgendem Kommando eine andere Sprache: \setbtxfallbacklanguage{frenchb}
Sollten Ihnen die Übersetzungen der Literaturbegriffe nicht zusagen, können Sie sie wie folgt anpassen: \declarebtxcommands{ngerman}{% \renewcommand*{\btxphdthesis}[1]{% \protect\foreignlanguage{ngerman}{Doktorarbeit}}% % statt "Dissertation"/"PhD thesis" }
Sie können im selben \declarebtxcommands mehrere Umdefinierungen vornehmen. Wenn Sie wissen wollen, was es alles gibt und was die Standardwerte sind, werfen Sie einen Blick in die Definitionsdatei: $ less ‘kpsewhich german.df‘
Wenn Sie die Beispiel-Literaturlisten ganz genau betrachten, sehen Sie, dass sie ISBNs (wenngleich alte) und URLs enthalten. Da Sie in bib-Dateien beliebige Felder aufnehmen dürfen, hindert Sie niemand daran, diese zusätzlichen Informationen mit Ihren Einträgen zu erfassen (außer der ISBN käme zum Beispiel noch die ISSN, das Äquivalent für Zeitschriften, in Frage), aber die Standard-Bibliografiestile von LATEX ignorieren diese Felder geflissentlich. babelbib dagegen gibt sie aus, solange Sie nicht mit \btxprintISBN{false}
oder \btxprintISSN{false}
ein Veto einlegen oder das babelbib-Paket von vornherein mit den Optionen noisbn oder noissn einlesen.
182
Kapitel 5: Gliederung und Verzeichnisse
KAPITEL SECHS
Dokumente Hacks #56–65
In diesem Kapitel zeigen wir Ihnen einige Strategien und Hacks zum Umgang mit ganzen Dokumenten. Zum Beispiel können Sie mit logischer Auszeichnung für konsistente Formatierung in großen Dokumenten sorgen oder ein Manuskript von Buchlänge in einzelne Kapitel zerlegen, die übersichtlicher zu verarbeiten sind. Ferner lernen Sie, wie Sie aus demselben Quellcode mehrere Versionen eines Dokuments erzeugen können oder die Seitenanzahl im Dokument für Zwecke der Seitennummerierung besorgen. Sie sehen, wie Sie mehrere unabhängige LATEX-Quelltextdateien zu einem großen Dokument kombinieren und Serienbriefe erzeugen können, und schließlich erfahren Sie noch, wie Sie LATEX und SQL-Datenbanken zusammenbringen, CD-Hüllen drucken und Visitenkarten oder Etiketten produzieren.
HACK
#56
Logische Auszeichnung Behalten Sie den Überblick in großen Dokumenten.
Eine der Stärken von LATEX ist das Konzept der »logischen Auszeichnung« – Sie schreiben hin, welche Funktion die Bestandteile Ihres Dokuments haben, und LATEX kümmert sich darum, sie passend zu formatieren. Sie können sich also ganz auf den Inhalt Ihres Dokuments konzentrieren und werden nicht dazu verleitet, an der Formatierung herumzubasteln. Vergleichende Studien haben gezeigt, dass diese Vorgehensweise effizienter ist als die Anwendung sogenannter WYSIWYG1 -Textverarbeitungsprogramme, die die Details der Formatierung direkt bei der Eingabe anzuzeigen versuchen. Logische Auszeichnung trennt die Bedeutung von Textteilen von ihrer Darstellung. Sie erlaubt Ihnen, Ihre Formatierungsentscheidungen später aufgrund der Bedeutung der formatierten Teile zu überdenken; Sie müssen nicht alle kursiv gedruckten Stellen 1
»What you see is what you get«
183
HACK
#56
Logische Auszeichnung
suchen und überlegen, ob es sich dabei um ein hervorgehobenes Stück Text oder eine fremdsprachliche Vokabel handelt, wenn Sie nur die Darstellung der fremdsprachlichen Vokabeln ändern wollen. Hier kommen WYSIWYG-Systeme an ihre Grenzen (Brian Kernighan, Unix-Entwickler der ersten Stunde und Computer-Schriftsatz-Guru, sagt dazu »What you see is all you’ve got«) – die Formatvorlagen gängiger Textverarbeitungsprogramme sind ein Eingeständnis dieser Feststellung, aber werden von vielen Benutzern als zu umständlich ignoriert und sind auch oft nicht zuverlässig implementiert (ein circulus vitiosus). LATEX bietet diverse Umgebungen und Kommandos für logische Auszeichnung an, aber in jedem halbwegs interessanten Dokument gibt es Elemente, die von diesen nicht erfasst werden. Im vorliegenden Buch reden wir zum Beispiel des öfteren über LATEX-Pakete, -Umgebungen und -Kommandos. Natürlich wäre es leicht, Dinge zu schreiben wie ... das \texttt{listings}-Paket ... ... die \texttt{document}-Umgebung ... ... das \verb|\emph|-Kommando ...
aber damit würden wir die Sünde der »optischen« Auszeichnung begehen – wir legen fest, dass diese Begriffe in Schreibmaschinenschrift erscheinen sollen, ohne zu sagen, was sie bedeuten. Es ist viel günstiger, statt dessen ... das \lpkg{listings}-Paket ... ... die \lenv{document}-Umgebung ... ... das \lcmd{emph}-Kommando ...
zu schreiben. So ist klar, worum es sich bei den Begriffen handelt, und wir können am Anfang des Dokuments einmal festlegen, wie sie dargestellt werden sollen, etwa mit \newcommand*{\lpkg}[1]{\texttt{#1}} \newcommand*{\lenv}[1]{\texttt{#1}} \newcommand*{\lcmd}[1]{\texttt{\textbackslash #1}}
(Beachten Sie, wie wir uns in der Definition von \lcmd um den lästigen Rückwärtsschrägstrich drücken.) Dass \lpkg und \lenv dieselbe Expansion haben, ist nicht weiter schlimm – unsere logische Auszeichnung stellt sicher, dass die beiden Kommandos im Manuskript (der LATEX-Eingabe) eine unterschiedliche Bedeutung transportieren, auch wenn das Aussehen im fertigen Dokument gleich ist. Wir müssen natürlich nicht hier stehen bleiben, sondern können auf der Basis einer guten logischen Auszeichnung auch noch andere nützliche Dinge tun. Beispielsweise könnten Sie daran denken, die erwähnten Paketnamen in den 184
Kapitel 6: Dokumente
HACK
Logische Auszeichnung
Index Ihres Dokuments aufzunehmen. Dies läßt sich automatisieren über etwas wie \newcommand*{\lpkg}[1]{\texttt{#1}\index{#1@\texttt{#1} (Paket)}}
Vielleicht möchten Sie auch nicht jede Erwähnung jedes Pakets in den Index aufnehmen. Sie könnten sich statt dessen wünschen, dass \lpkg{listings} den Paketnamen indizieren soll und \lpkg*{listings} nicht. LATEX hilft Ihnen hier über das \@ifstar-Kommando, das prüft, ob als nächstes Zeichen ein »*« folgt: \newcommand*{\lpkg}{\@ifstar\lpkg@star\lpkg@nostar} \newcommand*{\lpkg@star}[1]{\texttt{#1}} \newcommand*{\lpkg@nostar}[1]{\lpkg@star{#1}% \index{#1@\lpkg@star{#1} (Paket)}}
Ist das nächste Zeichen hinter dem \lpkg ein Stern, wird \lpkg@star ausgeführt, sonst \lpkg@nostar. Beachten Sie, dass das \lpkg-Kommando das Argument nicht anschaut, sondern es den beiden anderen Kommandos überläßt, sich darum zu kümmern. Ebenfalls bemerkenswert ist, dass \lpkg@nostar die tatsächliche Ausgabe des Kommandos im Text an \lpkg@star delegiert und nur den Indexeintrag besorgt. Auf diese Weise ist allein \lpkg@star für die Formatierung maßgeblich, so dass Änderungen nur an einer Stelle gemacht werden müssen. Karsten Günther schlägt vor, dass es einfacher wäre, einen optionalen Parameter zu verwenden. Das könnte ungefähr so aussehen: \lpkg{Paket} \lpkg[]{Paket} \lpkg[Index]{Paket}
Schreibt und indiziert Paket Schreibt Paket, indiziert nichts Schreibt Paket, indiziert Index
Dazu definieren Sie \lpkg wie folgt: \newcommand*{\lpkg@fmt}[1]{\texttt{#1}} \newcommand*{\lpkg@idx}[1]{% \index{#1@\lpkg@fmt{#1} (Paket)}} \newcommand*{\lpkg}[2][^^A]{% \lpkg@fmt{#2}% \ifthenelse{\equal{#1}{}}{% % Tue nichts }{\ifthenelse{\equal{#1}{^^A}}{% \lpkg@idx{#2}% }{\lpkg@idx{#1}}}}
(Wegen der »@« gehört die Definition in ein Paket oder zwischen \makeatletter. . . \makeatother, und vergessen Sie nicht das \usepackage{ifthen}.) Der eigenartige Standardwert »^^A« für das optionale Argument hilft dabei, den Fall »Kein optionales Argument« von dem Fall »Leeres optionales Argument« zu
Hack #56: Logische Auszeichnung
185
#56
HACK
#56
Logische Auszeichnung unterscheiden. \lpkg@fmt und \lpkg@idx wären nicht unbedingt nötig, ergeben sich aber aus dem DRY-Prinzip2 ; wir möchten nur an einer Stelle angeben müssen, wie Paketnamen formatiert und indiziert werden. – Sie müssen selbst entscheiden, was Sie lieber mögen; dieser Ansatz ist in mancher Hinsicht bequemer, aber »teurer« in der Bearbeitung durch LATEX.
Wenn Sie mehrere solche Kommandos definieren wollen (und darauf läuft es in der Regel hinaus), ist es mühselig, die Fallunterscheidung nach dem Stern wieder und wieder einzugeben. Definieren Sie sich statt dessen ein »Metakommando«, das die tatsächlichen Kommandos für Sie einrichtet: Etwas wie \markupcommand{bla}{\textsc}{Laberphrase}
stellt Ihnen bequem ein Kommando \bla*{Blubb} zur Verfügung, das sein Argument als »Blubb« ins Dokument überträgt. Dazu gibt es \bla{Blubb}, das außerdem einen Indexeintrag der Form Blubb (Laberphrase), 123 macht. Das \markupcommand-Kommando könnte ungefähr so aussehen: \newcommand*{\markupcommand}[3]{% \expandafter\edef\csname#1\endcsname{% \noexpand\@ifstar\@nameuse{#1@star}\@nameuse{#1@nostar}}% \@namedef{#1@star}##1{#2{##1}}% \@namedef{#1@nostar}##1{% \@nameuse{#1@star}{##1}\index{##1@#2{##1} (#3)}}}
Diesen dicken Brocken TEX-Code muss man in Ruhe genießen, damit man sich nicht daran verschluckt. Lesen Sie ihn am besten im Vergleich zu den manuell definierten Kommandos weiter oben, um die Parallelen würdigen zu können – das eigenartige Aussehen rührt nur daher, dass wir die manuellen Definitionen automatisieren müssen. Die Konstruktion \expandafter\edef\csname#1\endcsname{% \noexpand\@ifstar\@nameuse{#1@star}\@nameuse{#1@nostar}}%
entspricht dem \newcommand*{\lpkg}{\@ifstar...} oben. \@nameuse{bla} ist unter dem Strich dasselbe wie \bla, wir müssen TEX nur die Gelegenheit geben, die Ersetzung tatsächlich durchzuführen. Aus diesem Grund benutzen wir \edef, um das Kommando zu definieren – \edef führt genau wie sein Cousin \def ein neues TEX-Kommando ein, aber expandiert dabei den Kommandotext bis auf Sachen, vor denen ein \noexpand steht. Wenn #1 der Text 2
»Don’t Repeat Yourself«
186
Kapitel 6: Dokumente
HACK
Logische Auszeichnung
»bla« ist, dann wird der Kommandotext also so zusammengebaut, als stünde dort mit \@ifstar\bla@star\bla@nostar
genau das, was wir wollten. – Der \expandafter. . . \csname. . . \endcsname-Eiertanz dient hier dazu, das erste Argument (in #1) als Kommandonamen zu verwenden. Ein festes Kommando hätten wir natürlich wie oben mit \edef\bla{...}
definiert, aber da der Kommandoname sich erst später ergibt, müssen wir ihn als Zeichenkette lesen und mit \csname. . . \endcsname zu einem Kommando machen. Das \expandafter sorgt dafür, dass diese Umwandlung vorgenommen wird, bevor TEX das \edef zu sehen bekommt. Wie gesagt, große Magie. (Wenn Sie sich an \@namedef, das Analog zu \@nameuse, erinnern: Das können wir hier nicht verwenden, da \@namedef intern \def benutzt und nicht \edef. Ein \@nameedef bietet LATEX leider nicht an . . . ). Der Rest des Kommandos, das \@namedef{#1@star}##1{#2{##1}}% \@namedef{#1@nostar}##1{% \@nameuse{#1@star}{##1}\index{##1@#2{##1} (#3)}}
ist dagegen fast simpel. Sie müssen hier nur im Hinterkopf behalten, dass die #1, #2 und #3 durch die Parameter des Kommandos (in unserem Beispiel respektive »bla«, »\textsc« und »Laberphrase«) ersetzt werden, während ##1 einen Parameter des hier innerhalb der Definition eines anderen Kommandos definierten Kommandos darstellt (uff). Die erste Zeile ist also in unserem Beispiel äquivalent zu \def\bla@star#1{\textsc{#1}}
und das ist wiederum fast dasselbe wie \newcommand*{\bla@star}[1]{\textsc{#1}}
(Der wesentliche Unterschied zwischen den beiden – außer der Syntax – ist, dass \newcommand prüft, ob schon ein Kommando \bla@star definiert ist, während \def eine eventuell existierende Definition rücksichtslos überschreibt. \def ist ein primitives TEX-Kommando und \newcommand eine zivilisierte Erfindung von LATEX, die tief in ihrem Inneren auf \def zurückgreift, aber nach außen hin gesittetes Benehmen zeigt.) Die zweite Definition ist im Grunde wie die erste, nur umständlicher. Wenn Sie gut aufgepasst haben, ist Ihnen eine Inkonsistenz zwischen unserem \markupcommand und den ähnlichen LATEX-Kom-
Hack #56: Logische Auszeichnung
187
#56
HACK
#57
Teile und herrsche mandos wie \newcommand und \renewcommand aufgefallen: Letztere übernehmen den Kommandonamen als Kontrollsequenz, wie \newcommand{\bla}{...}
und unser Kommando als Zeichenkette \markupcommand{bla}{...}{...}
Das ist unschön und ließe sich umgehen, allerdings wäre die Definition von \markupcommand um einiges komplizierter. Für die grobe Richtung können Sie sich die Definition von \newif in der Datei latex.ltx (Bestandteil Ihrer LATEX-Distribution) anschauen. Essen Sie vorher nichts oder halten Sie einen Eimer bereit.
Logische Auszeichnung ist gerade in größeren Dokumenten (denken Sie an Diplomarbeiten, Dissertationen oder Bücher) eine immense Hilfe. Im Idealfall sind LATEX-Kommandos wie \texttt zwischen \begin{document} und \end{document} absolut tabu – sobald Sie sich dabei ertappen, so ein Kommando einzutippen, sollten Sie innehalten und überlegen, welche Funktion der Textbestandteil hat, den Sie gerade beinahe optisch ausgezeichnet hätten. Führen Sie statt des Schriftumschaltungskommandos lieber ein neues »logisches« Kommando ein, das Sie am besten gleich in der Präambel Ihres Dokuments vorläufig definieren. Später können Sie entscheiden, wie die endgültige Formatierung aussehen soll und ob Sie noch Index-Tricks wie hier gezeigt oder andere Extras einbauen möchten (was natürlich nicht Pflicht ist). Logische Auszeichnung bedeutet übrigens auch, dass Sie es einfacher haben, Ihre LATEX-Eingabedateien mit anderen Programmen zu bearbeiten. Um zum Beispiel herauszufinden, in welchen Kapiteln des vorliegenden Buchs das \texttt-Kommando erwähnt wird, reicht uns ein $ grep -l ’\lcmd{texttt}’ ch*.tex
Würden wir statt dessen überall \texttt zur optischen Auszeichnung verwenden, statt ein eigenes Kommando zur logischen Auszeichnung einzusetzen, würde eine Suchoperation wie $ grep -l ’\texttt’ ch*.tex
vor allem »falsche Positive« finden, wo das Kommando zur Formatierung benutzt wird, aber nicht selbst Teil des sichtbaren Textes ist.
HACK
#57
Teile und herrsche Wie Sie ein großes Dokument in übersichtliche Stücke zerlegen
Manuskripte von Buchlänge – neben »richtigen« Büchern zum Beispiel auch Examensarbeiten, gewichtige Gutachten und ähnliches – sind unbequem in ei188
Kapitel 6: Dokumente
HACK
Teile und herrsche
ner großen Eingabedatei zu bearbeiten. Zwar lassen sich heutige Texteditoren von Dateien mit Abertausenden von Zeilen nicht mehr durcheinander bringen, aber das Herumsuchen in solchen Monstertexten ist kaum vergnüglich. LATEX bietet deshalb einen Mechanismus an, mit dem Sie große Dokumente in mehrere Teile zerlegen können. Zum Beispiel könnten Sie jedes Kapitel Ihres Buchs oder Ihrer Diplomarbeit in einer eigenen Datei speichern. Die »Hauptdatei«, also die Datei, die Sie im LATEX-Aufruf benennen, enthält dann nur noch die Präambel und \include-Aufrufe für die einzelnen Kapiteldateien: \documentclass{book} \usepackage{...} ... \begin{document} \title{Wie ich meinen ersten Nobelpreis gewann} \author{A. N. Geber} ... \chapter*{Vorwort} ... \include{kapitel1} \include{kapitel2} ... \end{document}
Es bietet sich an, das Dokument auf Kapitelebene aufzuteilen, weil LATEX verlangt, dass der Inhalt einer mit \include eingebundenen Datei immer auf einer neuen Seite anfängt. Zumindest in den Standard-Dokumentklassen ist das für LATEX-Kapitel garantiert. Wenn Ihre Dokumentklasse es nicht vorschreibt, können Sie \include nicht verwenden, sondern müssen auf das \input-Kommando zurückgreifen, das diese Einschränkung nicht hat. Warum also überhaupt \include verwenden und nicht das flexiblere \input? Ein Grund ist, dass \include Ihnen das selektive Verarbeiten einzelner Dateien gestattet. Wenn Sie in die Präambel Ihres Dokuments etwas aufnehmen wie \includeonly{kapitel3,kapitel5}
dann bearbeitet LATEX nur noch diese beiden Dateien (alle anderen \includeKommandos werden ignoriert). Der Pfiff dabei ist, dass alle im Dokument definierten Marken bei der Verarbeitung der \includeonly-Dateien zur Verfügung stehen. Querverweise aus den einzeln bearbeiteten Kapiteln in andere, die gerade nicht mit durchgenudelt werden, werden also einigermaßen korrekt eingesetzt. Heutige Rechner sind so schnell, dass LATEX auch Bücher mit Hunderten von Seiten formatieren kann, noch bevor Sie Ihre Kaffeetasse neu gefüllt haben, aber nützlich ist diese Infrastruktur doch immer mal wieder.
Hack #57: Teile und herrsche
189
#57
HACK
#57
Teile und herrsche
Sie sind nicht gezwungen, die Liste der zu bearbeitenden Kapitel hart in Ihrem Dokument zu kodieren – wenn Sie zum Beispiel Quellcodekontrolle verwenden [Hack #100], dann bringen ständige Änderungen an Ihrer Hauptdatei nur Verwirrung ins Änderungsprotokoll. Sie können LATEX zum Beispiel dazu bringen, Sie bei jedem Lauf nach einer Liste der zu LATEXenden Dateien zu fragen: Schreiben Sie in die Präambel Ihres Dokuments etwas wie \typein[\incfiles]{Zu bearbeitende Kapitel:} \includeonly{\incfiles}
Ein Programmlauf sieht dann ungefähr so aus: $ latex mybook This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) entering extended mode (./mybook.tex LaTeX2e Babel and hyphenation patterns for ... loaded. (/usr/share/texmf-tetex/tex/latex/base/book.cls Document Class: book 2004/02/16 v1.4f Standard LaTeX document class (/usr/share/texmf-tetex/tex/latex/base/bk10.clo)) (/usr/share/texmf-tetex/tex/latex/base/inputenc.sty (/usr/share/texmf-tetex/tex/latex/base/latin1.def)) Zu bearbeitende Kapitel: \incfiles=kapitel2 (./mybook.aux (./kapitel1.aux) (./kapitel2.aux) (./kapitel3.aux)) (./kapitel.tex [2] Chapter 2. ) [3] (./mybook.aux (./kapitel1.aux) (./kapitel2.aux) (./kapitel3.aux))) Output written on mybook.dvi (2 pages, 444 bytes). Transcript written on mybook.log.
Natürlich könnten Sie es als lästig empfinden, bei jedem Programmlauf manuell die Kapitelliste eingeben zu müssen. Sie können sich diese Arbeit sparen, indem Sie die Kapitelliste direkt in den LATEX-Aufruf hineinschreiben, ohne sich mit \typein fragen zu lassen: $ latex ’\def\incfiles{kapitel2,kapitel3}\input{mybook}’
Diese Technik funktioniert allgemein, wenn Sie LATEX von außen Definitionen mit auf den Weg geben wollen.
190
Kapitel 6: Dokumente
HACK
Nach dem Ausschlussprinzip
Siehe auch • Das askinclude-Paket von Pablo A. Straub vereinfacht den Umgang mit \include und \includeonly: Das Paket fragt Sie interaktiv, welche \includeDateien eingelesen werden sollen. Sie können dann entweder einige Dateien namentlich aufzählen, einfach nur »Return« drücken (dann werden die Dateien gelesen, die auch im vorigen Lauf gelesen wurden) oder »*« oder »-« eingeben, um »alle« oder »keine« Dateien einzulesen. Das ist nett für den interaktiven Einsatz, aber natürlich nicht für Makefiles und ähnliches zu gebrauchen, wo der Ansatz mit der Definition auf der Kommandozeile mehr hilft.
HACK
#58
Nach dem Ausschlussprinzip Erstellen Sie mehrere Versionen eines Dokuments aus demselben LATEX-Quellcode.
Manche Dokumente existieren in verschiedenen Versionen: Eine Schulungsunterlage könnte es zum Beispiel als »Teilnehmerhandbuch« geben, das an die Kursteilnehmer ausgeteilt wird, und als »Trainerhandbuch« mit zusätzlichen Hinweisen und Anmerkungen, Lösungen für die Übungen und so weiter. Dabei ist es natürlich unpraktisch, den Teilnehmer-Anteil des Materials für das Teilnehmerhandbuch und für das Trainerhandbuch separat und parallel zu warten – es ist viel besser, eine einzige Eingabedatei zu haben und das zusätzliche Material nach Bedarf selektiv ein- und auszublenden: ... sehen Sie unmittelbar das Ergebnis. \begin{trainer} (Hierfür ist es dringend nötig, dass die vorigen drei Aufgaben korrekt gelöst wurden, da sonst gar nichts funktioniert. Geben Sie notfalls die richtige Lösung an.) \end{trainer} Wenn Sie dagegen ...
Text aus- und einblenden Das grundlegende Handwerkszeug dafür haben Sie in Aufgaben und Lösungen [Hack #14] gesehen, wo wir Ihnen das verbatim-Paket vorgestellt haben. Dieses Paket erlaubt es Ihnen, Umgebungen zu schreiben, die Material aus der Eingabe Zeile für Zeile lesen und dann mit den Zeilen interessante Dinge tun, sie zum Beispiel so in Schreibmaschinenschrift ausgeben, wie sie in der Eingabe stehen (der Standardfall für verbatim), oder in eine Datei zu schreiben und später wieder einzulesen (was wir mit unseren Musterlösungen gemacht haben). Natürlich ist es auch einfach, die Zeilen komplett wegzuwerfen:
Hack #58: Nach dem Ausschlussprinzip
191
#58
HACK
#58
Nach dem Ausschlussprinzip
\newcommand*{\trainer}{\@bsphack \let\do\@makeother\dospecials \catcode‘\^^M\active \let\verbatim@startline\relax \let\verbatim@addtoline\@gobble \let\verbatim@processline\relax \let\verbatim@finish\relax \verbatim@start} \let\endtrainer\@esphack
Hier werden einfach alle Operationen, die sich sonst um das Setzen von Verbatim-Text kümmern, neutralisiert, indem sie auf \relax gesetzt werden (das Kommando, das nichts tut). \verbatim@addtoline liest sonst ein Zeichen oder eine Kontrollsequenz aus der Eingabe und fügt sie der aktuellen Zeile hinzu; das \@gobble-Kommando, zu dem wir \verbatim@addtoline hier äquivalent machen, liest dasselbe, aber wirft es gleich weg. (Dieser Code findet sich im verbatim-Paket als Definition der comment-Umgebung). Der verbatim-Code sorgt dafür, dass Sie das Trainer-Material auslassen können. Aber wie schaffen Sie es, es in Ihr Dokument einzubinden, ohne jedes Auftreten der trainer-Umgebung zu suchen? Dazu müssen Sie natürlich nur die Definition der trainer-Umgebung ändern. Mit \newenvironment{trainer}{}{}
definieren Sie eine trainer-Umgebung. die nichts tut. Das Einzige, was übrig bleibt, ist eine bequeme Möglichkeit, zwischen den beiden Versionen umzuschalten (Aus- und Einkommentieren von TEX-Code in der Präambel mit Prozentzeichen ist nicht bequem.) Der einfache Ansatz könnte darin bestehen, etwas zu machen wie \newcommand*{\trainer}{...} \let\endtrainer\@esphack \newcommand*{\includetrainer}{% \renewenvironment{trainer}{}{}}
Das heißt, Sie schreiben das \renewenvironment nicht direkt ins Dokument, sondern führen es nur aus, wenn das \includetrainer-Kommando gegeben wurde. Ohne \includetrainer wird das Teilnehmerhandbuch erzeugt, mit das Trainerhandbuch. Wie in Teile und herrsche [Hack #57] beschrieben können Sie das Kommando \includetrainer natürlich auch auf der LATEX-Kommandozeile geben. Ein simples
192
Kapitel 6: Dokumente
HACK
Nach dem Ausschlussprinzip
$ latex ’\includetrainer\input{unterlage}’
schlägt zwar fehl – das \includetrainer-Kommando ist noch nicht definiert, da LATEX noch nicht einmal angefangen hat, Ihr Dokument zu lesen –, aber Sie können das Kommando auf »beim \begin{document}« vertagen: $ latex ’\AtBeginDocument{\includetrainer}\input{unterlage}’
Wenn Sie die Definition von \includetrainer dann in der Präambel oder in einem mit \usepackage einzubindenden LATEX-Paket unterbringen, ist sie mit Sicherheit bekannt, wenn das Kommando aufgerufen wird.
Windschnittiger mit make Zur weiteren Verfeinerung hilft make. Verwenden Sie ein Makefile wie teilnehmer: latex unterlage trainer: latex ’\AtBeginDocument{\includetrainer}\input{unterlage}’
und sagen Sie einfach »make teilnehmer« oder »make trainer«. Denken Sie gegebenenfalls daran, dass Sie mehrere Läufe brauchen, wenn Sie zwischen Trainer- und Teilnehmerhandbuch wechseln, damit alle Querverweise aktuell sind. Wenn Sie noch tippfauler sind, setzen Sie an den Anfang Ihres Makefiles etwas wie all: trainer
oder all: teilnehmer
(je nachdem), dann reicht ein simples »make«, um Ihre bevorzugte Version zu erzeugen. Noch ein Trick, der jedenfalls mit der TEXLive-Version von TEX funktioniert: Die Kommandozeilenoption »-output-directory« erlaubt es, ein Verzeichnis zu benennen, in das TEX alle seine Ausgabedateien schreibt (und das es auch als erstes wieder nach aux-Dateien und Ähnlichem durchsucht). Mit teilnehmer: latex -output-directory teilnehmer unterlage trainer: latex -output-directory trainer \ ’\AtBeginDocument{\includetrainer}\input{unterlage}’
Hack #58: Nach dem Ausschlussprinzip
193
#58
HACK
#58
Nach dem Ausschlussprinzip können Sie die beiden Versionen völlig trennen, was Dinge wie dvi- und aux-Dateien angeht. Das hilft, Verwirrung zu vermeiden und überflüssige LATEX-Läufe zu sparen.
Mehr als zwei Versionen Wenn Sie mehr als zwei Versionen Ihres Dokuments unterscheiden müssen, dann hält Sie niemand davon ab, mehrere Versionen der trainer-Umgebung parat zu halten. Verwenden Sie zur Vereinfachung eine »allgemeine« Definition wie \newcommand*{\ignoreenv}{\@bsphack ... \verbatim@start} \let\endignoreenv\@esphack \let\versionA\ignoreenv \let\endversionA\endignoreenv \newcommand*{\includeversionA}{\renewenvironment{versionA}{}{}} \let\versionB\ignoreenv \let\endversionB\endignoreenv \newcommand*{\includeversionB}{\renewenvironment{versionB}{}{}}
damit Sie in Ihrem Dokument \includeversionA %\includeversionB ... \begin{document} ... \begin{versionA} Text für Version \end{versionA} ... \begin{versionB} Text für Version \end{versionB} ... \end{document}
% versionA ist dabei % versionB ist nicht dabei
A
B
schreiben können. Natürlich können Sie die Definition der versionX-Umgebungen auch noch vereinfachen (für den Benutzer, nicht den LATEXniker): \newcommand{\newversion}[1]{% \expandafter\let\csname #1\endcsname\ignoreenv \expandafter\let\csname end#1\endcsname\endignoreenv
194
Kapitel 6: Dokumente
HACK
Nach dem Ausschlussprinzip
\@namedef{include#1}{\renewenvironment{#1}{}{}}}
erlaubt ein einfaches \newversion{versionA}
zur Definition der versionA-Umgebung und des \includeversionA-Kommandos. Um eine Überflutung an \includeversionX-Kommandos zu verhindern, würde sich eine Syntax wie \includeversion{versionA,versionB}
anbieten. Dazu müssen wir Ihnen noch zeigen, wie Sie eine durch Kommas getrennte Liste von Argumenten abarbeiten, nämlich so: \newcommand*{\includeversion}[1]{% \@for\@tempa:=#1\do{\renewenvironment{\@tempa}{}{}}}
(die \@namedef-Zeile in \newversion können Sie dann entfernen). Das Argument von \includeversion ist eine Liste (mit Kommas) von Versionsnamen. Das \@for-Kommando durchläuft diese Liste und ruft die hinter \do angegebenen Kommandos für jedes Listenelement auf, wobei es der temporären Variablen \@tempa vorher das Listenelement zuweist. Ein \includeversion{versionA,versionB}
führt also zum selben Ergebnis wie \renewenvironment{versionA}{}{} \renewenvironment{versionB}{}{}
Eine Fußangel existiert bei dieser bequemen Lösung: Etwas wie \includeversion{document,itemize}
bringt LATEX relativ kapital durcheinander. Im Interesse defensiver Programmierung sollten wir also prüfen, ob die betreffende Umgebung tatsächlich vorher mit \newversion definiert wurde: \newcommand{\includeversion}[1]{% \@for\@tempa:=#1\do{% \expandafter\ifx\csname\@tempa\endcsname\ignoreenv \renewenvironment{\@tempa}{}{} \else\PackageWarning{vrsn}{‘\@tempa’ is not a version name}% \fi}}
Die Zeile \expandafter\ifx\csname\@tempa\endcsname\ignoreenv
Hack #58: Nach dem Ausschlussprinzip
195
#58
HACK
#58
Nach dem Ausschlussprinzip
prüft, ob der Inhalt von \@tempa, als Kontrollsequenz interpretiert (und damit entsprechend einem \begin{...}) dieselbe Expansion hat wie das Kommando \ignoreenv. Wenn \@tempa tatsächlich eine vorher definierte Version beschreibt, dann sind diese Kontrollsequenz und \ignoreenv bei der Ausführung des Kommandos \newversion mit \let äquivalent gemacht worden, so dass der Vergleich »wahr« ergibt. Für andere Umgebungsnamen trifft die Äquivalenz nicht zu, und wir geben eine Warnung aus: Package vrsn Warning: ‘verse’ is not a version name on input line 9.
(den Paketnamen »vrsn« postulieren wir hier einfach mal).
Das versions-Paket Auch hier gilt wieder, dass dieses Problem so gängig ist, dass LATEX dafür vorgekochte Lösungen parat hat. Auf CTAN finden Sie das Paket versions von Uwe Lück, das in etwa das tut, was wir hier beschrieben haben, und noch ein paar Sachen mehr. Zum Beispiel kann es in der Ausgabe markieren, wo bestimmte Versionen anfangen und aufhören (zum Korrekturlesen) und hat eine Ausweichmethode für den Fall, dass versionsabhängiger Text im Argument eines anderen Kommandos stehen soll, etwa in einer Fußnote: ... \footnote{Genau. \begin{versionA} (Diese Fußnote ist überflüssig) \end{versionA}} ...
Unsere Lösung muss da kapitulieren (wobei die fehlende Funktionalität leicht nachzurüsten wäre), während versions dies über die Konstruktion ... \footnote{Genau. \processifversion{versionA}(Diese Fußnote ist überflüssig)} ...
erlaubt. versions kennt kein \newversion-Kommando, sondern verwendet zur Voranmeldung von Versionen die Kommandos \includeversion, \excludeversion und \markversion, jeweils mit der offensichtlichen Bedeutung.
Siehe auch • Weitere Pakete in dieser ökologischen Nische sind version von Stephen Bellantoni und Donald Arseneau, optional von Donald Arseneau oder comment von Victor Eijkhout.
196
Kapitel 6: Dokumente
HACK
Seite 5 von 9 HACK
#59
Seite 5 von 9 Wie Sie sich die letzte benutzte Seitennummer in Ihrem Dokument besorgen
Welche Seitennummer hat die letzte Seite Ihres Dokuments? Das ist nicht nur interessant bei Faxnachrichten, sondern überall dort, wo Sie Seitennummern in der Form »Seite i von n« angeben wollen. Hier erklären wir Ihnen, wie Sie diese Information erhalten können. Wenn Sie genauer über dieses Problem nachdenken, merken Sie schnell, dass die Sache nicht so einfach ist, wie sie scheint. Zum einen ist es nicht unbedingt damit getan, Ihr Dokument einfach mit einem \label{LastPage} \end{document}
zu beschließen, damit Sie mit \pageref{LastPage} die gewünschte Seitennummer erhalten. Immerhin könnte es sein, dass das \end{document} noch zurückgehaltene gleitende Bilder und Tabellen im Werte von fünf Seiten ausspuckt, die dann in Ihrer Zählung nicht vorkommen. Zum anderen ist die Seitennummer der letzten Seite nicht notwendigerweise die Gesamtanzahl der Seiten im Dokument; es könnte zum Beispiel sein, dass Sie irgendwo die Seitennummerierung mit \pagenumbering zurückgesetzt haben oder es ein Titelblatt gibt, das keine Seitennummer trägt, aber trotzdem ein Blatt Papier in der Ausgabe einnimmt. Das erste Problem können Sie lösen, indem Sie vor das \label ein \clearpage schalten, um allfällige übrige Gleitobjekte aus dem Speicher zu zwingen. Sie müssen nur einkalkulieren, dass Sie dann (theoretisch) am Anfang einer neuen leeren Seite stehen, die es in Ihrem Dokument ansonsten nicht gibt – die Seitennummer ist um eine Seite zu hoch. Sie können auf dieser Seite eine mit \label eine Marke setzen; solange Sie nicht wirklich Ausgabe produzieren, bleibt die Seite leer und wird auch nicht tatsächlich in die Ausgabe geschrieben: \newcommand*{\mark@lastpage}{% \clearpage \addtocounter{page}{-1}% \label{LastPage}% \addtocounter{page}{1}}
Sie können außerdem dafür sorgen, dass die Marke automatisch am Dokumentende gesetzt wird, indem Sie sie mit \AtEndDocument registrieren. LATEX kümmert sich darum, dass alle solchen Kommandos im richtigen Moment ausgeführt werden:
Hack #59: Seite 5 von 9
197
#59
HACK
#60
Die Zutatenliste
\AtEndDocument{\mark@lastpage}
Das lastpage-Paket von Jeff Goldberg tut im wesentlichen dasselbe, was wir hier erklärt haben. Wenn Sie wirklich die Gesamtanzahl der Seiten im Dokument wissen wollen, müssen Sie zählen, wie oft LATEX eine Seite in die Ausgabe schreibt. Ohne hier zu weit ausholen zu wollen, ist auch das möglich: LATEX erzeugt Ausgabeseiten über ein Kommando namens \shipout, und ein Paket namens \everyshi (von Martin Schröder) erlaubt es, jedesmal, wenn LATEX das \shipout-Kommando aufruft, eigenen Code auszuführen. Ebenfalls von Martin Schröder kommt das Paket count1to, das »interessante« Zahlen wie die aktuelle Kapitelnummer, Abschnittsnummer und so weiter in die ersten 10 Zahlenregister von TEX schreibt. Der Sinn dahinter ist, dass zumindest bei DVI-Ausgabe TEX diese Zahlenregister am Anfang jeder Seite in die Ausgabe kopiert, es ist dann also einfach, mit einem geeigneten DVI-lesenden Programm alle Seiten zu extrahieren, die zum n-ten Kapitel gehören. (Mit PDF geht das leider nicht.) Das erklären wir genauer in Seiten nach Wahl [Hack #91].
Einer der Werte, den count1to erfasst und in ein Zahlenregister schreibt, ist die »absolute«, also über alle \shipouts gezählte Seitennummer. Netterweise definiert count1to auch gleich ein \label namens TotalPages, das die Gesamtanzahl der Seiten angibt. Allerdings müssen Sie darauf mit \ref{TotalPages} zugreifen. Schreiben Sie auf Ihr Fax-Deckblatt also etwas wie Seitenanzahl: \ref{TotalPages} (inklusive Deckblatt)
und verwenden Sie für die Kopf- oder Fußzeilen der tatsächlichen Faxnachricht Seite \thepage\ von \pageref{lastpage}
Grundsätzlich spricht nichts dagegen, die relevanten Funktionen von lastpage und count1to zu einem Paket zusammenzufassen (Abbildung 6-1). Mit diesem ltpage-Paket erhalten Sie mit dem Kommando \pageref{LastPage} die Seitennummer der letzten Seite und die Gesamtzahl der Seiten im Dokument mit \ref{LastPage}. Dafür sind natürlich mindestens zwei LATEX-Läufe nötig. HACK
#60
Die Zutatenliste Welche Dateien sind an Ihrem LATEX-Dokument beteiligt?
Bei Problemen mit LATEX kommt man hin und wieder an einen Punkt, wo man die Hilfe von Experten in Anspruch nehmen möchte. TEX ist zugegebe-
198
Kapitel 6: Dokumente
HACK
Die Zutatenliste
% This package is a blatant rip-off of ideas from lastpage.sty % and count1to.sty. \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{ltpage}[2007/01/18 Last page number and total pages (AL)] \RequirePackage{everyshi}[1994/12/09] \newcommand*{\ltpage@shipout}{% \global\advance\count1 by1 } \EveryShipout{\ltpage@shipout} \newcommand*{\ltpage@makelabel}{% \clearpage \addtocounter{page}{-1}% \immediate\write\@mainaux{% \string\newlabel{LastPage}{{\the\count1}{\thepage}}}% \addtocounter{page}{1}% } \AtEndDocument{\ltpage@makelabel} Abbildung 6-1: ltpage: lastpage und count1to in einem
nermaßen nicht die genialste Programmiersprache, was die Organisation von großen Systemen (etwa LATEX und dreiundfünfzig Zusatzpakete) angeht, und so kann es durchaus passieren, dass zwei Pakete einander auf die Füße treten, mit unangenehmen Folgen für die formatierte Ausgabe Ihres Dokuments. Ihr Experte wird Sie also als erstes fragen, welche Erweiterungen Sie benutzen und in welcher Version. Aber woher diese Informationen nehmen, ohne mühsam die Logdatei durchwühlen zu müssen? Nichts einfacher als das. LATEX bietet das Kommando \listfiles an, das die beteiligten Dateien und ihre Versionsnummern anzeigt. Schreiben Sie es einfach in die Präambel Ihres Dokuments: \documentclass{...} ... \listfiles \begin{document} ...
Hack #60: Die Zutatenliste
199
#60
HACK
#60
Die Zutatenliste
Die Ausgabe könnte ungefähr so aussehen (bei einem kleinen Testdokument für das ltpage-Paket aus dem vorigen Hack): *File List* article.cls size10.clo ltpage.sty everyshi.sty
2004/02/16 2004/02/16 2007/01/18 2001/05/15
v1.4f Standard LaTeX document class v1.4f Standard LaTeX file (size option) Last page number and total pages (AL) v3.00 EveryShipout Package (MS)
***********
Diese Liste ist nicht nur für jemanden nützlich, der Ihnen bei der Fehlersuche hilft (das könnten auch Sie selber sein), sondern auch, wenn Sie genau wissen wollen, welche Dateien in Ihr Dokument eingehen, etwa um es zu archivieren oder im Quellcode an jemand anderen zu schicken. Der Nachteil von \listfiles für die Zwecke der Archivierung ist, dass es nur die Dateinamen ausgibt, keine Verzeichnisnamen. (TEX hat intern kein Konzept von Verzeichnissen.) Zumindest in TEXLive unterstützt das Programm tex aber eine Kommandozeilenoption »-recorder«, mit der es die Namen aller Dateien, die es zum Lesen oder Schreiben öffnet, in einer Datei ablegt. Für dieses Buch sieht das etwa so aus: $ cat lthacks.fls PWD /home/anselm/TeX/LTH2 INPUT /var/lib/texmf/web2c/pdftex/pdflatex.fmt INPUT lthacks.tex OUTPUT lthacks.log INPUT orahacks.cls INPUT orahacks.cls INPUT /usr/share/texmf-texlive/tex/latex/base/book.cls ...
Am Anfang jeder Zeile steht, was der folgende Name bedeutet: PWD bezeichnet das aktuelle Verzeichnis, INPUT steht für eine Eingabe- und OUTPUT für eine Ausgabedatei.
CTAN enthält übrigens ein kleines Perl-Programm von Scott Pakin namens arlatex, das ein LATEX-Dokument und eine Anzahl anderer Dateien (etwa Paketdateien oder einzubindende EPS-Grafikdateien) zu einer Datei zusammenfasst. Diese Datei ist selbst ein LATEX-Dokument, das beim Lauf die anderen Dateien wieder »ausspuckt« – der Vorteil gegenüber Archivprogrammen wie ZIP oder TAR ist, dass der Empfänger nur LATEX zur Verfügung haben muss (ohne das er ohnehin dumm da steht, wenn Sie ihm eine LATEX-Eingabedatei schicken). Im selben Paket findet sich auch bundledoc, ein Programm, das alle an einem LATEX-Dokument beteiligten Eingabedateien im Dateisystem zu finden versucht (in den umfangreichen TEX-Verzeichnisbäumen keine triviale Aufgabe) und ein Programm wie arlatex (aber auch tar oder ähnliches)
200
Kapitel 6: Dokumente
HACK
Proceedings of the . . .
aufrufen kann, um diese Dateien und das eigentliche Dokument handlich zusammenzupacken. Apropos »Experten konsultieren«: Wenn Sie externe Hilfe für Ihre LATEX-Probleme suchen – seien das Ihre Kumpels oder die TEX-Benutzergemeinde im Internet –, können Sie die Chance auf eine Lösung ungemein erhöhen, indem Sie versuchen, Ihr Problem auf ein »Minimalbeispiel« zu reduzieren. Ein Minimalbeispiel ist die möglichst einfachste LATEX-Eingabedatei, die das Problem noch reproduziert. Tipps dafür, wie Sie ein Minimalbeispiel für ein Phänomen konstruieren können, finden Sie zum Beispiel auf http://www.minimalbeispiel. de/ – und die Chancen stehen gut, dass Sie durch diesen Prozess selbst einen besseren Verdacht bekommen, wo der Hase im Pfeffer liegt, und Ihr Problem vielleicht schon selber lösen können.
HACK
#61
Proceedings of the . . . Wie Sie Tagungsbände und ähnliche Sammelwerke setzen können
Zu einer wohlorganisierten Konferenz gehört eine Sammlung der gehaltenen Vorträge. Auch manches Buch ist eine Zusammenstellung von ansonsten unabhängigen Dokumenten (denken Sie an eine Anthologie von Kurzgeschichten). Gerade in der naturwissenschaftlichen Szene ist LATEX das Mittel der Wahl für Veröffentlichungen aller Art, und darum lohnt es sich, einen Blick darauf zu werfen, wie Sie mit LATEX zum Beispiel mehrere articles zu einem Tagungsband zusammenfassen können. Das Problem an dieser Stelle ist zunächst, dass LATEX pro Programmlauf nur ein \documentclass-Kommando und eine document-Umgebung duldet. Auch \author, \title und \maketitle dürfen nur einmal auftreten. Wenn artikel1.tex, artikel2.tex usw. also vollständige LATEX-Eingabedateien sind, dann führt ein naives \documentclass{book} ... \title{23. Jahrestagung der Pinguinfreunde Castrop-Rauxel} \author{Herausgegeben von B. Schäftigt} \begin{document} \maketitle \include{artikel1} \include{artikel2} ... \end{document}
nicht zum gewünschten Ergebnis, sondern nur zu Fehlermeldungen. Auf der
Hack #61: Proceedings of the . . .
201
#61
HACK
#61
Proceedings of the . . .
anderen Seite wäre es aber auch ärgerlich, jede artikel-Datei manuell ändern zu müssen, um die Präambel zu entfernen und einen neuen Titel einzubauen. Offensichtlich wird ein anderer Ansatz gebraucht. Die combine-Dokumentklasse für LATEX, entwickelt von Peter R. Wilson, ist speziell dafür gedacht, mehrere unabhängige Dokumente in ein einziges zu integrieren und dabei genau die genannten Probleme zu lösen. Sie sorgt auch dafür, dass Querverweise, Literaturangaben und Inhaltsverzeichnisse der Teildokumente »lokal« bleiben. Um combine zu verwenden, müssen Sie nur ein »Rahmendokument« aufstellen, das ungefähr so aussieht wie in Abbildung 6-2. Bemerkenswert ist zunächst, dass das Rahmendokument aussieht wie ein ganz normales LATEX-Dokument. Es hat seine Titel- und Autorenangabe und ein Inhaltsverzeichnis, ganz wie man das erwarten würde. Auffällig ist außer dem \pagestyle{combine}, der für eine fortlaufende Seitennummerierung über alle eingebundenen Dokumente hinweg sorgt, nur die papers-Umgebung, in der alle eingebundenen Dokumente enthalten sind. Für jeden Artikel im Tagungsband sorgt etwas wie \coltoctitle{Brauchen Pinguine Fischbesteck?} \coltocauthor{Anton Auerhahn} \label{artikel1} \import{artikel1}
für den korrekten Eintrag im Inhaltsverzeichnis des Gesamtdokuments und die Möglichkeit, auf den Anfang des Artikels zu verweisen. Das Kommando \import schließlich ist eine Art Kreuzung aus \input und \include und sorgt für die Einbindung des Artikels, wobei dessen Präambel so weit wie möglich »neutralisiert« wird. Um die papers-Umgebung herum können Sie Vorworte, Werbeeinblendungen und ähnliches platzieren; Sie können auch Quer- oder Literaturverweise benutzen, die unabhängig von denen in den eingebundenen Dokumenten behandelt werden. In Abbildung 6-3 sehen Sie einen »Tagungsband« mit zwei kurzen Artikeln, die mit combine zusammengefasst wurden. combine ist ein »Hack« im wahrsten Sinne des Wortes – die Dokumentklas-
se macht etwas, wofür LATEX nie vorgesehen war, und das kann klappen oder auch nicht. Am größten ist die Chance, dass es klappt, wenn die eingebundenen Dokumente ähnliche oder gleiche Präambeln verwenden. combine macht beim \import alle \newcommand- und \newenvironment-Kommandos zu \providecommand und \provideenvironment, so dass es keine LATEX-Fehlermeldungen wegen bereits definierter Kommandos und Umgebungen gibt; auf der anderen Seite ist es immer die zuerst gesehene Definition, die gewinnt, und die für später gelesene Dokumente (deren eigene Definitionen ignoriert wurden) vielleicht nicht passt. Dasselbe gilt für \newlength und \newcounter.
202
Kapitel 6: Dokumente
HACK
Proceedings of the . . .
\documentclass[12pt]{combine} \usepackage[latin1]{inputenc} \usepackage[T1]{fontenc} \usepackage[ngerman]{babel} \title{23. Jahrestagung der Pinguinfreunde Castrop-Rauxel} \author{Herausgegeben von B. Schäftigt} \begin{document} \maketitle \pagestyle{combine} \tableofcontents \clearpage \section*{Einleitung} Im Artikel von Anton Auerhahn auf Seite~\pageref{artikel1} steht \dots\ Bei Bruno Bambusbär auf Seite~\pageref{artikel2} dagegen \dots \begin{papers} \coltoctitle{Brauchen Pinguine Fischbesteck?} \coltocauthor{Anton Auerhahn} \label{artikel1} \import{artikel1} \coltoctitle{Freiflugvolieren für Pinguine selbst gebaut} \coltocauthor{Bruno Bambusbär} \label{artikel2} \import{artikel2} % ... \end{papers} \clearpage \section*{Danksagungen} Besonders danken möchten wir der Firma Schulz-Kältetechnik in Eisleben, die \dots \end{document} Abbildung 6-2: Ein »Rahmendokument« für einen Tagungsband mit combine
Hack #61: Proceedings of the . . .
203
#61
#61
aaaa Aaaaaaa aaaaaaaaa. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa.
Brauchen Pinguine Fischbesteck?
Im Artikel von Anton Auerhahn auf Seite 3 steht . . . Bei Bruno Bambusbär auf Seite 5 dagegen . . .
Anton Auerhahn
2
Zusammenfassung
Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa [2]. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa.
Herausgegeben von B. Schäftigt
Kapitel 6: Dokumente
28. März 2007
Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa.
Aaaaaaaaa aaaaaaaaaaa
Inhaltsverzeichnis Brauchen Pinguine Fischbesteck? Anton Auerhahn
3
Freiflugvolieren für Pinguine selbst gebaut Bruno Bambusbär
5
1
∞ X i=0
1
1 i
Literatur
2 Zusammenfassung
1
3
4
Danksagungen Besonders danken möchten wir der Firma Schulz-Kältetechnik in Eisleben, die . . .
Bbbbbbbbb bbbbbbbbbbb
Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb [2]. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb.
Bbbbbbbbbbbbbbb
a=
∞ X i=0
Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb [1]. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb. b=
∞ X i=0
1 i
1 i
Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb (Abschnitt 1 auf Seite 5). Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb.
Literatur
Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb 5
[1] Aaa aaa Aaaa. Aaaaaa aaa Aaaaaa aaaa. Aaaaa 12:45678. [2] Aaaaa Aaaaaaaa. Aa aaa Aaaaaaaaaa aa? Aaaaaaaa 1A:34-56.
Bruno Bambusbär
Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb.
1 i
Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa (Abschnitt 1 auf Seite 3). Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa.
Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa 2
Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb. Bbb bbbb Bbbbbb bbbbbb bbb bbbbb Bbbbbb, bb Bbbbbbb bbb bbbbb Bbbbbbb bb bbbbbb, bbbb bbbbbbb Bbbbbb bbbb Bbbbbbb bbbbbbbbb.
∞ X i=0
Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa [1]. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaaaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa. Aaa aaaa Aaaaaa aaaaaa aaa aaaaa Aaaaaa, aa Aaaa aaa aaaaa Aaaaaaa aa aaaaaa, aaaa aaaaaaa Aaaaaa aaaa Aaaaaaa aaaaaaaaa. a=
Freiflugvolieren für Pinguine selbst gebaut
a=
Aaaaaaaaaaaaaaa
[1] Bbb bbb Bbbb. Bbbbbb bbb Bbbbbb bbbb. Bbbbb 12:456-78. [2] Bbbbb Bbbbbbbb. Bb bbb Bbbbbbbbbb bb? Bbbbbbbb 1A:34-56. 6
Abbildung 6-3: Ein »Tagungsband« mit zwei kurzen Artikeln, zusammengefasst mit combine
7
Proceedings of the . . .
Einleitung
HACK
204
23. Jahrestagung der Pinguinfreunde Castrop-Rauxel
HACK
Serienbriefe für Serientäter
Ein weiterer Bestandteil des combine-Pakets ist das combinet-Paket, das nützlich ist, wenn Sie nicht die Titel und Autoren der eingebundenen Dokumente mit \coltoctitle und \coltocauthor in Ihrem Rahmendokument wiederholen wollen. Es ändert das \maketitle-Kommando in einem eingebundenen Dokument so, dass die Titel- und Autorenangaben aus dem eingebundenen Dokument ins Inhaltsverzeichnis des Rahmendokuments übernommen werden. Allerdings kommt es vor, dass Autoren kreativen Code in die Titel- oder Autorenangabe tun (etwa über \thanks), der dann das Inhaltsverzeichnis durcheinanderbringt. In diesem Fall müssen Sie doch auf \coltoctitle und \coltocauthor zurückgreifen. Eine große Hilfe im Umgang mit combine sind natürlich wohlerzogene Autoren der einzubindenden Dokumente. Die Erfahrung lehrt, dass das Management der Autoren von Tagungsbandbeiträgen noch am ehesten mit dem Zusammentreiben einer Herde Katzen zu vergleichen ist (der Autor dieser Zeilen könnte da die eine oder andere war story erzählen) und die Hoffnung, von fünfundzwanzig Autoren fünfundzwanzig perfekt mit combine zusammenwerfbare Artikel zu bekommen, ungefähr so berechtigt ist wie die Hoffnung darauf, dass eines Tages Ostern, Pfingsten und Weihnachten auf denselben Tag fallen werden. Insbesondere ist in so einer Gruppe von Autoren immer mindestens ein Individualist, der absolut eines der gruseligen proprietären Textverarbeitungsprogramme für seinen Beitrag verwenden muss. In so einem Fall ist Ihre beste Hoffnung, diesen Beitrag in PDF umzuwandeln und mit pdfpages einzubauen [Hack #86].
HACK
#62
Serienbriefe für Serientäter Erzeugen Sie dasselbe Dokument x-mal mit kleinen Änderungen.
Eine typische »Büroaufgabe« ist das Verschicken von Serienbriefen: Eine Briefvorlage wird an viele Empfänger geschickt, wobei Name, Adresse, Anrede und ähnliches jeweils für jeden Empfänger individuell eingesetzt wird. Die Empfängerdaten können aus einer Datenbank kommen oder anderswie erzeugt werden. Natürlich ist das auch mit LATEX kein Problem, und hier zeigen wir Ihnen einige Ansätze dafür.
Mit Linux-Bordmitteln Im einfachsten Fall erzeugen wir eine LATEX-Eingabedatei, die jeden einzelnen der zu verschickenden Serienbriefe in kompletter Form enthält. Abbildung 6-4 zeigt, wie Sie das mit den typischen Linux-Bordmitteln (der Bash-Shell und sed) hinbekommen, ausgehend von einer Vorlage wie in Abbildung 6-5. Bis auf etwas sed-Akrobatik und die Verwendung von Bash-Arrays zum Speichern Hack #62: Serienbriefe für Serientäter
205
#62
HACK
#62
Serienbriefe für Serientäter
#!/bin/bash # mailmerge - Serienbriefe mit LaTeX und Linux-Bordmitteln letter=$1 shift # Gib die Präambel des Dokuments aus sed -n ’/\\documentclass/,/\\begin{document}/p’ $letter # Hole die zu wiederholende letter-Umgebung und die Feldnamen text=‘sed -n ’/\\\\begin{letter}/,/\\\\end{letter}/p’ $letter‘ eval fields=(‘sed -n ’s/^%%F://p’ $letter‘) max=$((${#fields[*]}-1)) # Durchlaufe die Adressenliste (mit durch ":" getrennten Feldern) # und erzeuge eine Kopie der letter-Umgebung pro Datensatz IFS=: cat $* | while read -a v do # Wir bauen in $substs eine Reihe von sed-Kommandos der Form # "-e ’s/@FELD@/Wert/’ auf, die wir am Schluss auf die # Vorlage anwenden substs=’’ i=0 for f in ${fields[*]} do substs="$substs -e ’s/@$f@/${v[$i]}/g’" i=$((i+1)) done echo $text | eval sed $substs done # Gib den Schluss des Dokuments aus (etwas verkrampft) sed -n ’/\\end{letter}/,${/^\\end{letter}/d;p}’ $letter Abbildung 6-4: mailmerge, ein Shellskript zur Serienbrief-Erzeugung
206
Kapitel 6: Dokumente
HACK
Serienbriefe für Serientäter
%%F:NAME ADRESSE ORT ANREDE \documentclass[12pt]{scrlttr2} \usepackage[latin1]{inputenc} \usepackage[ngerman]{babel} \setkomavar{fromname}{Beispiel GmbH \& Co. KG} \setkomavar{fromaddress}{Gewerbeplatz 1\\ 22222 Beispielshausen} \setkomavar{subject}{Preisausschreiben} \begin{document} \begin{letter}{@NAME@\\@ADRESSE@\\@ORT@} \opening{Sehr geehrte@ANREDE@,} wir freuen uns, Ihnen mitteilen zu können, dass Sie in unserem Preisausschreiben einen phänomenalen Preis gewonnen haben. \closing{Mit freundlichen Grüßen,} \end{letter} \end{document} Abbildung 6-5: Ein Musterbrief für die Serienbrief-Erzeugung
der Ersatztexte und deren Namen ist das Skript nicht bemerkenswert; man könnte es sicher auch mit weniger Code schaffen, aber der Witz an unserem Ansatz ist, dass Sie die Vorlage auch direkt mit LATEX bearbeiten können, etwa um die Formatierung zu prüfen. (Die Ausgabe finden Sie in Abbildung 6-6.) Was Sie außer der LATEX-Vorlage noch brauchen, ist natürlich die Adressenliste, die in unserem Fall aussehen kann wie Hugo Schulz:Beispielstraße 11:12345 Königs-Musterhausen:r Herr Schulz Sabine Mustermensch:Musterweg 19c:54321 Anderswo: Frau Mustermensch Egon Meier:Platanenallee 19:33333 Beispieldorf:r Herr Meier
(etc.) Dabei entsprechen die durch »:« getrennten Felder den in der Zeile %%F:NAME ADRESSE ORT ANREDE
angegebenen Ersatztexten – das erste Feld in einer Zeile in der Adressenliste ist der Name, dann kommt die Adresse und so weiter. Ein Aufruf wie $ mailmerge brief.tex adressen.dat
mit dem Namen der Vorlage als erstem und dem Namen der Adressenliste als zweitem Parameter erzeugt dann eine LATEX-Eingabedatei, die für jeden Adressaten eine Kopie des Briefs enthält. Diese Datei können Sie TEXen, drucken, die Briefe eintüten und zur Post bringen. Tadaaa!
Hack #62: Serienbriefe für Serientäter
207
#62
HACK
#62
Serienbriefe für Serientäter
Beispiel GmbH & Co. KG Gewerbeplatz 1 22222 Beispielshausen
Beispiel GmbH & Co. KG, Gewerbeplatz 1, 22222 Beispielshausen
@NAME@ @ADRESSE@ @ORT@
30. M¨arz 2007 Preisausschreiben
Sehr geehrte@ANREDE@, wir freuen uns, Ihnen mitteilen zu k¨onnen, dass Sie in unserem Preisausschreiben einen ph¨anomenalen Preis gewonnen haben. Mit freundlichen Gr¨ ußen,
Beispiel GmbH & Co. KG
Abbildung 6-6: Der Musterbrief, einfach geTEXt
208
Kapitel 6: Dokumente
HACK
Serienbriefe für Serientäter
Mit den üblichen Bordmitteln können Sie übrigens auch noch ein gutes Stück weiter kommen. Stellen Sie sich vor, Sie möchten den Adressaten in Ihrer Liste auch noch mitteilen, welchen Preis sie in unserem hypothetischen Preisausschreiben gewonnen haben. Dazu können Sie die Preiskategorie als erstes Feld in die Adressatenliste aufnehmen: 1:Hugo Schulz:Beispielstraße 11:12345 Königs-Musterhausen:... 2:Sabine Mustermensch:Musterweg 19c:54321 Anderswo:... 3:Egon Meier:Platanenallee 19:33333 Beispieldorf:... 3:Susi Schneider:Birkengasse 3:98765 Irgendstein:... ...
(es gibt mehrere dritte Preise). Dazu brauchen Sie eine Liste der Preise: 1:den ersten Preis:Eine Woche Urlaub in der Eifel 2:den zweiten Preis:Zwei Wochen Urlaub in der Eifel 3:einen dritten Preis:Einen Prunk-Briefbeschwerer
Diese Dateien können Sie dann mit dem join-Kommando zusammenfügen und an mailmerge verfüttern: $ join -t: adressen.dat preise.dat | mailmerge brief.tex join fügt die beiden Dateien »relational« zusammen, und zwar anhand des ersten Feldes in jeder Zeile (das »-t:« sagt join, dass Felder durch Doppel-
punkte getrennt werden). Voraussetzung dafür, dass das klappt, ist, dass die Zeilen beider Dateien bezüglich der Werte dieses Feldes sortiert sind. Das Ergebnis sieht ungefähr so aus wie 1:Hugo Schulz:Beispielstraße 11:12345 Königs-Musterhausen :r Herr Schulz:den ersten Preis:Eine Woche Urlaub in der Eifel 2:Sabine Mustermensch:Musterweg 19c:54321 Anderswo : Frau Mustermensch:den zweiten Preis:Zwei Wochen Urlaub in der Eifel ...
(mit Zeilenumbrüchen zum besseren Lesen), und eine passende Vorlage finden Sie in Abbildung 6-7. Abbildung 6-8 zeigt eine typische Ausgabe. Durch die »cat $* | while read ...«-Konstruktion in mailmerge haben wir übrigens sichergestellt, dass das Programm seine Adressen aus benannten Eingabedateien oder, falls keine angegeben wurden, von der Standardeingabe liest – immer ein nützliches Verhalten für Unix-Werkzeuge. (Ignorieren Sie alle Leute, die Ihnen weismachen wollen, »while read ...$tempfile artist_title=$(sed -ne ’/^DTITLE=/s/^DTITLE=//p’ $tempfile) artist_title_br=$(echo $artist_title | sed -e ’s, / ,\\\\,’) tracks=$(sed -ne ’/^TTITLE/s/^TTITLE.*=/\\item /p’ $tempfile) extra_info=$(sed -ne ’/^EXTD=/{s/^[^,]*,//;s/YEAR:.*$//;p}’ $tempfile) rm -f $tempfile cat >$1-$2.tex &2 "*** Resultat steht in $1-$2.pdf" Abbildung 6-15: Automatisches Erstellen von Audio-CD-Hüllen
222
Kapitel 6: Dokumente
HACK
CDs perfekt verhüllt
4
3
13
12
❅ ❅ ❅ ❅ ❅ ❅
1996, Vertigo 514 732-2
Mark Knopfler Golden Heart Mark Knopfler / Golden Heart
Mark Knopfler / Golden Heart 1. Darling Pretty 2. Imelda 3. Golden Heart 4. No Can Do 5. Vic And Ray 5 (bottom)
5 (bottom)
6. Don’t You Get It 7. A Night In Summer Long Ago 8. Cannibals 9. I’m The Fool
7 (top)
7 (top)
10. Je Suis Désolé 11. Rüdiger 6 (top)
12. Nobody’s Got The Gun 13. Done With Bonaparte 14. Are We In Trouble Now
6 (top)
8
10
❅ ❅ ❅ ❅ ❅ ❅ ❅ ❅
9
11
❅ ❅ ❅
4
3
❅ ❅ ❅ ❅ ❅
Abbildung 6-16: Eine Origami-Audio-CD-Hülle
Hack #64: CDs perfekt verhüllt
223
#64
HACK
#65
Gestatten, LATEX
• Ein anderes Paket zur Erstellung von CD-Inlays ist cd-cover von Christian Holm. Im Gegensatz zu cd kann es auch Seiten für CD-Broschüren formatieren, was hin und wieder nützlich sein mag.
HACK
#65
Gestatten, LATEX Wie Sie Etiketten und Visitenkarten gezielt bedrucken können
LATEX wird normalerweise nicht mit Drucksachen in Verbindung gebracht, bei denen vor allem die Optik im Vordergrund steht und erst in zweiter Linie die leichte Lesbarkeit – etwa Visitenkarten. Aber das heißt nicht, dass es unmöglich wäre, Visitenkarten, Namensschilder, Aufkleber und ähnliches mit LATEX herzustellen. Im Gegenteil, es ist sogar recht einfach und bequem, jedenfalls wenn Sie passende Unterstützung haben. In Frage käme da das ticket-Paket von Thomas Emmel. ticket kann gezielt vorgekochte Blätter für Visitenkarten, Ordnerrücken oder Aufkleber bedrucken. Alles, was Sie dafür brauchen, ist eine »Ticket-Definitions-Datei« (TDF-Datei), die das zu bedruckende Material spezifiziert, und LATEX-Code für das, was darauf erscheinen soll. Bequemerweise können Sie einen »Hintergrund« angeben, der auf jedem Exemplar auf dem Blatt erscheinen soll, und nur die variablen Teile (etwa den Namen und die Organisation eines Teilnehmers bei Namensschildern für Tagungen) jedesmal neu angeben.
Abbildung 6-17 zeigt ein Blatt (der Drucker sagt »Nutzen«) mit Visitenkarten, das wir so zum Beispiel auf vorgeschnittene Karten Marke »Zweckform 32010« drucken könnten3 . Die dazugehörige LATEX-Eingabe könnte ungefähr so aussehen: \documentclass[a4paper,12pt]{article} \usepackage[latin1]{inputenc} \usepackage{graphicx} \usepackage{color} \definecolor{uni}{gray}{.4} \usepackage[zw32010,crossmark]{ticket}
In der Präambel holen wir alle benötigten Pakete (hier außer ticket noch graphicx und color für die grafischen Elemente wie den Pinguin und die graue Linie zwischen Telefonnummern und Adresse). Die crossmark-Option von ticket sorgt für die kreuzförmigen Schnittmarken an den Ecken – neben dieser gibt es noch eine Handvoll andere Möglichkeiten. Auf vorperforierten 3
Dies soll keine Schleichwerbung für die Firma »Zweckform« sein – wir sind überzeugt, dass alle anderen Hersteller auch hervorragende Visitenkarten machen. Bequemerweise ist beim ticket-Paket aber eine TDF-Datei für ausgerechnet diese Visitenkarten dabei.
224
Kapitel 6: Dokumente
HACK
Gestatten, LATEX
Hugo Schulz
Hugo Schulz
Senior-Pinguinb¨andiger
Senior-Pinguinb¨andiger
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨ onigs-Musterhausen
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨onigs-Musterhausen
Hugo Schulz
Hugo Schulz
Senior-Pinguinb¨andiger
Senior-Pinguinb¨andiger
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨ onigs-Musterhausen
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨onigs-Musterhausen
Hugo Schulz
Hugo Schulz
Senior-Pinguinb¨andiger
Senior-Pinguinb¨andiger
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨ onigs-Musterhausen
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨onigs-Musterhausen
Hugo Schulz
Hugo Schulz
Senior-Pinguinb¨andiger
Senior-Pinguinb¨andiger
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨ onigs-Musterhausen
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨onigs-Musterhausen
Hugo Schulz
Hugo Schulz
Senior-Pinguinb¨andiger
Senior-Pinguinb¨andiger
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨ onigs-Musterhausen
Tel: +49(0)9999992 Fax: +49(0)9999993
[email protected] TuxTEX International Beispielgasse 123 99999 K¨onigs-Musterhausen
Abbildung 6-17: Ein »Nutzen« mit Visitenkarten
Hack #65: Gestatten, LATEX
225
#65
HACK
#65
Gestatten, LATEX
Karten wären eigentlich gar keine Schnittmarken nötig, aber wir drucken sie aus zwei Gründen: • Wir möchten Ihnen zeigen, dass es geht, und
• geizig, wie wir nun mal sind, drucken wir bei einem neuen Entwurf immer erst ein Blatt Visitenkarten auf normales (billiges) Papier und halten es vor den (teuren) Visitenkarten-Blättern gegen eine helle Lampe, um uns zu überzeugen, dass alles auch da sitzt, wo es hingehört. Die Schnittmarken helfen dabei, und für den tatsächlichen Druck schalten wir sie ab.
Als nächstes definieren wir den »Hintergrund« für die Visitenkarten. Dazu gehören die Grafik und die Adresse der »Firma«. Den Namen und die Telefonnummern des Visitenkarten-Inhabers setzen wir später ein. Auch der Hintergrund wäre hier nicht zwingend nötig – Sie könnten das, was darin steht, immer auch in die Definition der Visitenkarte selbst aufnehmen –, aber er spart ein bisschen Tipparbeit, wenn Sie mehrere Sorten Visitenkarten anlegen wollen, und konzentriert die »Corporate Identity« weitgehend an einer Stelle. Ansonsten wäre die Versuchung groß, die »Hintergrundelemente« per BlockCopy in 50 Visitenkartendefinitionen zu übernehmen, und wehe Ihnen, wenn sich dann etwas Nichttriviales ändert . . . Extrem nützlich ist er auch für Konferenz-Namensschilder und ähnliches (hierzu später mehr). Der Hintergrund ist einfach der Inhalt einer LATEX-picture-Umgebung, und die \unitlength ist bequemerweise auf 1 Millimeter voreingestellt: \renewcommand{\ticketdefault}{% \put( 45, 5){\includegraphics[width=38mm,origin=bl]{tux-logo}} \put( 5, 15){\color{uni}\line(1,0){36}} \put( 7, 11){\small Tux\TeX\ International} \put( 7, 7){\small Beispielgasse 123} \put( 7, 3){\small 99999 Königs-Musterhausen} \put( 7, 24){\small Tel:} \put( 7, 20){\small Fax:} }
Nun kommt die Definition des »variablen« Teils der Visitenkarte. Das ticketPaket sieht hierfür das Kommando \ticket vor, dessen Inhalt ebenfalls in einer LATEX-picture-Umgebung landet. Auf der Basis von \ticket definieren wir ein \vcard-Kommando, das die variablen Elemente als Parameter übernimmt und passend auf der Karte positioniert: \newcommand{\vcard}[5]{\ticket{% \put(6,40){\LARGE\bfseries #1} \put(7,34){#2} \put(14,24){\small #3}
226
Kapitel 6: Dokumente
HACK
Gestatten, LATEX
\put(14,20){\small #4} \put( 7,16){\small #5} }}
Jetzt müssen wir nur noch die tatsächlichen Karten drucken, zehn auf einen Sitz. Das passiert wie folgt: \begin{document} \sffamily \newcounter{numcards} \whiledo{\value{numcards} F N V ^ f n v ~
ˇ ›
ˇ N ˇ T
( 0 8 @ H P X ‘ h p x ˘ A
A˛
´L ˇ R
L’ ´ S
Ł
´ N
Š
Ÿ ˘ a ´l
´ Z a˛
Ž ´ c
¸ S ˙ Z ˇ c
ˇr ÿ
l’ ´s ´ z
ł š ž
´ n ¸s ˙ z
À
Á
Â
Ã
IJ d’
T ¸ ˙I
E˛ ˝ O ˝ U
ffl ’ / 7 ? G O W _ g o w ˘ G ´ R ˚ U
ˇ e
d ¯ ˛ e
§ ˘ g
ˇ n t’ ij
¸t ¡
˝ o ˝ u ¿
´r ˚ u £
Ä
Å
Æ
Ç
´31x
È
É
Ê
Ë
Ì
Í
Î
Ï
´32x
Ð
Ñ
Ò
Ó
Ô
Õ
Ö
Œ
´33x ´34x ´35x ´36x ´37x
Ø à è ð ø
Ù á é ñ ù
Ú â ê ò ú
Û ã ë ó û
Ü ä ì ô ü
Ý å í õ ý
Þ æ î ö þ
SS ç ï œ ß
˝8
˝9
˝A
˝B
˝C
˝D
˝E
˝F
˝0x ˝1x ˝2x ˝3x ˝4x ˝5x ˝6x ˝7x ˝8x ˝9x ˝Ax ˝Bx ˝Cx ˝Dx ˝Ex ˝Fx
Abbildung 7-2: testfont-Tabelle für URW Classico
Zu guter Letzt müssen Sie noch die Dateinamensliste auf den neuesten Stand bringen, die TEX verwendet, um seine Eingabedateien schnell finden zu können. Sagen Sie (als Systemverwalter): # texhash
Die neuen Schriften benutzen Sie können sich ein einfaches Bild davon machen, welche Zeichen in Ihrer neuen Schrift enthalten sind, indem Sie eine Tabelle ausgeben. Hierzu bietet TEX eine Datei namens testfont.tex:
250
Kapitel 7: Schriften
HACK
LATEX und PostScript-Schriften
$ tex testfont This is TeX, Version 3.141592 (Web2C 7.5.4) (/usr/share/texmf-tetex/tex/plain/base/testfont.tex Name of the font to test = uopr8t Now type a test command (\help for help):) *\table\bye [1] Output written on testfont.dvi (1 page, 10948 bytes). Transcript written on testfont.log.
testfont.tex kann diverse Testmuster für Schriften erzeugen, aber das Kommando \table gibt eine Zeichentabelle aus (siehe Abbildung 7-2). Innerhalb eines Dokuments können Sie jederzeit mit \fontfamily{uop}\selectfont
auf die URW Classico umschalten, aber wirklich bequem ist das nicht, und außerdem widerspricht es dem Gedanken, sich pro Dokument ein für alle Mal für eine Schrift zu entscheiden. In Familienangelegenheiten [Hack #67] haben Sie gesehen, wie Sie eine Schriftfamilie global für eine der drei LATEX-Standardschriften Serifenschrift, serifenlose Schrift und Schreibmaschinenschrift einstellen können. Wenn Sie also zum Beispiel die KOMA-Script-Dokumentklassen verwenden, die Überschriften normalerweise in der serifenlosen Familie von LATEX setzen, können Sie mit dem Kommando \renewcommand*{\sfdefault}{uop}
dafür sorgen, dass alle Überschriften in Optima erscheinen – zusammen mit Palatino als »Brotschrift«, ist das vom typografischen Standpunkt aus gar keine dumme Idee. Palatino erreichen Sie einfach mit: \usepackage{mathpazo}
Natürlich können Sie die Details der Schriftauswahl auch in einem LATEX-Paket verstecken. Etwas wie \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{sfoptima}[2007/01/17 v1.0 URW Classico als SF] \renewcommand*{\sfdefault}{uop} \endinput
sollte dafür ausreichen, so dass Sie für den eben vorgeschlagenen Effekt nur noch Folgendes schreiben müssen: \usepackage{mathpazo,sfoptima}
Hack #69: LATEX und PostScript-Schriften
251
#69
HACK
#70
Automatisierte Schriftanpassung
Siehe auch • Eine gute Einführung in die Feinheiten der Anpassung von Type-1-Schriften für LATEX ist The Font Installation Guide von Philipp Lehman (http: //www.ctan.org/tex-archive/info/Type1fonts/fontinstallationguide/). Dieses über hundert Seiten starke und sehr liebevoll gesetzte Handbuch beschreibt neben den hier gezeigten Anfangsgründen zum Beispiel auch den Umgang mit sogenannten »Expertenschriften«, die zusätzliche Zeichen und Ligaturen enthalten, mit Kapitälchen, Mediävalziffern und dem Eurozeichen. • Die Details von fontinst erklärt die Dokumentation des Pakets selbst. Ganz fertig ist sie (wie auch fontinst) aber leider noch nicht. • Wenn Sie wissen wollen, wie die TEX-Base-1- und die T1-Codierung genau aussehen, können Sie in Ihrem TEX-System die Dateien 8r.enc und cork.enc suchen. Diese Dateien sind relativ umfassend kommentiert.
HACK
#70
Automatisierte Schriftanpassung Vermeiden Sie langweilige Kommandofolgen mit einem Shell-Skript
Die im vorigen Hack vorgestellte Prozedur ist langwierig, aber nicht besonders anspruchsvoll – ein idealer Kandidat für die Automatisierung mit einem ShellSkript. Wir stellen Ihnen hier ein Skript namens tex-t1font vor, das die Aufgaben aus dem vorigen Hack weitestgehend übernimmt. Sie müssen nur noch ein Arbeitsverzeichnis anlegen und dort die PFB- und AFM-Dateien für die anzupassende Schrift mit den korrekten Namen im Karl-Berry-Stil zur Verfügung stellen. Unser Skript wird dann mit dem Familiencode der Schriftfamilie aufgerufen: $ tex-t1font uop
Es erledigt die folgenden Schritte: • Die (laut Konvention) korrekten Namen für Schriftanbieter und Schriftfamilie bestimmen. tex-t1font bedient sich dafür der Dateien supplier.map und typeface.map, die in den gängigen TEX-Distributionen enthalten sind. Sollten Sie sich an einer Schriftfamilie versuchen, die in diesen Dateien nicht auftaucht, müssen Sie den Anbieter und die Schriftfamilie explizit über die Kommando-Optionen -s und -t angeben. • Mit fontinst die Metriken und virtuellen Schriften erstellen. Hier gehen wir davon aus, dass \latinfamily ohne weitere Tricks ausreicht, um das Nötige zu tun.
252
Kapitel 7: Schriften
HACK
Automatisierte Schriftanpassung
#!/bin/bash suppfile=$(kpsewhich supplier.map) typefile=$(kpsewhich typeface.map) target=$(kpsewhich -expand-var \$TEXMFHOME) sudo= domaps=1 suppname= typename= latexfamily=rm usage="usage: %s [-m] [-p] [-s supplier] [-t face] [-F rm|sf|tt] family" while getopts mps:t:F: arg do case $arg in p) target=$(kpsewhich -expand-var \$TEXMFLOCAL) sudo=sudo ;; m) domaps=0 ;; s) suppname="$OPTARG" ;; t) typename="$OPTARG" ;; F) latexfamily="$OPTARG" ;; ?) printf $usage $0; exit 2 ;; esac done shift $(($OPTIND - 1)) famcode=$1 if [ -z "$suppname" ] then suppname=$(grep "^$(echo $famcode | cut -c1-1)" \ $suppfile | cut -d’ ’ -f2) fi if [ -z "$typename" ] then typename=$(grep "^$(echo $famcode | cut -c2-3)" \ $typefile | cut -d’ ’ -f2) fi if [ -z "$suppname" -o -z "$typename" ] then echo >&2 "supplier or typeface codes unknown"; exit 1 fi Abbildung 7-3: tex-t1font – ein Shellskript zur Anpassung von Type-1-Schriften für LATEX (Anfang)
Hack #70: Automatisierte Schriftanpassung
253
#70
HACK
#70
Automatisierte Schriftanpassung
cat $famcode-drv.tex % $famcode-drv.tex \\input fontinst.sty \\recordtransforms{$famcode-rec.tex} \\latinfamily{$famcode}{} \\endrecordtransforms \\bye EOF tex $famcode-drv.tex for f in *.pl; do pltotf $f; done for f in *.vpl; do vptovf $f; done $sudo mkdir -p $target/fonts/{afm,tfm,type1,vf}/$suppname/$typename for s in afm tfm vf; do $sudo mv *.$s $target/fonts/$s/$suppname/$typename done $sudo mv *.pfb $target/fonts/type1/$suppname/$typename $sudo mkdir -p $target/tex/latex/$suppname-$typename date=$(date +%Y/%m/%d) cat $typename.sty \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{$typename}[$date v0.1 $suppname $typename for LaTeX] \renewcommand*{\\${latexfamily}default}{$famcode} \endinput EOF $sudo mv *.fd *.sty $target/tex/latex/$suppname-$typename rm -f *.pl *.vpl *.mtx Abbildung 7-4: tex-t1font – ein Shellskript zur Anpassung von Type-1-Schriften für LATEX (Mitte)
254
Kapitel 7: Schriften
HACK
Automatisierte Schriftanpassung
if [ $domaps = 1 ] then cat $famcode-map.tex \\input finstmsc.sty \\resetstr{PSfontsuffix}{.pfb} \\adddriver{dvips}{$famcode.map} \\input $famcode-rec.tex \\donedrivers \\bye EOF tex $famcode-map.tex $sudo mkdir /etc/texmf/map/dvips/$suppname $sudo mv $famcode.map /etc/texmf/map/dvips/$suppname echo "Map $famcode.map" >tmp.map $sudo mv tmp.map /etc/texmf/updmap.d/10$famcode.map $sudo update-updmap $sudo updmap-sys fi $sudo mktexlsr $target Abbildung 7-5: tex-t1font – ein Shellskript zur Anpassung von Type-1-Schriften für LATEX (Schluss)
• Die Resultate des fontinst-Laufs an ihren Platz kopieren. Standardmäßig ist das das texmf -Unterverzeichnis in Ihrem Home-Verzeichnis, wobei tex-t1font sich darum kümmert, die nötige Verzeichnishierarchie anzulegen, sofern sie noch nicht existiert. Wenn Sie die Kommando-Option -p (wie public) angeben, werden die Dateien stattdessen unter $TEXMFLOCAL abgelegt, so dass sie im ganzen System sichtbar sind. Hierfür sind in der Regel Administratorprivilegien nötig, die sich das Skript über sudo holt. • Ein LATEX-Paket erstellen und installieren, das eine der drei Standardfamilien auf die neue Schriftfamilie umschaltet. Normalerweise ändert das Paket den \rmdefault, aber über die Kommando-Option -F können Sie den \sfdefault oder \ttdefault wählen: $ tex-t1font -F sf uop
erzeugt zum Beispiel das Paket optima, so wie wir es in LATEX und PostScript-Schriften [Hack #69] vorgestellt haben, mit
Hack #70: Automatisierte Schriftanpassung
255
#70
HACK
#71
Die Wahre Type
\renewcommand*{\sfdefault}{uop}
• Eine Map-Datei für die Schriftfamilie erstellen und installieren. Die Installation in unserem Beispiel ist spezifisch für TEXLive unter Debian GNU/Linux und hat den Vorteil, komplett automatisch zu funktionieren. Für andere Plattformen sind hier mitunter Änderungen nötig.
Das Skript tex-t1font ist natürlich nur ein Anfang (aber ein nützlicher). Zahlreiche Erweiterungen sind denkbar – zum Beispiel könnten Sie noch Kommando-Optionen einführen, um den Namen des LATEX-Pakets zu setzen. Leiten Sie die Ausgabe der einzelnen Programme in eine Datei um, um den Bildschirm nicht zuzumüllen. Wenn Sie mehr über fontinst wissen, können Sie auch dafür weitere Vereinfachungen schaffen. Toben Sie sich aus!
HACK
#71
Die Wahre Type Wie Sie TrueType-Schriften mit LATEX verwenden können
Wenn Sie beliebige PostScript-Type-1-Schriften für LATEX verdaulich machen können [Hack #69], drängt sich die nächste Frage auf: Was ist mit den TrueType-Schriften, die sich zu Dutzenden, wenn nicht Hunderten auf billigen CDs tummeln oder gar frei aus dem Internet herunterzuladen sind? Na, wenn wir mal ehrlich sind, sind viele davon die Mühe nicht wirklich wert – aber das sollte uns nicht davon abhalten, Ihnen zu zeigen, wie Sie sich diejenigen, die den Aufwand lohnen, nutzbar machen können. Betrachten wir als Beispiel mal die populäre Schrift »Comic Sans MS«, die Microsoft im Rahmen des »TrueType Core Fonts for the Web« kostenlos zur Verfügung gestellt hat. Sie eignet sich für informelle Drucksachen wie Geburtstagseinladungen und wird in dieser Funktion so gerne verwendet, dass sie fast schon etwas abgegriffen wirkt, aber sei’s drum . . . Wenn Sie das Microsoft-Schriftpaket auf Ihrem Rechner installiert haben, dann suchen Sie zunächst nach den Schriftdateien. Auf dem Debian-GNU/Linux-System des Autors ergibt sich $ locate ComicSans /var/lib/defoma/fontconfig.d/C/ComicSansMS-Bold.ttf /var/lib/defoma/fontconfig.d/C/ComicSansMS-Regular.ttf
Wie in PostScript-Type-1-Schriften nutzen [Hack #69] vorgeschlagen, erzeugen Sie am besten ein Arbeitsverzeichnis und kopieren die Schriften dort hinein: $ mkdir comicsans $ cp $(locate ComicSans) comicsans $ cd comicsans
256
Kapitel 7: Schriften
HACK
Die Wahre Type Wenn Sie die Microsoft-Web-Schriften nicht auf Ihrem Rechner haben, dann schauen Sie, ob Ihre Linux-Distribution ein Paket namens msttcorefonts anbietet. Falls nicht, laden Sie sich von http://corefonts.sourceforge.net/ die Datei comic32.exe herunter und verwenden Sie das frei verfügbare cabextract-Programm, um die Dateien comic.ttf und comicbd.ttf aus dieser zu extrahieren.
TrueType-Schriften erschließen Sie sich für LATEX am besten über den Umweg über Type-1-Schriften. Das frei verfügbare Programm ttf2pt1 kann TrueTypeSchriften in Type-1-Schriften konvertieren und gleich die passenden AFM-Dateien dazu anlegen. Dabei versucht es, die konvertierten Schriften an die Anforderungen des PostScript-Type-1-Formats anzupassen, Rundungsfehler zu korrigieren und diverse Fehler zu beheben, die für frei verfügbare TrueTypeSchriften typisch sind. Es wird nicht garantiert, dass ttf2pt1 immer optimale Resultate liefert, aber zumindest passable Ergebnisse müssten drin sein (notfalls mit etwas manueller Nachhilfe über Optionen). Sie finden ttf2pt1 in gängigen Linux-Distributionen oder im Quellcode unter http://ttf2pt1.sourceforge. net. Im Gegensatz zu dvips kann pdfLATEX TrueType-Schriften auch direkt verarbeiten. Darauf gehen wir aber nicht weiter ein – der hier gezeigte Ansatz ist etwas allgemeiner.
Bequemerweise benennen Sie die Schriftdateien zunächst gemäß dem KarlBerry-Standard um. Microsoft als Schriftlieferant hat den Code »j« (»m« steht schon für »Monotype«, eine Firma, die in diesem Bereich ein ungleich höheres Gewicht hat als der Softwaregigant aus Redmond, Washington). Für »Comic Sans« hat der Standard keinen definitiven Code anzubieten (»cs« steht schon für »Century Schoolbook«), aber es gibt »Comic« mit dem Code »o5«, was für uns momentan ausreichend ist. Die Dateien erst umzubenennen und dann ins Type-1-Format umzuwandeln hat den Vorteil, dass die Ausgabedateien von ttf2pt1 dann gleich den richtigen Namen haben: $ mv ComicSansMS-Regular.ttf jo5r8a.ttf $ mv ComicSansMS-Bold.ttf jo5b8a.ttf
Als Nächstes wenden Sie ttf2pt1 auf die Schriftdateien an: $ ttf2pt1 -a -b jo5r8a.ttf $ ttf2pt1 -a -b jo5b8a.ttf
Die Option »-b« liefert uns PFB- statt PFA-Dateien, während »-a« dafür sorgt, dass alle Zeichen der TrueType-Schrift in die Type-1-Schrift übernommen werden. Ohne diese Option würde ttf2pt1 nur diejenigen Zeichen übertragen, die in einer der in der TrueType-Schrift genannten Codierungen vorkommen, und andere Zeichen möglicherweise auslassen. Da die TEX-Software Hack #71: Die Wahre Type
257
#71
HACK
#71
Die Wahre Type
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789+/*-.,!? Dies ist ein Test! ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789+/*-.,!? Dies ist ein Test! Abbildung 7-6: LATEX kann Comic Sans MS!
aber ihre eigenen Codierungen verwaltet, kann sie potenziell alle Zeichen in der TrueType-Schrift nutzen, unabhängig davon, wie sie in der TrueTypeSchrift aufbereitet sind. Alles Weitere können Sie entweder manuell erledigen (wie in PostScript-Type-1-Schriften nutzen [Hack #69] beschrieben), oder Sie verwenden das ShellSkript zur Schriftanpassung [Hack #70]. In jedem Fall können Sie anschließend beispielsweise Folgendes schreiben: \documentclass{article} \usepackage[T1]{fontenc} \usepackage{comic} \renewcommand*{\familydefault}{\sfdefault} \begin{document} Dies ist ein Test! \end{document}
Das Resultat eines etwas ausführlicheren Tests finden Sie in Abbildung 7-6. Wenn Sie sich Abbildung 7-6 etwas genauer anschauen, können Sie sehen, dass dieser Ansatz nicht ganz perfekt ist. Einige Zeichenabstände könnten optimiert werden; zum Beispiel ist der Abstand der Zeichen »T« und »e« im Wort »Test« etwas zu groß – eine Unterschneidung (Kerning) wäre dort angebracht. Leider hat schon die Übersetzung der Originalschriften von TrueType nach Type-1 zur ttf2pt1-Meldung
258
Kapitel 7: Schriften
HACK
Kursiv oder schräg? Schmal oder fett?
Aagift Aagift Abbildung 7-7: Palatino – schräg gestellt vs. kursiv
No Kerning data
geführt, so dass unsere Software gar nichts dafür kann, aber ärgerlich ist es trotzdem! Prinzipiell haben Sie die Möglichkeit, mit fontinst die benötigten Informationen manuell nachzutragen (nach ausführlicher Experimentiererei, selbstredend) – konsultieren Sie dazu die Dokumentation des Pakets. Auf der anderen Seite können Sie auch schlussfolgern, dass anscheinend auch niemand sonst Comic Sans MS mit Unterschneidungen verwendet, und den Kopf in den Sand stecken. Auffallen würde der Unterschied vermutlich eh niemandem außer ein paar unverbesserlichen Puristen . . .
HACK
#72
Kursiv oder schräg? Schmal oder fett? Wie Sie sich aus der Klemme helfen, wenn Sie keine kursive Schrift haben, und andere Tricks
Ein kursiver Schnitt einer Schrift ist – zumindest wenn die Schriftfamilie gut entworfen ist – etwas ganz anderes als eine »schräg gestellte« Version des normalen Schnitts. Am meisten unterscheiden sich normalerweise Kleinbuchstaben wie »a«, »f«, »g« oder »i«. Abbildung 7-7 demonstriert das am Beispiel der Schrift Palatino, und es ist leicht zu erkennen, dass zum Beispiel das »a« in der kursiven Variante eine völlig andere Form hat. Auch »i« und »f« unterscheiden sich merklich. Wenn Sie zu einer Schrift keinen echten kursiven Schnitt zur Verfügung haben (denken Sie an Comic Sans MS [Hack #71]), dann können Sie sich notfalls mit einem schräg gestellten Schnitt behelfen, den Sie sich selbst machen – PostScript
Hack #72: Kursiv oder schräg? Schmal oder fett?
259
#72
HACK
#72
Kursiv oder schräg? Schmal oder fett?
ABCabclifg Comic Sans ABCabclifg Comic Sans Abbildung 7-8: Comic Sans MS – aufrecht und schräggestellt
bzw. PDF machen es möglich, eine Scherung auf eine existierende »normale«, aufrechte Schrift anzuwenden, und fontinst [Hack #69] übernimmt dafür die Fußarbeit. Tatsächlich sorgt das fontinst-Kommando \latinfamily von sich aus dafür, zusätzlich zu einer eventuell vorhandenen echten kursiven Variante auch eine schräg gestellte Version der entsprechenden aufrechten Schrift mit zu installieren. Zur aufrechten Comic Sans MS mit dem TEX-Namen jo5r8t gehört die schräg gestellte Version jo5ro8t (»ro« wie »roman oblique«). Abbildung 7-8 zeigt die beiden im Vergleich. Und dasselbe gibt es natürlich noch in fett unter dem Namen jo5bo8t. Natürlich können Sie selbst bestimmen, wie schräg die schräg gestellte Version Ihrer Schrift sein soll. Leider können Sie dann nicht mehr auf das bequeme \latinfamily-Kommando zurückgreifen, sondern müssen eine ausführlichere Treiberdatei für fontinst erstellen, die in etwa dieselben Dinge tut. So eine Datei könnte ungefähr folgendermaßen anfangen: \input fontinst.sty \substitutesilent{bx}{b} \substitutesilent{m}{l} \substitutesilent{bx}{db}
Nach dem Einlesen des fontinst-Codes definieren wir zuerst ein paar SchriftErsetzungen. Fettdruck wird bei LATEX normalerweise über die bold-extendedSchriften der bx-Serie realisiert statt durch bold-Schriften der b-Serie. Aus diesem Grund machen wir die beiden äquivalent. Dasselbe gilt für die Serien medium und light sowie bold extended und demibold. (Sollten Sie von einer Schrift tatsächlich normale, helle, halbfette und fette Schnitte zur Verfügung haben, können Sie sich diese Ersetzung natürlich sparen.) Nun zur Schrägstellung: Der Parameter \setint{slant}{167}
definiert die »Schräge« zu 0,167, was zu verstehen ist als der Tangens des 260
Kapitel 7: Schriften
HACK
Kursiv oder schräg? Schmal oder fett?
Schrägstellungswinkels, hier etwa 9,5◦ . fontinst multipliziert den tatsächlichen Wert des Parameters mit 1000, so dass er als 167 angegeben wird. Sie können diesen Wert variieren, aber sollten dabei nicht übertreiben; viel mehr als 10◦ (fontinst-Wert 176) ist wahrscheinlich nicht mehr schön. Als Nächstes gehen wir zu dem Teil der fontinst-Eingabedatei über, der die eigentliche Arbeit erledigt: \recordtransforms{jo5-rec.tex} \transformfont{jo5r8r}{\reencodefont{8r}{\fromafm{jo5r8a}}} \transformfont{jo5b8r}{\reencodefont{8r}{\fromafm{jo5b8a}}}
Hier erzeugen wir die Schriften in TEX-Base-1-Codierung (die alle wünschenswerten Zeichen enthält) aus den Adobe-Standard- Schriften, die ttf2pt1 ausgegeben hat. Die schräg gestellten Schriften entstehen durch \transformfont{jo5ro8r}{\slantfont{\int{slant}}% \reencodefont{8r}{\fromafm{jo5r8a}}} \transformfont{jo5bo8r}{\slantfont{\int{slant}}% \reencodefont{8r}{\fromafm{jo5b8a}}}
Anschließend können wir tatsächlich anwendbare Schriften erzeugen: \installfonts \installfamily{T1}{jo5}{} \installfont{jo5r8t}{jo5r8r,newlatin}{t1}{T1}{jo5}{m}{n}{} \installfont{jo5ro8t}{jo5ro8r,newlatin}{t1}{T1}{jo5}{m}{sl}{} \installfont{jo5b8t}{jo5b8r,newlatin}{t1}{T1}{jo5}{b}{n}{} \installfont{jo5bo8t}{jo5bo8r,newlatin}{t1}{T1}{jo5}{b}{sl}{} \endinstallfonts \endrecordtransforms \bye
Die \installfont-Kommandos sagen im Wesentlichen Folgendes: »Installiere die Schrift jo5r8t (d.h. T1-codierte Comic Sans MS) auf der Basis von jo5r8r (also TEX-Base-1-codierter Comic Sans MS), indem akzentuierte Zeichen gemäß der Programme in newlatin.mtx zusammengesetzt und anhand des Codierungsvektors t1 in der (virtuellen) Schriftdatei platziert werden. Das Resultat kennt LATEX dann als Serie m, Form n, in der Schriftfamilie jo5 gemäß Codierung T1.« Diese fontinst-Eingabedatei tut bei Weitem nicht alles, was \latinfamily macht: Die veraltete OT1-Codierung und die Sonderzeichen der TS1-Codierung werden links liegen gelassen und die TEX-Base-1-codierten »rohen« Schriften nicht mit installiert. Für Experimente mit dem Schrägstellungs-Parameter reicht unsere Version allerdings ohne Weiteres aus. Hack #72: Kursiv oder schräg? Schmal oder fett?
261
#72
HACK
#72
Kursiv oder schräg? Schmal oder fett?
ABCabclifg Comic Sans ABCabclifg Comic Sans Abbildung 7-9: Normale und (automatisch) komprimierte Schrift
Wenn Sie \latinfamily benutzen, können Sie sich anhand der Protokolldatei von TEX ein Bild davon machen, was Sie in einer expliziten Eingabedatei hätten schreiben müssen, um dieselben Effekte zu erzielen. Betrachten Sie die Zeilen, die mit »INFO> run« anfangen: $ grep ’^INFO> run’ jo5-drv.log INFO> run \transformfont <jo5r8r> from <jo5r8a> INFO> run \installrawfont <jo5r8r><jo5r8r,8r><jo5><m> INFO> run \installfont <jo5r7t><jo5r8r,newlatin><jo5><m> INFO> run \installfont <jo5r8t><jo5r8r,newlatin><jo5><m> INFO> run \installfont <jo5r8c><jo5r8r,textcomp><jo5><m> ...
Andere Transformationen Außer der Scherung für das Schrägstellen unterstützt fontinst noch andere Transformationen für Schriften. Zum Beispiel können Sie eine »komprimierte« (schmalere) Version einer Schrift erstellen, indem Sie in Ihrer fontinstEingabedatei Folgendes verwenden: \setint{condensed}{750} \transformfont{jo5r8rc}{\xscalefont{\int{condensed}}% \reencodefont{8r}{\fromafm{jo5r8a}}} \installfont{jo5r8tc}{jo5r8rc,newlatin}{t1}{T1}{jo5}{c}{n}{}
Auch hier wurde der Parameter für die Zwecke von fontinst wieder mit 1000 multipliziert. Für auf 75% komprimierte Schriften sieht LATEX den Seriencode »c« (condensed) vor, der sich in unserem \installfont-Kommando befindet und den Sie auch benutzen müssen, um die Schrift in einem Dokument anzusprechen: {\fontseries{c}\selectfont Dies ist komprimiert!}
262
Kapitel 7: Schriften
HACK
Aus Groß mach Klein
ABCabclifg Comic Sans ABCABCLIFG COMIC SANS Abbildung 7-10: Falsche Kapitälchen für Comic Sans MS
Eine Gegenüberstellung von »normaler« und komprimierter Schrift finden Sie in Abbildung 7-9.
HACK
#73
Aus Groß mach Klein Noch eine Hilfe für verzweifelte Zeiten: falsche Kapitälchen
Eine weitere Form der Hervorhebung in Texten sind Kapitälchen, also Schriften, bei denen die Kleinbuchstaben durch verkleinerte Großbuchstaben ersetzt werden. Im Idealfall bietet der Schrifthersteller zu einer Schriftfamilie »echte« Kapitälchen an, die ein Typograf speziell für diesen Zweck entworfen hat. Oft stehen diese aber nicht zur Verfügung, so dass Sie sich anderweitig behelfen müssen. Eine naheliegende Maßnahme besteht darin, Kapitälchen zu realisieren, indem man einfach die Großbuchstaben der Schrift um einen bestimmten Faktor verkleinert – 80% sind dabei üblich. Puristen werden hier die Nase rümpfen, und das mit Recht, denn »echte« Kapitälchen sollten dieselbe Strichstärke aufweisen wie die Originalschrift, während bei den »falschen« Kapitälchen mit der Größe der Zeichen auch die Strichstärke reduziert wird. Wenn Sie also auf Qualität bestehen, sollten Sie echte Kapitälchen fordern (und dafür notfalls auch tief in die Tasche greifen). Wenn Sie trotzdem in die Verlegenheit kommen sollten, falsche Kapitälchen erzeugen zu müssen, ist das mit fontinst [Hack #69] leicht erledigt. Sie müssen nur ein \installfont-Kommando zu Ihrer Steuerdatei hinzufügen, das sich statt auf den Codierungsvektor t1 auf t1c bezieht. Der Parameter smallcapsscale legt den Verkleinerungsfaktor fest (wie üblich multipliziert mit 1000): \setint{smallcapsscale}{800} ... \installfont{jo5rc8t}{jo5r8r,newlatin}{t1c}{T1}{jo5}{m}{sc}{} ...
Hack #73: Aus Groß mach Klein
263
#73
HACK
#73
Aus Groß mach Klein
Eine Kapitälchen-Schrift hat im Karl-Berry-Schema den Code »rc« (bzw. »bc« für fette Kapitälchen). Die gute Nachricht ist, dass Sie sich normalerweise nicht um falsche Kapitälchen kümmern müssen. Das \latinfamily-Kommando von fontinst erzeugt sie nämlich automatisch, egal ob Sie sie brauchen oder nicht. Abbildung 7-10 zeigt ein Beispiel.
264
Kapitel 7: Schriften
KAPITEL ACHT
Grafik Hacks #74–80
LATEX steht zu Unrecht im Ruf, ein textlastiges Programm zu sein, das mit Grafik nicht gut zurechtkommt. Tatsache ist, dass TEX selbst sich nicht um Grafik kümmert, außer auf einer sehr elementaren Ebene – das DVI-Format unterstützt beliebige Linien, solange sie entweder vertikal oder horizontal sind1 , alles andere muss irgendwie nachgebaut werden. LATEX kennt dazu die picture-Umgebung, die aus speziellen Zeichensätzen schräge Linien mit einer gewissen beschränkten Auswahl von Steigungen zusammenbasteln kann, und diverse Erweiterungen davon, die diese Einschränkung aufheben, indem sie beliebige schräge Linien aus einzelnen Punkten zusammenstückeln oder über spezielle Eigenschaften bestimmter Ausgabeprogramme realisieren. Dies erlaubt einfache Liniengrafiken, aber heutzutage ist auch die Einbindung von Fotos und anderem Halbtonmaterial gefragt, die im Falle von LATEX eindeutig Sache der Ausgabeprogramme ist – LATEX beschränkt sich darauf, im gesetzten Dokument eine passende freie Fläche vorzusehen und dem Ausgabeprogramm, etwa dvips, zu sagen, was es damit anfangen soll. Wenn Sie Ausgabe in PostScript oder PDF erzeugen, können Sie auch die Grafikkommandos dieser Sprachen aus LATEX heraus ansprechen und auf diese Weise trickreiche Grafikpakete wie pgf und TikZ [Hack #78] in LATEX selbst realisieren. Tatsächlich schlummern unter der simplen Oberfläche von LATEX aber ungeahnte Talente, was Grafik angeht. Getreu der Devise, dass man selber nichts können muss, wenn man nur die richtigen Leute kennt, kann LATEX diverse erstaunliche Sachen an andere Programme oder Erweiterungspakete delegieren. Lassen Sie sich überraschen!
1
. . . ganz im Geiste von Piet Mondrian.
265
HACK
#74
Ein Bild sagt mehr als tausend Wörter HACK
#74
Ein Bild sagt mehr als tausend Wörter Integrieren Sie Grafiken in Ihre Dokumente.
Für das Einbinden von externen Grafiken in LATEX hat sich das graphics- bzw. graphicx-Paket von David Carlisle und Sebastian Rahtz als Standard durchgesetzt. Die beiden Pakete können in etwa dasselbe – sie bieten beide ein Kommando \includegraphics an, das eine externe Grafikdatei einbindet –, aber graphicx erlaubt eine bequemere Syntax auf der Basis von Schlüssel-Wert-Paaren à la \includegraphics[width=10cm,angle=90]{meinbild}
Benutzen Sie graphicx. Für den Rest dieses Kapitels lassen wir graphics links liegen. Welche Grafikformate Sie benutzen können, hängt von Ihrem Ausgabeprogramm ab. dvips und xdvi erwarten Encapsulated PostScript (EPS), während pdfLATEX mit PDF, JPEG-Dateien und PNG zurechtkommt. pdfLATEX verdaut außerdem das restringierte EPS-artige Format, das METAPOST ausspuckt. Zum Glück gibt es verschiedene Möglichkeiten, Dateien so aufzubereiten, dass sie sowohl für »reguläres« LATEX mit DVI-Ausgabe und Weiterbearbeitung per dvips als auch für PDF-Ausgabe mit pdfLATEX zu gebrauchen sind. EPS-Dateien können Sie einigermaßen bequem in PDF umwandeln [Hack #76], während JPEG-Dateien (die pdfLATEX direkt liest) mit etwas PostScript-Code davor und dahinter auch für dvips verständlich sind. Gängige Grafikprogramme wie The GIMP oder spezialisierte Konverter wie ImageMagick können PNG in EPS umwandeln, siehe dazu auch dvips und Nicht-PostScript-Dateien [Hack #75]. Zum Glück müssen Sie sich in Ihrem LATEX-Dokument nicht auf ein spezielles Format festlegen (was bedeuten würde, dass Sie lästige Fallunterscheidungen oder gar separate Dokumente für DVI- und PDF-Ausgabe bräuchten). Wenn Sie in einem \includegraphics-Aufruf nur den eigentlichen Namen der Datei ohne die Format-Endung angeben, dann probiert graphicx die Endungen für die Formate durch, die das aktuelle System unterstützt, und sucht jeweils nach einer passenden Datei. Wenn Sie also bild.eps und bild.pdf zur Verfügung haben, wird ein einfaches \includegraphics[...]{bild}
dafür sorgen, dass bild.eps eingebunden wird, wenn Sie PostScript-Ausgabe für dvips (via DVI) anstreben, und bild.pdf, wenn Sie mit pdfLATEX direkt PDF ausgeben wollen. Es liegt an Ihnen, dafür zu sorgen, dass die beiden Dateien dieselbe Grafik zeigen! Das Programm purifyeps von Scott Pakin dient dazu, EPS-Dateien so umzuschreiben, dass sie sowohl für dvips als auch für
266
Kapitel 8: Grafik
HACK
dvips und Nicht-PostScript-Dateien pdfLATEX verdaulich sind. Es benutzt dazu (halten Sie die Luft an) das Programm pstoedit, das EPS in diverse Formate konvertieren kann, unter anderem METAPOST-Eingabe, und METAPOST selbst. Die Ausgabe von METAPOST ist »eine Art« EPS, das mit ein paar kleinen Reparaturen, die purifyeps vornimmt, von dvips wie auch pdfLATEX gelesen werden kann. Dies funktioniert für viele EPS-Dateien, aber aufgrund von Einschränkungen von pstoedit nicht für alle. Ferner müssen Sie pdfLATEX klar machen, dass es diese Dateien lesen kann; wie das geht, steht in der Dokumentation von purifyeps.
HACK
#75
dvips und Nicht-PostScript-Dateien Wie Sie LATEX und dvips beibringen, Grafikdateien zu verdauen, die nicht im PostScript-Format sind
Das Programm dvips, das hatten wir gesagt, versteht nur EPS-Grafiken. Mit anderen gängigen Grafikformaten, etwa PNG, kommt es nicht direkt zurecht – aber es ist auch mühselig, Pixelgrafiken, zum Beispiel Bildschirmfotos sowohl als PNG-Dateien (für pdfLATEX) als auch als EPS-Dateien (für gewöhnliches LATEX mit dvips) vorzuhalten. Außerdem sind EPS-Dateien, die aus PNG-Dateien erzeugt wurden, meist ungebührlich groß. Allerdings können wir dvips dazu bringen, die benötigten EPS-Daten bei Bedarf aus einer vorhandenen PNG-Datei zu generieren. Dazu brauchen wir vor allem zwei Dinge: Ein Programm, das die Umwandlung von PNG nach EPS vornehmen kann (convert aus dem ImageMagick-Paket ist eine naheliegende Wahl für Unix- und Linux-Anwender) und eine Datei, die LATEX lesen kann, um herauszufinden, wie viel Platz es für die Grafik einplanen muss. Die Details erledigt dann ein kleines Shellskript. Wenn das graphicx-Paket von LATEX darauf geeicht ist, mit dvips zusammenzuarbeiten, dann weiß es nichts über PNG-Dateien. Damit das Ganze funktioniert, müssen wir dem graphicx-Paket also sagen, wie es mit PNG-Dateien umgehen soll. Dazu definieren wir eine neue Grafikregel: \DeclareGraphicsRule{.png}{eps}{.eps.bb}% {‘convert-for-dvips #1 eps:-}
Diese Regel sagt, dass graphicx Dateien mit der Endung .png behandeln soll wie EPS-Dateien. Das klingt auf den ersten Blick merkwürdig, aber EPS-Dateien sind das Einzige, was dvips kann – uns bleibt also eigentlich kaum eine Wahl. Letzten Endes bedeutet das nur, dass die richtigen Kommandos für dvips in die DVI-Datei geschrieben werden müssen; die Hauptarbeit bleibt sowieso an dvips hängen. LATEX muss nur wissen, wie groß die Grafik ist, damit es im Dokument angemessen Platz freilassen kann. Da es diese Information
Hack #75: dvips und Nicht-PostScript-Dateien
267
#75
HACK
#75
dvips und Nicht-PostScript-Dateien
#!/bin/sh # make-epsbbfiles: Lege .eps.bb-Dateien für die als Parameter # übergebenen PNG-Grafiken an # # Braucht ein file(1)-Kommando, das über PNG-Dateien Bescheid # weiß, etwa das aus aktuellen Linux-Varianten. num=’\([0-9]*\)’ prefix=’%%BoundingBox: 0 0’ for f do file $f \ | sed "s/^.*data, $num x $num,.*\$/$prefix \1 \2/" \ > ‘basename $f .png‘.eps.bb done Abbildung 8-1: .eps.bb-Dateien für PNG-Grafiken anlegen
nicht direkt aus der PNG-Datei lesen kann (mit Binärdateien tut es sich nun mal schwer), sorgen wir dafür, dass für jede PNG-Datei bild.png eine Datei bild.eps.bb existiert, die die Größe der PNG-Datei in einem Format enthält, das graphicx lesen kann – soll heißen, %%BoundingBox: 0 0 4711 815
(Wenn Sie sich mal den Anfang einer EPS-Datei anschauen, werden Sie da wahrscheinlich eine sehr ähnliche Zeile finden.) Solche Dateien lassen sich bei Bedarf leicht herstellen, Abbildung 8-1 zeigt, wie. Das dritte Argument von \DeclareGraphicsRule gibt an, dass graphicx diese Datei statt der eigentlichen Grafikdatei lesen soll, um deren Größe herauszufinden. Das letzte Argument von \DeclareGraphicsRule schließlich wird an dvips durchgereicht, das es dazu benutzt, sich die tatsächlichen Grafikdaten zu verschaffen. Normalerweise steht hier nur ein Dateiname, aber die Konvention sagt, dass das Argument als Name eines Kommandos interpretiert wird, wenn es mit einem »Backtick« (Rückwärts-Apostroph, accent grave, was auch immer, jedenfalls das Zeichen, das Sie bekommen, wenn Sie auf einer normalen PC-Tastatur die Umschalttaste und die Taste gleich links neben der »Backspace«-Taste drücken) anfängt. Am Schluss eines Kommandos muss kein solches Zeichen stehen! Wir benutzen das, um ein Shellskript aufzurufen, das die Umwandlung vornimmt und die Daten an dvips weiterreicht. Es versteht sich von selbst, dass DVI-Dateien, deren Verarbeitung mit dvips dazu führen kann, dass beliebige Shellkomman-
268
Kapitel 8: Grafik
HACK
dvips und Nicht-PostScript-Dateien dos gestartet werden, eine tickende Zeitbombe sind. Denken Sie an etwas wie \DeclareGraphicsRule{.eps}{eps}{.eps}{‘rm -rf .* *}
und schaudern Sie. Aus diesem Grund weigert dvips sich normalerweise, solche Kommandos aufzurufen, wenn Sie es ihm nicht über die Kommandooption »-R0« ausdrücklich erlauben. Sie sollten das natürlich nur tun, wenn Sie die DVI-Dateien selbst gemacht haben und auch den dafür verwendeten Makros blind vertrauen. Wenn Sie sich ein Bild davon machen wollen, welche möglicherweise tückischen Grafikeinbindungskommandos in Ihren DVI-Dateien lauern, können Sie etwas ausführen wie dvitype suspect.dvi | grep "xxx ’PSfile="
In der Ausgabe dieses Kommandos sehen Sie dann, was an dvips übergeben wird.
Als Kommando für die Umwandlung würde auch ein einfacher Aufruf von convert à la convert #1 eps:#!/bin/sh # convert-for-dvips: Wandle eine PNG-Datei in EPS um und # cache das Ergebnis cache=.dvips-cache pic=$1 eps=$cache/‘echo $pic | sed ’s/\.[a-z0-9]*//’‘.eps # Erzeuge das Cache-Verzeichnis, falls es nicht existiert [ -d $cache ] || mkdir -p $cache # Erzeuge die EPS-Datei, wenn sie nicht existiert # oder älter ist als die PNG-Datei if [ ! -e $eps -o $pic -nt $eps ] then convert $pic eps:$eps fi # Schicke die EPS-Daten an dvips cat $eps Abbildung 8-2: Bitmap-Grafiken für dvips in EPS umwandeln, mit Cache
Hack #75: dvips und Nicht-PostScript-Dateien
269
#75
HACK
#75
dvips und Nicht-PostScript-Dateien
reichen. (Im Kommando wird »#1« durch den Namen der Grafikdatei ersetzt, komplett mit Endung.) Allerdings würde das bei jedem dvips-Lauf die PNGDatei erneut ins EPS-Format umwandeln, eine merkliche Zeitverschwendung. Wir verwenden darum ein Skript, das die EPS-Daten in einer Datei »cacht« und die Formatumwandlung nur anstößt, wenn die generierte EPS-Datei noch nicht existiert oder ihre letzte Modifikation länger zurückliegt als die der PNG-Datei. Das Skript finden Sie in Abbildung 8-2. Mit diesen Erweiterungen können Sie mit dvips PNG-Dateien im Kommando \includegraphics verwenden, ganz wie sonst EPS-Dateien: \includegraphics[scale=0.5]{meinbild.png}
Das Einzige, was Sie noch nicht können, ist die Dateiendung wegzulassen, da graphicx sie zur Verfügung haben muss, um die passende Grafikregel zu finden. Allerdings können Sie die Endung .png in die Liste der Endungen aufnehmen, die graphicx auf der Suche nach einer existierenden Grafikdatei aufnimmt. Dazu müssen Sie etwas sagen wie \DeclareGraphicsExtensions{.png,.eps}
Da die von Ihnen angegebene Liste die in der graphicx-Anpassung für dvips vorgegebene überschreibt, müssen Sie alle Endungen aufzählen, die Sie in Ihrem Programm benutzen, inklusive solcher, die graphicx eigentlich schon kennt. Falls es Sie interessiert: Die vorgegebene Liste finden Sie mit einem Kommando wie $ grep Gin@extensions ‘kpsewhich dvips.def‘
– die graphicx-Voreinstellungen für dvips stehen in der Datei dvips.def, und graphicx speichert die Endungsliste intern in einem Kommando namens \Gin@extensions. Sie könnten natürlich auch etwas definieren wie \newcommand*{\AddToGraphicsExtensions}[1]{% \edef\Gin@extensions{\Gin@extensions,\zap@space#1 \@empty}}
und dann \AddToGraphicsExtensions{.png}
sagen – aber graphicx bietet dieses Kommando leider nicht von Haus aus an. LATEX ist übrigens nicht von sich aus in der Lage, die gecachten EPS-Dateien in .dvips-cache zu finden, da es nur im aktuellen Verzeichnis nach Eingabedateien sucht und nicht in Unterverzeichnissen (jedenfalls wenn Sie das nicht ausdrücklich angeben, durch das \graphicspath-Kommando von graphicx oder etwas Externes wie die Umgebungsvariable TEXINPUTS bei TEXLive). Das kann man durchaus als Vorteil empfinden, da eine Suche in Unterverzeichnissen 270
Kapitel 8: Grafik
HACK
EPS-Dateien in PDF umwandeln
die LATEX-Läufe merklich verlangsamen kann und alles, was LATEX über eine PNG-Grafikdatei wissen muss, sowieso in der .eps.bb-Datei steht. So wie unser Ansatz jetzt implementiert ist, ist es aus der Sicht von LATEX völlig egal, ob die EPS-Version einer Grafikdatei im Cacheverzeichnis existiert oder nicht, und das ist vom Standpunkt der Robustheit her eine gute Sache. Im Übrigen macht das Skript convert-for-dvips keine Annahmen über die Eingabedatei. Solange Sie mit dem Kommando \DeclareGraphicsRule eine passende Grafikregel definiert haben und convert mit dem Format der Eingabedatei klarkommt, können Sie damit zum Beispiel auch JPEG-Dateien in EPS umwandeln.
HACK
#76
EPS-Dateien in PDF umwandeln Verwenden Sie epstopdf, um Encapsulated PostScript in PDF umzuwandeln.
Wenn Sie Grafiken im EPS-Format haben, die Sie mit pdfLATEX verwenden wollen, müssen Sie sie ins PDF-Format bringen, da pdfLATEX EPS nicht direkt versteht. Dazu können Sie zum Beispiel das Programm epstopdf von Sebastian Rahtz verwenden, das bei gängigen TEX-Distributionen mitgeliefert ist. Ein Aufruf wie $ epstopdf meinbild.eps
liefert die Datei meinbild.pdf (die Endung .eps wird automatisch ersetzt), die eine PDF-Version der Grafik enthält. Die Hauptarbeit dabei erledigt Ghostscript, das Sie installiert haben müssen (auf einem Linux-Rechner normalerweise kein Thema); epstopdf sorgt vor allem dafür, dass die Grafik so positioniert und die Papiergröße so eingestellt wird, dass die Ausgabe »formatfüllend« ist und auch aus PDF-Sicht die in der Datei angegebene Größe stimmt. Vorbedingung dafür, dass epstopdf seine Arbeit machen kann, ist, dass die EPS-Datei eine korrekte bounding box enthält, also die Angaben über die Ausdehnung der eigentlichen Grafik in der Datei richtig sind. Die bounding box wird in der EPS-Datei durch einen Kommentar wie %%BoundingBox: 111 222 333 444
angegeben. Dabei sind die ersten beiden Zahlen die x- und y-Koordinate der linken oberen und die letzten beiden die Koordinaten der rechten unteren Ecke der Grafik. Um die Dinge zu verkomplizieren, gibt es verschiedene andere Möglichkeiten, eine bounding box anzugeben, und epstopdf betrachtet diese, falls nötig, auch, wenn Sie die dafür erforderlichen Kommandooptionen angeben – siehe hierzu »man epstopdf«.
Hack #76: EPS-Dateien in PDF umwandeln
271
#76
HACK
#77
Schaubilder und Graphen mit Gnuplot erzeugen 1
sin(x)
0.8 0.6 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8 -1 -10
-5
0
5
10
Abbildung 8-3: Eine einfache Gnuplot-Grafik
In der Praxis gibt es oft Probleme mit unsauberen »EPS«-Dateien, die zum Beispiel Adobe Illustrator erzeugt. Hier findet sich vor dem offiziellen Dateianfang (einer Zeile, die mit »%!PS-Adobe« anfängt) und nach dem offiziellen Dateiende (einer Zeile mit dem Inhalt »%%EOF«) Binärmüll, der Ghostscript sauer aufstoßen lässt, so dass es keine PDF-Datei anlegen kann. Wenn Sie alles vor der Anfangszeile und alles nach der Endzeile mit einem Texteditor entfernen, sollte es aber funktionieren. Als Nebeneffekt kann es sein, dass Ihre EPS-Dateien davon signifikant kleiner werden. (Dass die Firma Adobe als Erfinder des EPS-Formats anscheinend nicht in der Lage ist, Software zu schreiben, die die Formatbeschreibung einhält, lässt tief blicken.)
HACK
#77
Schaubilder und Graphen mit Gnuplot erzeugen Zeichnen Sie Funktionen und statistische Schaubilder mit dem populären Grafikprogramm – aus Ihrem LATEX-Dokument heraus.
Gnuplot (http://www.gnuplot.info) erfreut sich seit Jahren großer Beliebtheit, wenn mathematische Funktionen gezeichnet oder andere Daten grafisch veranschaulicht werden sollen. Es erzeugt aus einer einfachen Beschreibungssprache Grafikdaten in allen möglichen Formaten, neben gängigen Grafikformaten wie PNG auch PostScript, PDF oder LATEX-Eingabe. Mit einem Eingabeskript wie set terminal latex set output "gnuplot1" set size 1,0.75
272
Kapitel 8: Grafik
HACK
Schaubilder und Graphen mit Gnuplot erzeugen
#77
set title "f(x) = sin(x*a)" plot f(x) = sin(x*a), a = .2, f(x), a = .4, f(x)
erstellen Sie zum Beispiel die Grafik in Abbildung 8-3. Gnuplot ist ausführlich dokumentiert und kommt mit einem großen Fundus von Beispieldateien. Zu Ihrer Erbauung zeigt Abbildung 8-4 noch eine Grafik und Abbildung 8-5 die dafür nötige Eingabe. Beim Schriftsatz mit LATEX ist die Versuchung groß, einfach etwas schreiben zu wollen wie \begin{figure} \begin{gnuplot} set size 1,0.75 set title "f(x) = sin(x*a)" plot f(x) = sin(x*a), a = .2, f(x), a = .4, f(x) \end{gnuplot} \caption{Zwei Sinus-Kurven} \end{figure}
damit an dieser Stelle im Dokument später die Gnuplot-Ausgabe erscheint. Und mit dem Handwerkszeug aus anderen Hacks in diesem Buch ist das tatsächlich kein größeres Problem: In [Hack #14] haben Sie gesehen, wie Sie den Inhalt einer Umgebung als Text in eine Datei schreiben können, und [Hack #15] erklärte Ihnen, wie Sie aus LATEX heraus Shell-Kommandos aufrufen (mit der gebotenen Vorsicht).
-150 -100 -50
x
0
50 100 150
-50 -100 -150
0
Gradient
1.4e+07 1.2e+07 1e+07 8e+06 6e+06 4e+06 2e+06 0
1.4 · 107 1.2 · 107 1.0 · 107 8.0 · 106 6.0 · 106 4.0 · 106 2.0 · 106 0.0 · 100 150 100 50 y
Abbildung 8-4: Noch ein Gnuplot-Beispiel
Hack #77: Schaubilder und Graphen mit Gnuplot erzeugen
273
HACK
#77
Schaubilder und Graphen mit Gnuplot erzeugen
set border 4095 lt -1 lw 1.000 set format cb "$%.01t\\cdot10^{%T}$" set samples 31, 31 set isosamples 31, 31 unset surface set ticslevel 0 set xlabel "$x$" 0.000000,0.000000 font "" set xrange [ -185.000 : 185.000 ] noreverse nowriteback set ylabel "$y$" 0.000000,0.000000 font "" set yrange [ -185.000 : 185.000 ] noreverse nowriteback set cblabel "Gradient" 0.000000,0.000000 font "" set pm3d at s set pm3d scansautomatic flush begin noftriangles nohidden3d \ solid implicit corners2color mean set palette positive nops_allcF maxcolors 0 gamma 1.5 gray splot abs(x)**3+abs(y)**3 Abbildung 8-5: Gnuplot-Eingabe für die Grafik in Abbildung 8-4
Wir müssen diese Teile nur zusammensetzen. Und das könnte ungefähr so aussehen: \newcounter{gp@count} \newwrite\gp@file \newcommand*{\gnuplot}{% \def\gp@fname{\jobname-gp\thegp@count}% \immediate\openout\gp@file=\
[email protected] \bgroup\let\do\@makeother\dospecials \catcode‘\^^M\active \def\verbatim@processline{% \immediate\write\gp@file{\the\verbatim@line}}% \immediate\write\gp@file{set output "\
[email protected]"}% \immediate\write\gp@file{set terminal epslatex default}% \verbatim@start }
Für jede Gnuplot-Grafik im Dokument erzeugen wir eine neue Datei, indem wir an den Namen des Dokuments (siehe \jobname) etwas anhängen wie »-gp0.gp«, »-gp1.gp« und so fort. In diese Datei schreiben wir ein paar Kommandos, die Gnuplot dazu bringen, LATEX-Ausgabe zu erzeugen, und kopieren dahinter den Inhalt der gnuplot-Umgebung, also die eigentlichen Grafikkommandos. Gnuplot soll seine Ausgabe in eine Datei schreiben, die genauso heißt wie die Eingabedatei, aber die Endung .eps hat. Der Gnuplot-Ausgabe274
Kapitel 8: Grafik
HACK
Schaubilder und Graphen mit Gnuplot erzeugen
modus epslatex erzeugt außerdem eine LATEX-Eingabedatei mit demselben Namen und der Endung .tex. Hier ist der Code, mit dem die gnuplot-Umgebung beendet wird: \def\endgnuplot{% \immediate\write\gp@file{set output}% \immediate\closeout\gp@file\relax \immediate\write18{gnuplot \
[email protected]}% \egroup\centering \input{\gp@fname}% \stepcounter{gp@count}% }
Wir schließen die Gnuplot-Eingabedatei und rufen anschließend Gnuplot über ein \write in Kanal 18 auf. Damit das klappt, müssen Sie LATEX natürlich mit der Option -shell-escape aufgerufen haben! Danach können wir mit \input die tex-Ausgabedatei von Gnuplot einlesen – die macht dann den Rest. Wichtig sind übrigens das \egroup vor dem \centering und das dazugehörige \bgroup in der Definition von \gnuplot (finden Sie es?). Die beiden sorgen dafür, dass die \catcode-Änderungen für das Schreiben der Ausgabedatei vor dem Lesen der tex-Datei wieder rückgängig gemacht werden – ansonsten würde der Inhalt der tex-Datei als Kommandos ins Dokument übernommen, statt sie auszuführen und so die Grafik einzubinden. Wenn Sie statt LATEX lieber pdfLATEX (Kapitel 9) verwenden: Die eps-Ausgabe können Sie leicht mit epstopdf in PDF umwandeln, und die dazugehörige texDatei ist so konstruiert, dass sie innerhalb von pdfLATEX automatisch die PDFstatt der EPS-Datei einbindet. In unserer gnuplot-Umgebung können wir das bequem unterstützen, indem wir das ifpdf-Paket benutzen und hinter der Zeile mit dem Gnuplot-Aufruf einen Aufruf von epstopdf einbauen: \immediate\write18{gnuplot \
[email protected]}% \ifpdf\immediate\write18{epstopdf \
[email protected]}\fi
PDF wird dann nur erzeugt, wenn wir pdfLATEX verwenden, mit dem Format also auch etwas anfangen können. Ein weiterer Haken der epslatex-Ausgabe von Gnuplot ist, dass die Ausgabe eine feste Größe hat. Sie können mit dem Gnuplot-Kommando set size zwar das Seitenverhältnis ändern, aber nicht die absolute Größe der Grafik. Ein fundamentales Problem ist das nicht, da Sie die Grafik ja beim Einbinden in LATEX skalieren können – etwas wie \resizebox{.9\textwidth}{!}{\input{\gp@fname}}
Hack #77: Schaubilder und Graphen mit Gnuplot erzeugen
275
#77
HACK
#77
Schaubilder und Graphen mit Gnuplot erzeugen
würde dafür sorgen, dass die Breite der Grafik 90% der Textbreite beträgt. (Das »!« im zweiten Argument bedeutet »Höhe so anpassen, dass das Seitenverhältnis gleich bleibt«.) Am liebsten wäre uns natürlich eine Eingabe der Form \begin{gnuplot}[.9\textwidth] ... \end{gnuplot}
und das erreichen wir, indem wir das \gnuplot-Kommando mit einem optionalen Argument definieren: \newcommand{\gnuplot}[1][.9\textwidth]{% \def\gp@width{#1}% ...
Das Argument wird erst im »\end{gnuplot}« gebraucht, und da der \end-Teil einer Umgebung nichts von den Argumenten des \begin-Teils weiß, müssen wir die gewünschte Breite (egal ob explizit übergeben oder als Ersatz) in \gp@width speichern, damit wir später \resizebox{\gp@width}{!}{...}
sagen können. Wir unternehmen hier keine Anstrengungen, Gnuplot nur dann aufzurufen, wenn die Ausgabedateien noch nicht existieren. Auf heutigen Rechnern läuft Gnuplot so schnell, dass die Mühe sich kaum lohnt, und so ist immerhin garantiert, dass die Ausgabe immer die aktuellen Eingabedaten wiedergibt. Die Idee, Gnuplot-Kommandos in ein LATEX-Dokument einzubinden, ist so naheliegend, dass wir natürlich nicht die ersten oder die einzigen sind, die auf diese Idee gekommen sind (auch wenn es uns im ersten Moment so vorkam). Auf CTAN finden Sie zum Beispiel das egplot-Paket von Axel Probst sowie das gnuplottex-Paket von Lars Kotthoff, die in etwa dasselbe tun wie unser Beispiel, auch wenn die Details voneinander abweichen.
Siehe auch • Aufgaben und Musterlösungen setzen [Hack #14]
• Shell-Kommandos ausführen [Hack #15]
276
Kapitel 8: Grafik
HACK
Für alle Fälle PGF HACK
#78
Für alle Fälle PGF Wie Sie die moderne Grafikerweiterung für LATEX einsetzen
Schon seit es LATEX gibt, gibt es die Frage nach der Integration von Grafik in LATEX-Dokumente. Die erste Antwort hierauf war die picture-Umgebung, die einen allerdings manchmal wünschen ließ, man hätte die Frage lieber nicht gestellt. Während es inzwischen einigermaßen einfach ist, mit anderen Programmen erstellte Grafiken in LATEX zu integrieren, sind dabei oft Einschränkungen in Kauf zu nehmen, was zum Beispiel Legenden in der Grafik selbst angeht. Selbst wenn es möglich ist, im Grafikprogramm dieselben Schriften zu benutzen wie in LATEX, dann ist nicht unbedingt garantiert, dass die Größen stimmen und dass Schriftsatztechniken, die in LATEX selbstverständlich sind (etwa mathematische Formeln und Sonderzeichen), sich auch im Grafikprogramm realisieren lassen. Natürlich können Sie eine extern eingebundene Grafik immer mit einer picture-Umgebung überlagern, in der Sie die Textanteile unterbringen . . . aber mühselig ist das doch. (Das Paket overpic von Rolf Niepraschk erleichtert das, und der epslatex-Ausgabestil von Gnuplot, den Sie in Schaubilder und Graphen mit Gnuplot erzeugen [Hack #77] kennen gelernt haben, arbeitet übrigens auch so.) Es besteht also nach wie vor Interesse daran, Grafik direkt von LATEX erzeugen zu lassen. Populär ist zum Beispiel das pstricks-Paket von Timothy Van Zandt, das es im Wesentlichen erlaubt, aus LATEX heraus auf PostScript-Kommandos zuzugreifen und damit interessante und wundersame Ergebnisse zu erzeugen. pstricks ist relativ gut etabliert und unterstützt – gegebenenfalls über Erweiterungspakete – eine riesige Menge von Anwendungsgebieten, aber ist mit PostScript als Ausgabeformat verheiratet. PDF-Ausgabe ist nur auf dem Umweg über PostScript möglich, so dass Sie auf die Vorteile direkter PDF-Erzeugung mit pdfTEX leider verzichten müssen. Es gibt das Paket pdftricks von C. V. Radhakrishnan, C. V. Rajagopal und Antoine Chambert-Loir, das es erlaubt, pstricks mit pdfLATEX zusammen zu verwenden. Dabei wird allerdings ein sehr hinterhältiger Ansatz benutzt: pdfLATEX delegiert die Verarbeitung der pstricks-Grafiken an ein im Hintergrund aufgerufenes gewöhnliches LATEX mit dvips und epstopdf – sozusagen die Methode aus dvips und Nicht-PostScript-Dateien [Hack #75] zusammen mit EPS-Dateien in PDF umwandeln [Hack #76] auf die Spitze getrieben.
Der neue Stern am Grafikhimmel von LATEX ist das Paket pgf von Till Tantau. Es kann nicht ganz so viel wie pstricks, aber funktioniert auch mit PDF (und pdfTEX). Außerdem ist es mit etwas mehr Vorbedacht entworfen, so dass die Kommandostruktur mehr »aus einem Guss« ist als bei pstricks, das über die Jahre einige Algen und Muscheln angesetzt hat. pgf besteht konzeptionell aus
Hack #78: Für alle Fälle PGF
277
#78
HACK
#78
Für alle Fälle PGF
drei Schichten, einem Frontend, das bequeme Benutzerkommandos implementiert, einer Basisschicht, die Dienste für das Frontend zur Verfügung stellt, und einer Systemschicht, die die Grafikoperationen der Basisschicht auf Kommandos im Ausgabeformat (PostScript, PDF oder Ähnliches) abbildet. Man kann pgf an ein neues Ausgabeformat anpassen, indem man die Systemschicht entsprechend ändert; umgekehrt ist es auch möglich, problemangepasste Frontends zu entwickeln, die auf der Basisschicht aufbauen. Das kanonische Frontend von pgf heißt TikZ, kurz für »TikZ ist kein Zeichenprogramm«, und stellt eine Eingabesprache zur Verfügung, die irgendwo in der Mitte zwischen der von pstricks und der des METAFONT-Systems anzusiedeln ist (ohne dass sie Ansprüche auf Kompatibilität zu einer der beiden erhebt). Der Name TikZ unterstreicht die Tatsache, dass Grafiken hier nicht mit der Maus gemalt, sondern textuell »programmiert« werden, genau wie Sie in LATEX Ihre Dokumente »programmieren«. TikZ hat also viele der Vorteile von LATEX (unter anderem Präzision, Programmierbarkeit und hohe Qualität), aber auch viele der Nachteile (es ist nicht ganz einfach zu lernen, man hat keine unmittelbare Rückkopplung, und kleine Änderungen können aufwendig sein). Das Handbuch für pgf und TikZ ist über dreihundert Seiten dick, so dass wir hier leider nur einen kleinen Einblick in die Möglichkeiten dieses Pakets geben können. Mit TikZ können Sie Bilder entweder »direkt« mit dem Kommando \tikz erzeugen oder in eine tikzpicture-Umgebung einbetten. Das \draw-Kommando dient dazu, beliebige Pfade zu zeichnen. Ein Pfad ist eine Folge von aneinander stoßenden Geraden und Kurven, die von einem bestimmten Punkt ausgeht. Betrachten Sie zum Beispiel \tikz \draw (0,0) -- (2,2) [rounded corners] -- (0,2) -- (2,0) ;
In diesem Beispiel sind alle Koordinaten »absolut« angegeben. Sie können allerdings auch »relative« Koordinaten benutzen, die jeweils vom vorigen Punkt ausgehen: \tikz \draw (0,0) -- ++(1,1) -- ++(1,-1) -- ++(1,1) ;
Hier steht »++(1,1)« für »mache ausgehend vom letzten Punkt einen Schritt nach rechts und einen nach oben«. Die nächste relative Koordinate geht dann von diesem Punkt aus. TikZ unterstützt diverse Koordinatensysteme, zum Beispiel auch dreidimensionale oder Polarkoordinaten.
278
Kapitel 8: Grafik
HACK
Für alle Fälle PGF
Sie können statt gerader Linien auch Kurven verwenden, müssen dann aber »Kontrollpunkte« angeben, die über die Form der Kurve entscheiden. TikZ verwendet so genannte kubische Bézier-Kurven, bei denen die Verbindung zwischen dem Anfangspunkt und dem ersten Kontrollpunkt die Richtung angibt, die die Kurve am Anfang hat. Entsprechend gibt die Verbindung zwischen dem zweiten Kontrollpunkt und dem Endpunkt der Kurve die Richtung vor, die die Kurve hat, wenn sie den Endpunkt erreicht. Der Abstand zwischen den Endpunkten der Kurve und den jeweiligen Kontrollpunkten entscheidet über die Länge der Kurve. Beide Kontrollpunkte dürfen zusammenfallen, und dann müssen Sie nur einen Kontrollpunkt angeben. Das folgende Beispiel (aus der TikZ-Dokumentation ausgeliehen) zeigt einen Pfad aus zwei Kurven, die erste mit einem und die zweite mit zwei Kontrollpunkten. \begin{tikzpicture} \draw[line width=10pt] (0,0) .. controls (1,1) .. (3,0) .. controls (4,0) and (4,1) .. (3,1); \draw[color=gray] (0,0) -- (1,1) -- (3,0) -- (4,0) -- (4,1) -- (3,1); \end{tikzpicture}
Hier sehen Sie auch, dass Sie in eckigen Klammern Parameter angeben können, die das Resultat des jeweiligen Befehls modifizieren. Beim ersten \draw entsteht zum Beispiel eine breite Linie, beim zweiten wird die Zeichenfarbe umgestellt. TikZ unterstützt eine große Auswahl von Parametern, die die Grafikausgabe steuern. Sie sind nicht gezwungen, alles aus Pfaden mit expliziten Koordinaten zusammenzustückeln. TikZ macht einige grafische Formen bequem zugänglich: \begin{tikzpicture} \draw [style=dashed] (2,0.5) circle (0.5cm); \draw [fill=gray!20] (1,1) ellipse (.5cm and 1cm); \draw [fill=gray] (0,0) rectangle (1,1); \draw [style=thick] (0,2) -- +(30:1cm) arc (30:60:1cm) -- cycle; \end{tikzpicture}
Das letzte Kommando zeichnet das »Tortenstück«; beachten Sie hier, dass der Anfang des Bogens in Polarkoordinaten angegeben wurde (»+(30:1cm)« steht für »1 cm weit in einem 30-Grad-Winkel«) und dass »-- cycle« den Pfad schließt, indem eine gerade Linie zum Anfangspunkt des Pfads gezogen wird. Hack #78: Für alle Fälle PGF
279
#78
HACK
#78
Für alle Fälle PGF
Auch für »Präsentationsgrafiken« hält TikZ einige Hilfsmittel bereit: \begin{tikzpicture}[ycomb] \draw[color=gray!20,line width=2mm] plot coordinates{(.5,1) (1,.7) (1.5,1.3)}; \draw[color=gray!50,line width=2mm,xshift=1.5mm] plot coordinates{(.5,.6) (1,1.1) (1.5,0.9)}; \draw[->] (-.2,0) -- (2,0); \draw[->] (0,-.2) -- (0,1.5); \end{tikzpicture}
Das »ycomb« ist eigentlich eine Option für plot, das dafür sorgt, dass die angegebenen Koordinaten über eine Linie mit der x-Achse verbunden werden. Das Koordinatenpaar »(.5,1)« steht also für eine Säule, ohne dass der korrespondierende Punkt (.5,0) mit spezifiziert werden muss. Beachten Sie auch, wie wir das Achsenkreuz gezeichnet haben. Das folgende interessante Beispiel illustriert gleich mehrere neue Konzepte von TikZ:
c a
b
\begin{tikzpicture} \tikzstyle{every node}=[circle,fill=gray!20] \node (a) at (0,0) {a}; \node (b) at +(0:1.5cm) {b}; \node (c) at +(60:1.5cm) {c}; \foreach \from/\to in {a/b,b/c,c/a} \draw [->] (\from) -- (\to); \end{tikzpicture}
Mit \node können Sie ein Objekt definieren, das (unter anderem) Text enthält. Ein Kommando wie \node[circle,fill=red] (x) at (0,0) {abc};
platziert an der angegebenen Position einen Kreis, der den Text »abc« enthält. Das so erzeugte Objekt bekommt den Namen »x«, unter dem es später angesprochen werden kann. In unserem Beispiel weist das \foreach-Kommando den »Schleifenvariablen« \from und \to nacheinander die Werte a und b, b und c sowie c und a zu und sorgt so für das Zeichnen der Verbindungspfeile. Die mit \tikzstyle{every node} vereinbarten Parameter werden so behandelt, als seien sie bei jedem \node-Kommando angegeben worden. Die Objekte b und c werden übrigens mit relativen Polarkoordinaten platziert: b landet 1,5 cm rechts von a (Winkel 0◦ ), c im selben Abstand in einem Winkel von 60◦ (so wie es sich für ein gleichseitiges Dreieck gehört).
280
Kapitel 8: Grafik
HACK
Für alle Fälle PGF
1
1 2
tan α =
sin α
−1
− 12
cos α
sin α cos α
1
\begin{tikzpicture}[scale=3] \clip (-2,-0.3) rectangle (2,1.1); \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle; \draw[->] (-1.5,0) -- (1.5,0) coordinate (x axis); \draw[->] (0,-1.5) -- (0,1.5) coordinate (y axis); \draw (0,0) circle (1cm); \draw[very thick,red] (30:1cm) -- node[left=1pt,fill=white] {$\sin \alpha$} (30:1cm |- x axis); \draw[very thick,blue] (30:1cm |- x axis) -- node[below=2pt,fill=white] {$\cos \alpha$} (0,0); \draw[very thick,orange] (1,0) -- node [right=1pt,fill=white] {$\displaystyle \tan \alpha \color{black}= \frac{{\color{red}\sin \alpha}}{\color{blue}\cos \alpha}$} (intersection of 0,0--30:1cm and 1,0--1,1) coordinate (t); \draw (0,0) -- (t); \foreach \x/\xtext in {-1, -0.5/-\frac{1}{2}, 1} \draw (\x cm,1pt) -- (\x cm,-1pt) node[anchor=north,fill=white] {$\xtext$}; \foreach \y/\ytext in {-1, -0.5/-\frac{1}{2}, 0.5/\frac{1}{2}, 1} \draw (1pt,\y cm) -- (-1pt,\y cm) node[anchor=east,fill=white] {$\ytext$}; \end{tikzpicture}
Abbildung 8-6: Winkelfunktionen (mit TikZ)
Hack #78: Für alle Fälle PGF
281
#78
HACK
#78
Für alle Fälle PGF
0
q1 0
1
q0
q3 1
0 q2
1 \usetikzlibrary{automata} \begin{tikzpicture} [shorten >=1pt,node distance=2cm,>=stealth,initial text=] \tikzstyle{every state}=[draw=blue!50,very thick,fill=blue!20] \tikzstyle{accepting}=[accepting by arrow] \node[state,initial] (q_0) {$q_0$}; \node[state] (q_1) [above right of=q_0] {$q_1$}; \node[state] (q_2) [below right of=q_0] {$q_2$}; \node[state,accepting](q_3) [below right of=q_1] {$q_3$}; \path[->] (q_0) edge node [above left] {0} (q_1) edge node [below left] {1} (q_2) (q_1) edge node [above right] {1} (q_3) edge [loop above] node {0} () (q_2) edge node [below right] {0} (q_3) edge [loop below] node {1} (); \end{tikzpicture}
Abbildung 8-7: Ein endlicher Automat (mit TikZ)
282
Kapitel 8: Grafik
HACK
Von Monat zu Monat
TikZ hat auch eine bequeme Notation für Baumstrukturen: Wurzel
Links
Mitte
Rechts
Links
Rechts
\begin{tikzpicture} \node {Wurzel} child {node {Links}} child {node {Mitte}} child {node {Rechts} child {node {Links}} child {node {Rechts}} }; \end{tikzpicture}
Dabei kümmert es sich selbstständig um die Positionierung der Knoten im Baum. Auch hier können Sie geometrische Objekte und Namen verwenden: Wurzel
L
R
\begin{tikzpicture} \node[rectangle,draw] {Wurzel} child {node[circle,draw] (linke) {L}} child {node[circle,draw] (rechte) {R}}; \draw[dashed,] (linke) -- (rechte); \end{tikzpicture}
pgf und TikZ stellen ausgesprochen mächtige Werkzeuge dar, auf deren Fein-
heiten wir hier gar nicht eingehen können. Die Dokumentation des Pakets ist aber sehr ausführlich und enthält jede Menge anschauliche Beispiele, die die Eigenschaften der verschiedenen Kommandos verdeutlichen. Der riesige Leistungsumfang und die Möglichkeit, Grafiken für PDF-Ausgabe zu erzeugen, machen pgf zu einem Paket, das es sicherlich wert ist, genauer angeschaut zu werden. Zu Ihrer Erbauung zeigen Abbildung 8-6 und Abbildung 8-7 noch einige aus der pgf-Dokumentation adaptierte Grafiken, die weitere Fähigkeiten des Pakets illustrieren.
HACK
#79
Von Monat zu Monat Setzen Sie einen Fotokalender mit LATEX.
Jedes Jahr in der dritten Adventswoche oder so beginnt die Hektik: Was schenken Sie Tante Frieda, Großonkel Heribert, der Nichten und Neffen zahlloser Schar? Wie wäre es denn mit einem Fotokalender? Digitalfotos der Brut haben Sie sicherlich in Fülle. Oder Sie überraschen die Liebe Ihres Lebens mit einer Erinnerung an den letzten Bali-Urlaub. Notfalls gibt es immer noch Flickr. Fotokalender sind natürlich etwas, was die Foto-Onlinedienste Ihnen mit Freuden und wohlfeil herstellen. Auf der anderen Seite sind die dort angebotenen Layouts im Großen und Ganzen etwas hausbacken. Wenn Sie Ihre
Hack #79: Von Monat zu Monat
283
#79
HACK
#79
Von Monat zu Monat
eigenen Ideen umsetzen wollen, können Sie das natürlich mit LATEX tun. Es folgen ein paar Anregungen dafür.
Kalendarium Die erste Hürde ist, sich ein Kalendarium zu verschaffen. Es gibt diverse LATEX-Methoden, um Kalendarien zu erzeugen, die aber alle für unsere Anwendung nicht wirklich in Frage kommen. Sie sind entweder für die falsche Sorte Kalender ausgelegt – typischerweise Jahreskalender in groß (kalender von Jörg Söhner) oder klein (calxxxx von Slobodan Jankovi´c) oder große Wochen- und Monatskalender mit Platz für Notizen (calendar von Frank Bennett) –, oder mit der angloamerikanischen Marotte verheiratet, hart codiert den Sonntag zum ersten Tag der Woche zu erklären (calendar_barr von Michael Barr). Wir greifen hier wieder einmal in den Unix-Werkzeugkasten, genaugenommen den von BSD (der auch unter Linux zur Verfügung steht), und holen dort das Programm ncal heraus, das uns nette kleine Monatskalender etwa wie folgt beschert: $ LANG=de cal -m 3 2007 März 2007 Mo Di Mi Do Fr Sa So 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Dass die Woche hier, so wie sich das gehört, mit dem Montag anfängt, ist eine Konsequenz der Option »-m«. Sie könnten sich natürlich darauf verlassen, die deutsche Lokalisierung eingeschaltet zu haben – was Sie sollten, wegen der deutschsprachigen Monats- und Wochentagsnamen –, aber sicher ist sicher. Dieser Kalender ist schön, aber für uns nicht direkt verwendbar. Wir hätten gerne etwas wie \begin{calmonth}{März}{2007} Mo&Di&Mi&Do&Fr&Sa&So\\ & & & 1& 2& 3& 4\\ 5& 6& 7& 8& 9&10&11\\ 12&13&14&15&16&17&18\\ 19&20&21&22&23&24&25\\ 26&27&28&29&30&31&\\ \end{calmonth}
284
Kapitel 8: Grafik
HACK
Von Monat zu Monat
#!/usr/bin/perl # make-calendar: ncal-Ausgabe für LaTeX aufbereiten my $year = shift; foreach my $month (1 .. 12) { my ($head, @cal) = ‘cal -m $month $year‘; ($head) = $head =~ /(\S+)/; printf qq|\\begin{calmonth}{%s}{%d}\n|, $head, $year; foreach (@cal) { next unless /\S/; @days = unpack ’(A3)7’, $_; print join(’&’, @days), "\\\\\n" if @days; } print qq|\\end{calmonth}\n|; } Abbildung 8-8: make-calendar – Kalender für LATEX mit ncal
und das ist eindeutig ein Job für Perl (Abbildung 8-8). Das Skript schreibt zwölf solche Monatskalender auf seine Standardausgabe, und uns fehlt nur noch ein »Rahmen« zur Formatierung der Kalenderblätter (mit Fotos!) Wir betrachten zuerst ein einfaches Layout (Abbildung 8-9), das sich vor allem für hochkant stehende Fotos eignet und das Kalendarium rechts vom Foto hat. Die Unterkanten von Foto und Kalendarium sind auf einer Höhe. Die Eingabedatei dafür könnte ungefähr so aussehen: \documentclass{photocal} \usepackage[latin1]{inputenc} \usepackage[T1]{fontenc} \usepackage{comic} \renewcommand{\familydefault}{\sfdefault} \calendarsetup{style=side} \begin{document} \calendar{cal2007} \end{document}
Wir verwenden für die Kalender eine eigene Dokumentklasse, photocal, die im Wesentlichen die Kommandos \calendarsetup und \calendar zur Verfügung stellt. Mit \calendarsetup können Sie einen »Kalenderstil« auswählen, hier side, und \calendar liest die angegebene Datei, hier cal2007.tex, ein und formatiert die darin enthaltenen Kalendarien. Diese Datei haben Sie vorher natürlich mit make-calendar angelegt.
Hack #79: Von Monat zu Monat
285
#79
HACK
#79
Von Monat zu Monat
Januar Mo Di Mi Do Fr Sa So 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Abbildung 8-9: Ein einfaches Kalender-Layout
Die (relativ überschaubare) Dokumentklasse photocal sehen Sie in Abbildung 8-10. Die ersten Zeilen beschäftigen sich mit den üblichen Verwaltungsarbeiten. Wir verwenden die Klasse geometry [Hack #31], um ein Papierformat einzustellen, das durch sein Seitenverhältnis von 4 : 3 dem ähnelt, was gängige Digitalkameras so von sich geben – dies mit Blick darauf, die Kalenderblätter bei einem Foto-Dienstleister wohlfeil und mit hoher Qualität ausgeben zu lassen. Die \define@key-Kommandos dienen dazu, über das keyval-Paket von David Carlisle das \calendarsetup-Kommando zu implementieren. (Es wäre natürlich möglich, weitere Konfigurationsschlüssel beim \calendar-Kommando zu akzeptieren, aber im Interesse der Übersichtlichkeit sparen wir uns das mal.) Insbesondere sorgt der style-Schlüssel dafür, für den konkreten Kalenderstil eine Datei zu lesen, deren Name den gewünschten Stil enthält. Der vorher skizzierte Stil aus Abbildung 8-9 steht in der Datei cal-side.sty, die in Abbildung 8-11 zu sehen ist. Ihr wesentlicher Bestandteil ist die Definition der calmonth-Umgebung, deren Inhalt aus zwei minipages besteht. Die rechte minipage enthält eine tabular-Umgebung, die wir zum Formatieren des
286
Kapitel 8: Grafik
HACK
Von Monat zu Monat
\NeedsTeXFormat{LaTeX2e} \ProvidesClass{photocal}[2007/03/05 v0.1 Photo calendar (AL)] \LoadClass{article} \RequirePackage[paperwidth=18cm,paperheight=13.5cm,% noheadfoot,left=5mm,right=5mm,top=1cm,% bottom=5mm]{geometry} \RequirePackage{color} \RequirePackage{array} \RequirePackage[latin1]{inputenc} \RequirePackage{graphicx} \RequirePackage{keyval} \setlength{\parindent}{0pt} \pagestyle{empty} \newcommand*{\cal@prefix}{pic} \define@key{Cal}{prefix}{% \renewcommand*{\cal@prefix}{#1}} \define@key{Cal}{style}{\RequirePackage{cal-#1}} \newcounter{calmonth} \newcommand*{\calendarsetup}[1]{\setkeys{Cal}{#1}} \newcommand*{\calendar}[1]{\input{#1}} \endinput Abbildung 8-10: Die Dokumentklasse photocal
Kalendariums verwenden, das ja tabellenartig den Inhalt von calmonth bildet. Über dem Kalendarium steht der Monatsname, das erste Argument von \begin{calmonth}. Den Namen des Fotos, das in der linken minipage steht, konstruieren wir aus dem Kommando \cal@prefix, das in der Dokumentklasse über den \calendarsetup-Schlüssel prefix gesetzt werden kann, und einer fortlaufenden Nummer, die die Monate zählt. Mit dem Standardwert für \cal@prefix, pic, kommen wir also auf pic1, pic2, . . . , pic12 Die Endung hängt natürlich davon ab, welches Ausgabeprogramm wir verwenden wollen – unsere Empfehlung ist pdfLATEX, damit wir direkt JPEG-Dateien verwenden können, so wie die Digitalkamera sie liefert. (Alternativ können Sie natürlich den Ansatz aus dvips und Nicht-PostScript-Dateien [Hack #75] verwenden, um dvips mit den JPEG-Dateien zu füttern.) Die Parameter für \includegraphics sorgen dafür, dass das Bild in ein Rechteck eingepasst wird, ohne dabei gestreckt oder gestaucht zu werden.
Hack #79: Von Monat zu Monat
287
#79
HACK
#79
Von Monat zu Monat
Erwähnenswert sind die Definitionen für die Kommandos \weekdays, \evenweek, \oddweek und \hd. Bevor wir diese erklären können, müssen wir eine Lüge gestehen: Die Ausgabe unseres »echten« make-calendar sieht eher aus wie \begin{calmonth}{März}{2007} \weekday{Mo&Di&Mi&Do&Fr&Sa&So} & & & 1& 2& 3& 4\oddweek 5& 6& 7& 8& 9&10&11\evenweek 12&13&14&15&16&17&18\oddweek 19&20&21&22&23&24&25\evenweek 26&27&28&29&30&31&\oddweek \end{calmonth}
Das heißt, die Zeilenenden werden nicht durch das LATEX-übliche \\ ausgedrückt, sondern abwechselnd durch \evenweek und \oddweek, und die Wo\ProvidesPackage{cal-side}[2007/03/05 Calendar style ’side’ (AL)] \newenvironment{calmonth}[2]{% \stepcounter{calmonth}% \begin{minipage}[b]{.58\textwidth} \centering \includegraphics[width=\textwidth,height=.96\textheight,% keepaspectratio=true]% {\cal@prefix\arabic{calmonth}} \end{minipage} \hfill \begin{minipage}[b]{.41\textwidth} \Large \centering {\Huge\bf#1}\\[5mm] \begin{tabular}[b]{@{}rrrrrr>{\color{red}}r@{}} }{% \end{tabular} \end{minipage} \newpage } \newcommand{\weekdays}[1]{#1\\} \newcommand{\evenweek}{\\} \newcommand{\oddweek}{\\} \newcommand{\hd}[2][]{\textcolor{red}{#2}} \endinput Abbildung 8-11: Der Kalenderstil side
288
Kapitel 8: Grafik
HACK
Von Monat zu Monat
Januar
Mo 1 15 29
Di 2 16 30
Mi 3 17 31
Do 4 18
Fr 5 19
Sa 6 20
So 7 21
Mo 8 22
Di 9 23
Mi 10 24
Do 11 25
Fr 12 26
Sa 13 27
So 14 28
Abbildung 8-12: Ein distinguierter Kalenderstil
chentagszeile ist das Argument eines \weekdays-Kommandos. Naja, die betreffenden Kommandos haben alle ziemlich naheliegende Bedeutungen, und wir erklären Ihnen später, wofür diese zusätzliche Komplexität gut ist.
Ein anderer Kalenderstil Einen anderen, durchaus distinguierten Kalenderstil zeigt Abbildung 8-12. Hier steht das Kalendarium unterhalb des Bildes und ist »zwei Wochen breit«. Dieser Stil eignet sich besser für querformatige Fotos. Wir müssen dafür nur ein weiteres Paket, cal-bottom, zur Verfügung stellen, das eine entsprechende Implementierung von calmonth & Co. enthält. Der dazu nötige Code steht in Abbildung 8-13. Bis auf die veränderte Positionierung unterscheidet sich die calmonth-Umgebung nicht nennenswert von der in cal-side, bis auf eine Sache: Im Tabellenkopf der tabular-Umgebung sehen wir die sieben Wochenspalten jetzt doppelt vor. Und so langsam dürfte Ihnen auch dämmern, warum wir den Eiertanz mit \weekdays, \oddweek und \evenweek gemacht haben, wenn Sie sich die ent-
Hack #79: Von Monat zu Monat
289
#79
HACK
#79
Von Monat zu Monat
\ProvidesPackage{cal-bottom}[2007/03/05 Calendar style ’bottom’ (AL)] \newenvironment{calmonth}[2]{% \stepcounter{calmonth}% \centering \includegraphics[height=.8\textheight,keepaspectratio=true]% {\cal@prefix\arabic{calmonth}}\par \vspace{2ex} \begin{minipage}{\textwidth} \centering {\fontsize{36pt}{40pt}\selectfont\textbf{#1}}\quad \begin{tabular}[b]{@{}*{2}{rrrrrr>{\color{red}}r}@{}} }{% \end{tabular} \end{minipage} \newpage } \newcommand{\weekdays}[1]{#1\\} \newcommand{\oddweek}{&} \newcommand{\evenweek}{\\} \newcommand{\hd}[2][]{\textcolor{red}{#2}}% \endinput Abbildung 8-13: Der Kalenderstil bottom
sprechenden Definitionen in diesem Kalenderstil anschauen: Das ganze war nötig, um mit derselben Kalendariumsdatei die »doppelt breite« Ausgabe unterstützen zu können!
Feiertage Ein im wirklichen Leben wichtiges Thema haben wir bisher offen gelassen: Was ist mit den Feiertagen, die nicht auf einen Sonntag fallen? In unserem Konzept ist das die Aufgabe von make-calendar, unserem Perl-Skript. Tatsächlich enthält die LATEX-Seite unseres Kalenderdruckwerks schon die nötigen Vorarbeiten: Die Kalenderstile definieren ein \hd-Kommando, mit dem das PerlProgramm Feiertagsdaten in der Form \hd[Neujahr]{1}
auszeichnen kann. Der Kalenderstil kann dann entscheiden, ob er zum Beispiel das Datum rot darstellen möchte, und was er mit dem Feiertagsnamen anfangen will (wenn überhaupt). make-calendar muss gegenüber der simplen Form in Abbildung 8-8 etwas erweitert werden – die komplette Fas290
Kapitel 8: Grafik
HACK
Von Monat zu Monat
#!/usr/bin/perl my $year = shift; my @hd; $hd[0] = undef; # unbenutzt push @hd, {} foreach (1..12); $hd[1] = { ’ 1’ => ’Neujahr’ }; $hd[5] = { ’ 1’ => ’Maifeiertag’ }; $hd[10] = { ’ 3’ => ’Einheitstag’ }; $hd[12] = { ’25’ => ’Weihnachten’, ’26’ => ’Weihnachten’ }; # Dies sollten wir eigentlich ausrechnen. $hd[4] = { ’ 6’ => ’Karfreitag’, ’ 8’ => ’Ostersonntag’, ’ 9’ => ’Ostermontag’ }; foreach my $month (1 .. 12) { my ($head, @cal) = ‘cal $month $year‘; ($head) = $head =~ /(\S+)/; printf qq|\\begin{calmonth}{%s}{%d}\n|, $head, $year; $week = 0; foreach (@cal) { next unless /\S/; @days = unpack ’(A3)7’, $_; my $count = 0; @days = map { $count++ == 6 || $hd[$month]->{$_} ? sprintf "\\hd[%s]{%s}", $hd[$month]->{$_}, $_, : $_ } @days; if ($week++ == 0) { printf qq|\\weekdays{%s}\n|, join(’&’, @days); } else { print join(’&’, @days), sprintf "\\%sweek\n", $week % 2 ? "even":"odd" } } print qq|\\end{calmonth}\n|; } Abbildung 8-14: make-calendar – die komplette Fassung
Hack #79: Von Monat zu Monat
291
#79
HACK
#79
Von Monat zu Monat
sung, die auch das \oddweek/\evenweek-Manöver unterstützt, steht in Abbildung 8-14. Sie enthält einige Subtilitäten, die eher in einem Perl-Buch als in einem LATEX-Buch erklärt werden sollten, und ist auch nicht schlau genug, um die variablen Feiertage rund um Ostern selber korrekt zu berechnen (wie gesagt, dies ist ein LATEX-Buch). Aber man muss sich ja Steigerungsmöglichkeiten erhalten . . .
Ausgabe Das letzte Problem ist: Wie bereiten wir unseren Kalender für den freundlichen Nachbarschafts-Fotodienstleister auf? PDF-Dateien gehören dort nicht wirklich zum Programm (wobei, wenn Sie ein paar hundert Kalender für Ihre weitläufige Bekanntschaft drucken lassen wollen, würde eine richtige Druckerei sich sicher über die PDF-Dateien freuen), sondern man rechnet eher mit JPEG. Wir müssen die PDF-Datei, die pdfLATEX uns liefert, also in zwölf JPEG-Dateien umwandeln. Dazu enthält das xpdf-Paket, das Sie in Ihrer Linux-Distribution oder auf http://www.foolabs.com/xpdf finden, ein nettes kleines Programm namens pdftoppm: $ pdftoppm -r 300 calendar.pdf cal
Eine Weile und etliche Megabyte Plattenplatz später sollten Sie dann die Dateien cal-000001.ppm bis cal-000012.ppm in Ihrem Verzeichnis finden. Mit der -r-Option können Sie eine Auflösung in dpi (Punkten pro Zoll) für die Ausgabedatei angeben. Diese sollte einigermaßen sinnvoll zu dem Druckformat passen, das Sie anstreben; mit dem pdftoppm-Standard von 150 dpi bekommen Sie bei unserer Papiergröße PPM-Dateien von 1063 auf 797 Pixel, und das ist zu klein. Mit 300 dpi sind Sie aber praktisch genau bei dem Format, das wir ursprünglich eingestellt haben (rechnen Sie’s nach). Das Bild hat dann ungefähr 3,4 »Megapixel«, und das ist für ein 18-Zentimeter-Bildformat durchaus in Ordnung. Viel größere Seiten sollten Sie nur erzeugen, wenn Ihre JPEG-Kalenderbilder auch mehr Auflösung zu bieten haben. Die PPM-Dateien müssen wir jetzt noch in JPEG-Dateien umwandeln. Hier kommt uns zum Beispiel wieder das convert-Programm aus dem ImageMagick-Paket zu Hilfe, das wir auch in dvips und Nicht-PostScript-Dateien [Hack #75] benutzt haben. Mit $ for i in cal-*.ppm; do \ > convert $i ‘basename $i .ppm‘.jpg; done
bekommen Sie schöne (und nicht mehr ganz so riesige) JPEG-Dateien namens cal-000001.jpg usw., die Sie zum Fotodienstleister hochladen und hoffentlich 292
Kapitel 8: Grafik
HACK
Stickvorlagen aus Grafikdateien generieren
bald als beeindruckende »Abzüge« in der Hand halten können. Weihnachten ist gerettet!
Siehe auch • Wenn Sie die Feiertage in Perl berechnen wollen, können Sie von einigen hilfreichen CPAN-Modulen ausgehen. Date::Manip weiß, wann Ostern ist, und hat auch genug Muckis, um die davon abhängigen Feiertage wie Pfingsten oder Rosenmontag (O’Reilly Deutschland sitzt in Köln) zu berechnen. Date::Easter ist um einiges leichtgewichtiger und einfacher zu verstehen, aber Sie müssen mehr Eigenleistung beisteuern.
HACK
#80
Stickvorlagen aus Grafikdateien generieren Für alle, die Handarbeiten schätzen: Wie Sie aus beliebigen Grafiken Stickschrift erzeugen können
Aus dem trauten Heim ist es nicht wegzudenken: St. Bartholomä am Königssee und der Watzmann im Kreuzstich, rechts oberhalb vom Fernseher. Sicher haben Sie sich auch schon gefragt, wie Sie aus Ihren Urlaubsfotos etwas ähnlich Repräsentatives machen können, und Ihnen ist der leise Verdacht gekommen, dass Großtante Elsbeth da vielleicht eher eine Antwort drauf weiß als der freundliche Nachbarschafts-Fotodienstleister im Internet. (Der macht dafür, wenn wir ehrlich sind, schönere Mauspads und Bierseidel als Tante Elsbeth.) Wir zeigen Ihnen hier, wie Sie aus einer Grafikdatei etwas machen können, das eine des Stickens kundige Person dann in Weihnachts- und Geburtstagsgaben konvertieren könnte. Sie brauchen dazu außer LATEX nur ein geeignetes Grafikprogramm und ein paar Zeilen Perl-Code. Wir beginnen damit, unsere Ausgangsgrafik (Abbildung 8-15a) radikal zu verkleinern, denn selbst wenn Tante Elsbeth auch ansonsten nichts anderes zu tun zu haben scheint, wollen wir ihr doch nicht wirklich Megapixel-Bilder zumuten. Anschließend müssen wir die Anzahl der Farben im Bild ebenso radikal reduzieren, aus ähnlichen Gründen – selbst hartgesottene Stickfanatiker scheuen vor »True Color« mit 24 Bitebenen zurück. Rechts in Abbildung 8-15 sehen Sie unser Motiv auf etwa ein lineares Zehntel der Ausgangsgröße und 8 Farben reduziert, im Vergleich zum Wallfahrtskirchlein am Königssee geradezu ein Kinderspiel. Zur Verringerung der Farbenvielfalt haben wir mit unserem Grafikprogramm (The GIMP) das Bild in den »indizierten« Modus umgewandelt2 und dabei »8 Farben« ausgewählt. Dabei sucht der GIMP sich 2
Die Funktion finden Sie unter »Bild« im Untermenü »Modus«; dieser Modus heißt nicht so, weil er als jugendgefährdend verpönt ist, sondern weil nur eine geringe Anzahl von Farben im Bild vorkommen darf. Pro Pixel wird dann nicht mehr der tatsächliche Farbton gespeichert, sondern
Hack #80: Stickvorlagen aus Grafikdateien generieren
293
#80
HACK
Stickvorlagen aus Grafikdateien generieren
/* XPM */ static char * pingu_xpm[] = { "22 26 9 1", " c None", ". c #0D0E08", "+ c #735205", "@ c #5A574C", "# c #BA890E", "$ c #9F9988", "% c #F7C71C", "& c #CCCBC3", "* c #FAFCF9", " .. ", " ...... ", " ...... ", " ........ ", " .$@.&$.. ", " .@@@@@@. ", " .@%%#$.. ", " .%%%%%.. ", " .+%#%#@@. ", " .&$#&*$.. ", " .@******... ", " .&******$... ", " ..******&$... ", " .$********@... ", " .@*********&... ", " .$**********.... ", " ..&**********.... ", " .@&**********.... ", " %%+*********%...# ", " %%%%.&******&%+.+% ", " %%%%#.&*****$%%%%% ", "%%%%%%%+&*****+%%%%%%%", "%%%%%%%%&***&@+%%%%%%%", " %%%%%%%+@@...+%%%%% ", " #%#%%%+.....+%%%# ", " ### ## "}; Abbildung 8-16: Die Grafik im XPM-Format
Hack #80: Stickvorlagen aus Grafikdateien generieren
295
#80
HACK
#80
Stickvorlagen aus Grafikdateien generieren ♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
♣
⊙
⋆
♣
♥
⊙
♣
♣
♣
⋆
⋆
⋆
⋆
⋆
⋆
♣
26
21
♣
♣
⋆
•
•
⊕
⊙
♣
♣
♣
•
•
•
•
•
♣
♣
♣
◦
•
⊕
•
⊕
⋆
⋆
♣
♣
♥
⊙
⊕
♥
♦
⊙
♣
♣
♣
⋆
♦
♦
♦
♦
♦
♦
♣
♣
♣
♣
♥
♦
♦
♦
♦
♦
♦
⊙
♣
♣
16
♣
♣
♣
♦
♦
♦
♦
♦
♦
♥
⊙
♣
♣
♣
♣
⊙
♦
♦
♦
♦
♦
♦
♦
♦
⋆
♣
♣
♣
♣
⋆
♦
♦
♦
♦
♦
♦
♦
♦
♦
♥
♣
♣
♣
♣
⊙
♦
♦
♦
♦
♦
♦
♦
♦
♦
♦
♣
♣
♣
♣
♣
♥
♦
♦
♦
♦
♦
♦
♦
♦
♦
♦
♣
♣
♣
♣
♣
⋆
♥
♦
♦
♦
♦
♦
♦
♦
♦
♦
♦
♣
♣
♣
♣
♣
11
6
• •
•
•
•
◦
♦
♦
♦
♦
♦
♦
♦
♦
♦
•
♣
♣
♣
⊕
•
•
•
•
♣
♥
♦
♦
♦
♦
♦
♦
♥
•
◦
♣
◦
•
•
•
•
•
⊕
♣
♥
♦
♦
♦
♦
♦
⊙
•
•
•
•
•
•
•
•
•
•
◦
♥
♦
♦
♦
◦
•
•
•
•
•
•
•
•
•
♦
♦
•
•
•
•
•
•
•
♥
♦
♦
♦
♥
⋆
◦
•
•
•
•
•
•
•
•
•
•
•
•
◦
⋆
⋆
♣
♣
♣
◦
•
•
•
•
•
⊕
•
⊕
◦
♣
♣
♣
♣
♣
◦
•
•
•
⊕
⊕
⊕
•
•
•
⊕
⊕
⊕
1 0 5 10 15 20 ♣ = #0D0E08, ◦ = #735205, ⋆ = #5A574C, ⊕ = #BA890E, ⊙ = #9F9988, • = #F7C71C, ♥ = #CCCBC3, ♦ = #FAFCF9
Abbildung 8-17: Tux als Stickvorlage
das Ockergelb der Füße wiedergibt. (Erinnern Sie sich daran, dass auf dem Computerbildschirm Rot und Grün zusammen Gelb ergeben, und in #F7C71C sind Rot und Grün relativ stark vertreten, aber Blau kaum.) Abbildung 8-17 zeigt das Endergebnis, das wir uns wünschen; hier sind die einzelnen »Pixel« (oder sollten wir »Stixel« sagen?) nicht als Farben, sondern als Symbole dargestellt, was nicht nur farbige Tinte spart, sondern möglicherweise auch leichter zu lesen ist. Die Konvertierung von XPM nach LATEX übernimmt das Perl-Programm in Abbildung 8-18. Seine Aufgabe ist es, die Farbtabelle zu lesen und zu speichern (und dabei jeder Farbe ein TEX-Symbol zu296
Kapitel 8: Grafik
HACK
Stickvorlagen aus Grafikdateien generieren
#!/usr/bin/perl # xpmtostitch -- XPM-Datei in Stickmuster umwandeln use strict; my @symbols = qw/clubsuit circ star oplus odot bullet heartsuit diamondsuit spadesuit cup cap div/; my $next = 0; my ($w, $h, $cols, @colours, %symbol); my ($row, $column); print {name})\n" if $typeface ne $typeface{$tfcode}->{name}; print " (Alias: @{$typeface{$tfcode}->{alias}})\n" if @{$typeface{$tfcode}->{alias}}; }
Abbildung 10-4: decode-fontname – Schrifthersteller und -name nachschlagen
340
Kapitel 10: LATEX-Werkzeuge
HACK
Welche Schriften gibt es im Dokument?
Abbildung 10-5: Die benutzten Schriften in einer PDF-Datei, mit Adobe Reader
Schriften in PDF-Dateien Die Schriften, die in einer PDF-Datei vorkommen, können Sie sich von den meisten PDF-Betrachtern auflisten lassen (Abbildung 10-5 zeigt ein Beispiel mit Adobe Reader). Allerdings ist das nicht unbedingt immer nützlich, wenn Sie die Liste anschließend weiterverarbeiten wollen. Dafür hält zum Beispiel der freie PDF-Betrachter xpdf ein Programm namens pdffonts bereit, das die Schriftenliste auf seiner Standardausgabe produziert: $ pdffonts elche.pdf name -----------------------------CLEYIP+URWBookmanL-DemiBold ZNKJEM+URWBookmanL-Ligh MWIUED+URWBookmanL-LighItal
type -----Type 1 Type 1 Type 1
emb --yes yes yes
sub --yes yes yes
uni object ID --- --------no 6 0 no 9 0 no 12 0
Hack #93: Welche Schriften gibt es im Dokument?
341
#93
HACK
#93
Welche Schriften gibt es im Dokument?
Dabei werden die Schriftnamen zwar durch einen eigenartigen Code verschandelt1 , aber das ist nichts, was Sie nicht notfalls mit etwas sed oder Perl in den Griff bekämen.
Anwendungen Diese Listen haben verschiedene Anwendungen. Zum einen können Sie, wie angedeutet, prüfen, welche Schriften Sie gegebenenfalls mit dem Dokument weitergeben müssen. Die Ausgabe von pdffonts gibt in der Spalte emb an, ob die Schrift in der PDF-Datei enthalten (embedded) ist; die Spalte sub gibt an, ob es sich um einen Ausschnitt (subset) der Schrift handelt oder die komplette Schrift. Wenn Sie es mit Schriften kommerzieller Anbieter wie Adobe oder Linotype zu tun bekommen, werden Sie feststellen, dass man Ihnen diese Schriften normalerweise nur unter ziemlich restriktiven Lizenzen zur Verfügung stellt. Insbesondere ist es der Horror eines kommerziellen Schriftanbieters, dass seine geheiligten Dateien irgendwie Fremden in die Hände fallen könnten. Ein Feature wie das von PDF, nur die wirklich benutzten Zeichen einer Schrift in die Datei aufnehmen zu können, spielt daher eine große Rolle für den Schutz des »geistigen Eigentums« von Schriftherstellern – selbst wenn man aus einer PDF-Datei die eingebetteten Schriften in verwendbarer Form zurückgewinnen kann, sind diese doch nicht viel wert, wenn das »Q« oder das »y« fehlen, weil sie in dem ursprünglichen Dokument aus irgendwelchen Gründen nicht vorkamen.
Die Schriftlisten sind auch nützlich dafür, festzustellen, ob sich in ein Dokument mit relativ stringenten Vorgaben über die zu verwendenden Schriften irgendwelche Irrläufer eingeschlichen haben. Spätestens wenn es um mathematische Sonderzeichen geht, ist es nämlich auch für das trainierte Auge nicht mehr sofort offensichtlich, aus welcher Schrift ein Zeichen stammt. Mit LATEX haben Sie grundsätzlich einen Vorsprung gegenüber Benutzern beliebiger Textverarbeitungsprogramme – Sie haben eine ziemlich explizite Kontrolle darüber, welche Schriften in Ihren Dokumenten vorkommen sollten, während in den gängigen Textverarbeitungsprogrammen alle möglichen fremdartigen und wundervollen Schriften nur einen Menü-Klick entfernt sind –, aber sicher ist bekanntlich sicher.
1
Dieser Code deutet an, dass nur eine Teilmenge der Schriftzeichen tatsächlich in der PDF-Datei vorliegt.
342
Kapitel 10: LATEX-Werkzeuge
HACK
Bequeme LATEX-Editoren
Siehe auch • Das »TeX-Guy«-Paket von Hirotsugu Kakugawa (http://www-masu.ist. osaka-u.ac.jp/~kakugawa/TeX-Guy/) enthält das Kommando dvifontlist, das eine etwas freundlichere Ausgabe produziert als dvitype: 19 pbkli8t scaled 1.2000, design size 10.000pt, scaled size 12.000pt 18 pbkd8t scaled 1.7280, design size 10.000pt, scaled size 17.280pt 16 pbkl8t scaled 1.2000, design size 10.000pt, scaled size 12.000pt
HACK
#94
Bequeme LATEX-Editoren Probieren Sie Kile und LyX aus.
Einer der großen Vorteile von LATEX ist, dass das System Sie nicht auf einen bestimmten Editor festlegt. Sie sind also völlig frei in der Wahl des Programms, mit dem Sie bei der Arbeit mit LATEX die meiste Zeit verbringen, und das ist mehr, als man für die meisten anderen Textprogramme sagen kann. Es besteht also kein Grund dafür, zum Schreiben von Texten, Briefen und Büchern nicht den Editor zu benutzen, den Sie auch zum Programmieren oder Editieren von Konfigurationsdateien verwenden. Viele populäre Editoren bringen sogar spezielle Unterstützung für die Arbeit mit TEX und LATEX mit (siehe zum Beispiel Lernfähiger Editor [Hack #95]). Trotzdem haben sich auch einige Editoren etabliert, die sich vor allem die Arbeit mit TEX auf die Fahne geschrieben haben. Hier stellen wir Ihnen zwei davon vor: Kile aus dem KDE-Projekt und LyX.
Der LATEX-Spezialist: Kile Kile präsentiert sich auf dem Bildschirm zuerst mit einem dreigeteilten Hauptfenster (siehe Abbildung 10-6). Links befindet sich (zunächst) eine Übersicht über die Dateien im aktuellen Verzeichnis, rechts oben eine Menge Platz für LATEX-Eingabedateien und rechts unten ein Bereich für Verlaufsmeldungen, etwa vom tex-Programm. Der Editor kann mehrere LATEX-Eingabedateien gleichzeitig offen halten, die dann über Karteireiter zu erreichen sind. Am oberen Rand des Fensters sind zwei Werkzeugleisten; die obere enthält diverse Operationen für die Dateiverwaltung und die Steuerung von LATEX und den dazugehörigen Programmen, die untere erlaubt die bequeme Eingabe von LATEXKonstrukten in die angezeigte Datei. Wenn Sie eine neue Datei öffnen wollen, erscheint zunächst eine Auswahl verschiedener Dokumentvorlagen (siehe Abbildung 10-7). Wählen Sie dort zum Beispiel article, wird das »Skelett« eines neuen Artikels als neue Datei geöff-
Hack #94: Bequeme LATEX-Editoren
343
#94
HACK
Bequeme LATEX-Editoren
H UGO S CHULZ Beispielstraße 53a 12345 Königs-Musterhausen Telefon: 0011/222 333 E-Mail:
[email protected] URL: www.example.com Hugo Schulz · Beispielstraße 53a · 12345 Königs-Musterhausen
Sabine Mustermensch Lindenstraße 44 54321 Anderswo
Königs-Musterhausen, 30. März 2007 Ihr Schreiben vom 35.5.2006
Sehr geehrte Frau Mustermensch, bezugnehmend auf Ihr o. g. Schreiben kann ich Ihnen mitteilen, dass wir Ihrem Ansinnen in vollem Umfang zustimmen. Es ist höchste Zeit dafür, sämtliche rosa Spitzendeckchen in der Seniorenresidenz »Silberner Oktember« durch lindgrüne Makrameeuntersetzer zu ersetzen. Wir sind sicher, Ihnen hierfür ein günstiges Angebot machen zu können, und warten auf Ihre Antwort. Mit freundlichen Grüßen,
Hugo Schulz
P. S.: Auch Himmelblau und Zartgelb können wir sehr empfehlen. Verteiler: The LYX Users
Abbildung 10-12: scrlttr2 und LyX – die Ausgabe
Hack #94: Bequeme LATEX-Editoren
349
#94
HACK
#95
Benutzen Sie AUCTEX im GNU Emacs
Auch direktes Drucken aus LyX ist möglich. Was LyX standardmäßig aus dem Brief macht, sehen Sie übrigens in Abbildung 10-12 – Sie können das natürlich nach Bedarf an Ihre Vorlieben anpassen. LyX ist eine patente Möglichkeit, LATEX zu verwenden, wenn man LATEX eigentlich gar nicht verwenden möchte. In diesem Buch wird es weniger erwähnt, weil wir befürchten, dass Sie LATEX zugunsten von LyX untreu werden könnten (in Hack 94 von 100 ist damit wohl kaum noch zu rechnen), sondern weil Sie es vielleicht Ihren Verwandten, Freunden und Bekannten empfehlen möchten. Wer weiß, vielleicht kommen sie ja auch noch auf den Geschmack, es mit dem echten LATEX zu versuchen . . . HACK
#95
Benutzen Sie AUCTEX im GNU Emacs Wie Sie sich im textorientierten Betriebssystem mit Editorfunktionen die Arbeit mit LATEX erleichtern
Im Gegensatz zu Kile und LyX [Hack #94] ist AUCTEX kein spezieller Editor für LATEX, sondern eine Erweiterung, die den populären GNU Emacs (oder X-Emacs) für die Arbeit mit LATEX (und TEX, ConTEXt und Texinfo, was uns hier aber nicht weiter interessiert) fit macht. Ähnlich wie Kile bietet AUCTEX diverse Eingabevereinfachungen sowie die Möglichkeit, LATEX-Dokumente aus dem Editor heraus mit LATEX und anderen Werkzeugen aus dessen Dunstkreis zu bearbeiten. Weitere Eigenschaften von AUCTEX, die wir anderswo in diesem Buch besprechen, sind die Sofortvorschau [Hack #97] und das Verweissystem RefTEX [Hack #98].
Eingabe von Texten AUCTEX enthält Abkürzungen zur Texteingabe auf einem mit Kile vergleichbaren Niveau. Sie können zum Beispiel Gliederungskommandos mit Hilfe der Tastenkombination »Strg+c, Strg+s« (im Emacs-Jargon »C-c C-s« vom englischsprachigen Namen der »Strg«-Taste, Control) eingeben. AUCTEX fragt Sie dann zuerst nach der gewünschten Gliederungsebene, dann nach dem Titel des Kapitels, Abschnitts (oder was auch immer) und schließlich nach dem Namen eines \labels. Für die Gliederungsebenen unterstützt AUCTEX eine Vervollständigung über die Tabulator- oder Leertaste. Umgebungen können Sie mit »C-c C-e« eingeben; auch hier vervollständigt AUCTEX eine partielle Eingabe so gut wie möglich, und ähnlich wie in Kile tut auch AUCTEX das »Richtige«, wenn Sie zum Beispiel eine itemize-Umgebung eingeben möchten: Ein »C-c C-e it Tab Return« genügt, und in Ihrem Dokument steht
350
Kapitel 10: LATEX-Werkzeuge
HACK
Benutzen Sie AUCTEX im GNU Emacs
\begin{itemize} \item \end{itemize}
mit dem Cursor direkt hinter dem \item. Um am Ende des ersten Listeneintrags mit dem nächsten \item fortzufahren, genügt übrigens ein »C-c C-j«. Versuchen Sie mal, eine figure oder table anzulegen – AUCTEX fragt Sie nach den Details und hilft Ihnen dabei, alles richtig zu machen. Und ein »C-c C-]« schließt die innerste noch offene Umgebung. Mit »C-c C-m« können Sie ein LATEX-Kommando eingeben. Auch hier unterstützt AUCTEX die Vervollständigung und hilft Ihnen bei etwaigen Argumenten (versuchen Sie mal, \newtheorem einzugeben, um einen Eindruck davon zu bekommen). »C-c C-f C-e« erlaubt die Eingabe von hervorgehobenem Text mit \emph, und in der AUCTEX-Dokumentation können Sie die Tastenkürzel für eine ganze Reihe anderer Schrift-Umschaltungen nachschlagen (aber denken Sie an das, was wir Ihnen über logische Auszeichnung [Hack #56] gesagt haben). Außerdem hilft AUCTEX Ihnen bei der Eingabe von Anführungszeichen, geschweiften Klammern und Ähnlichem, kann den aktuellen Absatz ein- und auskommentieren (»C-c %«) und verträgt sich mit dem Outline-Modus von Emacs.
Kommandos ausführen LATEX und alle Hilfsprogramme werden über das Kommando »C-c C-c« aufgerufen. AUCTEX rät, welches Programm jeweils am sinnvollsten ist, und macht Ihnen einen entsprechenden Vorschlag – normalerweise erst LATEX, dann ein Anzeigeprogramm. Allerdings erkennt AUCTEX auch oft, ob es an der Zeit ist, BibTEX oder makeindex aufzurufen. Unfehlbar ist es dabei allerdings nicht, und es kann schon sein, dass noch ein weiterer LATEX-Durchlauf nötig ist. »C-c C-r« benimmt sich wie »C-c C-c«, schickt aber nur die gerade markierte Region durch LATEX (natürlich mit der richtigen Präambel). Möchten Sie statt DVI PDF erzeugen, können Sie mit »C-c C-t C-p« umschalten (und auch wieder zurückschalten). Treten beim LATEX-Lauf Fehler auf, können Sie mit »C-c ‘« an die Stelle springen, wo der erste Fehler gefunden wurde. Die Fehlermeldung erscheint in einem anderen Emacs-Fenster. Ein weiteres »C-c ‘« transportiert Sie zum nächsten Fehler und so weiter. Normalerweise startet AUCTEX LATEX so, dass es Fehler übergeht und weiterzumachen versucht. Wenn Sie möchten, dass LATEX stattdessen anhält und nach einer Eingabe fragt, können Sie mit »C-c C-t C-i« den »interaktiven Modus« ein- oder ausschalten. Hack #95: Benutzen Sie AUCTEX im GNU Emacs
351
#95
HACK
Benutzen Sie AUCTEX im GNU Emacs
»Esc« und dann »x« zu drücken; alternativ können Sie auch die »Meta«-Taste festhalten, sofern Sie eine haben (bei Linux-Rechnern ist das gerne die linke »Windows«-Taste), und »x« drücken oder die »Menü«-Taste auf einer Windows-PC-Tastatur drücken. Wenn Sie den TeX-fold-mode für alle Ihre LATEX-Dokumente einschalten wollen, dann schreiben Sie in Ihre $HOME/.emacs-Datei etwas wie (add-hook ’LaTeX-mode-hook (lambda () (TeX-fold-mode 1)))
Nachdem der TeX-fold-mode eingeschaltet wurde, müssen Sie ihn nur noch mit »C-c C-o C-b« aktivieren. Dieses Kommando versteckt alles Versteckenswerte und kann auch verwendet werden, um den aktuellen Pufferzustand zu »aktualisieren«, indem alle seit dem letzten Aufruf hinzugekommenen Makros und Umgebungen mit bearbeitet werden. »C-c C-o b« macht diese Operation rückgängig, und »C-c C-o C-o« tut »das Richtige«: Wenn Sie es aufrufen, während der Cursor auf etwas ausgefaltetem Einfaltbarem steht, wird es eingefaltet; ist es schon eingefaltet, wird es wieder ausgefaltet.
Eigene Definitionen Sie können AUCTEX um Ihre eigenen Definitionen für Umgebungen, Makros und Ähnliches erweitern. In den meisten Fällen ist das gar nicht nötig, da AUCTEX die Pakete liest, die eine LATEX-Datei einbindet, und sich auf die Existenz der darin definierten Kommandos einstellt. Selber aktiv werden müssen Sie nur, wenn Sie den Benutzer bei der Eingabe von Umgebungen oder Makros nach zusätzlichen Informationen fragen wollen. Stellen Sie sich vor, Sie haben ein Paket greet implementiert, das das Makro \greeting zur Verfügung stellt: \newcommand*{\greeting}[2][Hallo]{#1 #2!}
Aufrufen würde man das ungefähr so: \greeting{Welt} (liefert Hallo Welt!) \greeting[Huhu]{Welt} (liefert Huhu Welt!)
Parallel dazu können Sie eine Datei greet.el zur Verfügung stellen, die ungefähr das Folgende enthält: (TeX-add-style-hook "greet" (lambda () (TeX-add-symbols ’("greeting" [ "Grussformel" ] "Grussobjekt"))))
Hack #95: Benutzen Sie AUCTEX im GNU Emacs
353
#95
HACK
#95
Benutzen Sie AUCTEX im GNU Emacs Tabelle 10-2: Einige Eingabemöglichkeiten für Makrodefinitionen in AUCTEX Parameter Zeichenkette Zahl nil t
Liste Vektor TeX-arg-label TeX-arg-cite TeX-arg-file TeX-arg-define-label
Bedeutung Eingabeaufforderung für ein Argument Fügt »Zahl« Paare von geschweiften Klammern ein, positioniert den Cursor im ersten Klammernpaar. Fügt ein leeres Klammerpaar ein. Fügt ein leeres Klammerpaar ein und positioniert den Cursor darin. Wenn das erste Element ein String ist: Benutze es als Eingabeaufforderung und das nächste Element als Eingabevorschlag. Wenn das erste Element etwas anderes ist: Rufe es mit dem Rest der Liste als Argumente auf. Optionales Argument. Wenn er nur ein Element hat, wird dieses Element wie sonst auch bearbeitet. Hat er mehr als ein Element, werden die Elemente als Liste bearbeitet. Fragt nach einem \label mit Vervollständigung. Fragt nach einem BIBTEX-Verweis. Fragt nach einer Datei im aktuellen Verzeichnis und fügt den Namen ohne Endung ein. Fragt nach einem \label mit Vervollständigung und merkt sich das Ergebnis als bekanntes \label.
Diese Datei könnten Sie zunächst in einem Unterverzeichnis style des aktuellen Verzeichnisses ablegen. Wenn Sie jetzt eine neue Datei anlegen, die \usepackage{greet}
enthält, müssen Sie diese Datei zunächst einmal abspeichern und neu laden, damit AUCTEX merkt, dass es auch die Anpassung für greet aus der Datei style/greet.el holen muss.2 Anschließend können Sie das Kommando \greeting mit Vervollständigung eingeben. Wenn Sie den Vorschlag akzeptieren, fragt AUCTEX als Nächstes: (Optional) Grussformel: _
Dort können Sie etwas eingeben wie »Aloha« und die Eingabe bestätigen. Danach erscheint Grussobjekt: _
und dort können Sie zum Beispiel »Hawaii« schreiben. Im Dokument landet dann Folgendes \greeting[Aloha]{Hawaii}
In solchen Definitionen können Sie auf eine Vielzahl von Eingaberoutinen zurückgreifen, die zum Beispiel die \labels oder Zähler Ihres Dokuments mit 2
Alternativ können Sie auch \usepackage über »C-c C-m« eingeben und sich nach dem Paketnamen fragen lassen – dann liest AUCTEX die Anpassung sofort ein.
354
Kapitel 10: LATEX-Werkzeuge
HACK
Vor- und Rückwärtssuche benutzen
Vervollständigung anbieten (siehe Tabelle 10-2). Wenn Sie Emacs-Lisp können, können Sie sogar Ihre eigenen Eingaberoutinen definieren.
HACK
#96
Vor- und Rückwärtssuche benutzen Springen Sie zwischen dem Quelltext und der LATEX-Ausgabe hin und her.
In der Welt der Textverarbeitungsprogramme ist »WYSIWYG« (What you see is what you get) inzwischen Standard – auf dem Bildschirm erscheint schon bei der Eingabe eine ans spätere Aussehen des Dokuments angenäherte Darstellung. Die Vor- und Nachteile dieses Ansatzes lassen sich lange debattieren, aber Tatsache ist, dass LATEX nicht so funktioniert: Sie haben die LATEX-Eingabedatei in einem Texteditor und die LATEX-Ausgabe (DVI oder PDF) in einem Anzeigeprogramm, und das wirft ein paar Probleme auf, die die WYSIWYG-Programme nicht haben. Stellen Sie sich vor, Sie haben gerade in Ihrer tex-Datei etwas geändert und möchten die entsprechende Stelle in der Ausgabe sehen. Oder Sie finden ein Problem (etwa einen Tippfehler oder eine überbreite Zeile) in der Ausgabe – wo ist die dazugehörige Stelle in der Eingabe? Die erste Frage ist ein Problem der Vorwärtssuche, die zweite eines der Rückwärtssuche. Für beide Sucharten gibt es Lösungen, die allerdings von den verwendeten Dateiformaten, Anzeigeprogrammen und Editoren (und damit auch den zugrunde liegenden Betriebssystemen) abhängen. Alle verfügbaren Ansätze beruhen darauf, dass zusätzliche Informationen über die Eingabedateien in die DVI- bzw. PDF-Datei geschrieben werden. Im Falle von DVI-Dateien können die gängigen TEX-Implementierungen das direkt, wenn Sie sie mit der Option »-src-specials« aufrufen: $ latex -src-specials my-book
Der Name »source specials« leitet sich dabei vom \special-Kommando in TEX her, das es erlaubt, spezielle Informationen in DVI-Dateien unterzubringen, die ursprünglich nicht im DVI-Format vorgesehen sind. TEX benutzt \special vor allem zur Grafikeinbindung und zur Unterstützung von Farben, aber auch die Zusatzinformationen zur Navigation beruhen auf dem Datenformat von \special – auch wenn TEX die entsprechenden Daten direkt in die DVI-Datei schreibt, ohne dafür explizite \special-Kommandos zu benötigen. Die Anwesenheit dieser Zusatzinformationen ist Voraussetzung dafür, dass die gezeigten Methoden funktionieren. Wir betrachten im Rest dieses Hacks die gängigsten Anwendungsfälle. Wenn Ihr TEX-Programm keine source specials unterstützt: Das LATEX-Paket srcltx von Aleksander Simonic und Stefan Ulrich
Hack #96: Vor- und Rückwärtssuche benutzen
355
#96
HACK
Vor- und Rückwärtssuche benutzen
ellen Versionen von AUCTEX können Sie dafür einfach den »TEX source specials mode« einschalten (die entsprechende Tastenkombination lautet »C-c C-s C-t«). Danach müssen Sie nur noch »C-c C-v« eingeben, und xdvi zeigt den Bereich der Ausgabe an, der mit der Position des Cursors in der Eingabedatei korrespondiert. Wenn Sie lieber vim verwenden, können Sie Folgendes ausführen: :execute "!xdvi -sourceposition " . line(".") . expand("%") . " " . expand("%:r") . ".dvi"
(alles auf einer Zeile) bzw. dieses Kommando einer Taste zuweisen, indem Sie die folgende Definition in Ihre $HOME/.vimrc-Datei aufnehmen: map :execute "!xdvi -sourceposition " \ . line(".") . expand("%") . " " . expand("%:r") \ . ".dvi"
Damit die Rückwärtssuche funktioniert, Sie also im Editor automatisch (ungefähr) an die Stelle springen können, die mit einem Punkt in der Ausgabe korrespondiert, muss xdvi wissen, wie er den Editor Ihrer Wahl mit Dateiname und Zeilennummer aufrufen muss. Dazu definieren Sie mit der Option »-editor« ein entsprechendes Kommando oder weisen das Kommando der X11-Ressource .editor zu: $ xdvi -editor "xterm -e vi +%l %f" sample2e.dvi
In dem Kommando werden »%f« durch den im nächstgelegenen source special benannten Dateinamen und »%l« durch die dazugehörige Zeilennummer ersetzt. Ist weder -editor angegeben noch die Ressource definiert, prüft xdvi die Umgebungsvariablen XEDITOR, VISUAL und EDITOR. Existiert auch von diesen keine, wird »xterm -e vi +%l %f« als Standardwert angenommen. Enthält das definierte Kommando kein %f oder %l, werden die fehlenden Informationen beim Aufruf einfach angehängt. Nachdem Sie diese Voreinstellung getroffen haben, können Sie die Strg-Taste festhalten und mit der linken Maustaste irgendwo in Ihre DVI-Datei klicken, damit xdvi versucht, den Editor mit der richtigen Datei und Position zu starten. Beachten Sie, dass ein einfacher Editoraufruf in der Regel dazu führt, dass ein neuer Editor gestartet wird. Wenn Sie sowieso schon an der betreffenden Datei arbeiten, ist das nicht das, was Sie wollen. Die meisten Editoren bieten aber die Möglichkeit, auf einen bereits laufenden Editor zurückzugreifen. Dazu setzen Sie die Umgebungsvariable EDITOR beispielsweise auf emacsclient --no-wait
Hack #96: Vor- und Rückwärtssuche benutzen
357
#96
HACK
#96
Vor- und Rückwärtssuche benutzen
wenn Sie GNU Emacs verwenden, und starten den »Emacs-Server«, indem Sie das Kommando »M-x server-start« ausführen oder »(server-start)« in Ihre .emacs-Datei schreiben. Auch wenn Sie den TEX source specials mode in AUCTEX aktivieren, wird gegebenenfalls ein Server gestartet. Im vim können Sie etwas verwenden wie gvim --remote
um an die passende Stelle in der Eingabe zu springen. Dies setzt allerdings den X11-basierten »grafischen« vim, den gvim, voraus. Die Vorwärts- und vor allem die Rückwärtssuche funktioniert in jedem Fall nur ungefähr, da TEX nicht für jedes Zeichen in der Eingabe markiert, wo es in der Ausgabe zu stehen kommt. Schon so werden die DVI-Dateien durch die source specials merklich aufgebläht. Ein anderer Punkt ist, dass möglicherweise große Textstücke aus der Expansion von Makros entstehen, wo die Position des Makroaufrufs in der Eingabe nicht wirklich viel mit der Stelle in der Eingabe zu tun hat, die man ändern müsste. Trotzdem sind diese Suchmöglichkeiten eine große Hilfe bei der Dokument-Erstellung. Beachten Sie, dass source specials möglicherweise zu einer Ausgabe führen, die anders aussieht als die Ausgabe ohne Erzeugung von source specials – Seitenumbrüche und Abstände können anders ausfallen, und die Erzeugung von source specials verträgt sich auch nicht mit jedem LATEX-Paket. Sie sollten deshalb Abstand davon nehmen, die Endfassung eines Dokuments mit source specials zu erzeugen. Vor allem sollten Sie die Seitenumbrüche eines Dokuments nicht optimieren, solange source specials eingeschaltet sind.
Vor- und Rückwärtssuche für PDF-Dateien Mit PDF-Dateien ist die Vor- und Rückwärtssuche aufwendiger, weil es keinen Mechanismus wie die \special-Kommandos von DVI gibt. Man ist noch mehr als bei DVI auf Näherungsmethoden angewiesen. Die Vorwärtssuche in PDF-Dateien wird derzeit über ein LATEX-Paket namens
pdfsync realisiert. Dieses Paket legt bei der Bearbeitung einer Datei meineda-
tei.tex eine neue Datei meinedatei.pdfsync an, die Positionsinformationen enthält. Die pdfsync-Datei wird nicht von PDF-Anzeigeprogrammen ausgewertet, sondern von einer TEX-Arbeitsumgebung wie AUCTEX, die dann ein PDF-Anzeigeprogramm mit geeigneten Parametern aufruft. Damit ist zunächst keine genauere Positionierung als diejenige auf der richtigen Seite möglich (tatsächlich garantiert AUCTEX laut Dokumentation nur eine Positionierung auf die richtige Seite plus oder minus eine).
358
Kapitel 10: LATEX-Werkzeuge
HACK
Vor- und Rückwärtssuche benutzen
#!/bin/sh [ -f $1 ] || exit 1 while true do for id in ‘dcop | grep kpdf‘ do doc=‘dcop $id kpdf currentDocument‘ if [ "‘basename $doc‘" = "$1" ] then dcop $id kpdf goToPage $2 dcop $id kpdf-mainwindow#1 raise exit 0 fi done kpdf $1 & sleep 3 done Abbildung 10-15: run-kpdf – KPDF aufrufen oder mit einem existierenden Prozess reden
Mit einer aktuellen AUCTEX-Version (unterstützt wird pdfsync seit AUCTEX 11.83) haben Sie eigentlich schon alles, was Sie brauchen, sofern Sie das pdfsync-Paket installiert haben. Sie müssen in Ihr Dokument nur ein \usepackage{pdfsync}
einbauen, den PDF-Modus und den TEX source special mode in AUCTEX einschalten und sind im Rennen. Nach einem pdfLATEX-Durchlauf sollte ein »C-c C-v« in Ihrer LATEX-Eingabedatei xpdf starten und die richtige Seite anzeigen. Wenn Sie an eine andere Stelle in Ihrem Dokument springen und wieder »C-c C-v« eingeben, blättert xpdf auf die entsprechende Seite; gegebenenfalls wird das xpdf-Fenster auch nach oben geholt. Da die ganze Arbeit von AUCTEX erledigt wird, gibt es keinen Grund, warum Sie nicht ein anderes PDF-Anzeigeprogramm außer xpdf verwenden sollten (xpdf ist ja nicht mehr der Weisheit letzter Schluss auf diesem Gebiet). Voraussetzung ist nur, dass das Programm sich von außen sagen lässt, welche Seite es anzeigen soll, ohne jeweils wieder eine neue Instanz von sich selbst zu starten. KPDF, das PDF-Programm von KDE, unterstützt das nicht über die Kommandozeile, sondern über das Kommunikationsprotokoll DCOP. Statt also kpdf neu aufzurufen, rufen wir gegebenenfalls dcop auf, ein Shellprogramm, das
Hack #96: Vor- und Rückwärtssuche benutzen
359
#96
HACK
#97
Ein Frühwarnsystem im Editor
DCOP-Nachrichten an KDE-Programme schicken kann. Das entsprechende Skript (run-kpdf) sehen Sie in Abbildung 10-15. Das Hauptärgernis in run-kpdf ist, dass es möglicherweise mehrere aktive KPDF-Prozesse in der aktuellen Sitzung gibt. Aus diesem Grund fragen wir jeden KPDF-Prozess nach dem Namen seines Dokuments und vergleichen diesen mit dem Namen der anzuzeigenden Datei. Stimmen die beiden überein, gehen wir davon aus, den richtigen KPDF gefunden zu haben, lassen ihn die gewünschte Seite ansteuern und holen das Fenster nach oben. Erklärt sich kein KPDF für zuständig, starten wir einen neuen mit der richtigen Datei. Die hier verwendete Technik hat eindeutig Hack-Qualität: Wenn wir beim ersten Mal keinen passenden KPDF gefunden haben, starten wir einen neuen und versuchen es noch mal, in der Hoffnung, dass sich das Programm bis zum dcop-Aufruf am Anfang der Schleife so weit berappelt hat, dass es vernünftig antwortet. Sollte etwas schiefgehen, könnten wir in eine Endlosschleife geraten. Betrachten Sie es als Herausforderung, run-kpdf zu verbessern.
Das Thema »Rückwärtssuche in PDF-Dateien« steckt ebenfalls noch ziemlich in den Kinderschuhen. Das LATEX-Paket vpe von Heiko Oberdiek lässt sich von Perl dabei helfen, \special-ähnliche Konstrukte in die PDF-Datei einzubauen. Zumindest Adobe Reader kann dann über anklickbare Marken in der PDF-Datei ein Programm aufrufen, das wiederum den gewünschten Editor aufruft. Das Ganze steht aber noch auf relativ wackligen Füßen, da die Positionierungsinformationen von LATEX eingefügt werden. Dafür werden alle möglichen LATEX-Interna umdefiniert, was selbst bei einfach scheinenden Eingabedateien zu Problemen führen kann. Hier ist sicherlich noch weitere Entwicklungsarbeit angesagt.
HACK
#97
Ein Frühwarnsystem im Editor Verwenden Sie preview-latex, um Formeln und Tabellen schon bei der Eingabe zu prüfen.
Normalerweise kann man es durchaus als Vorteil ansehen, dass LATEX nicht auf der Philosophie des What you see is what you get beruht. So können Sie immerhin in einem Editor mit einer schönen, für den Bildschirm optimierten Schrift arbeiten – und wenn Sie sehen wollen, wie Ihr Machwerk gedeiht, gibt es ja DVI- und PDF-Anzeigeprogramme, die ein präziseres Bild vermitteln als die meisten Textverarbeitungsprogramme. Aber eben nicht sofort, und in ein paar Situationen wäre das halt doch schon mal nützlich, zum Beispiel wenn Sie komplexe Formeln und Tabellen bearbeiten und sich direkt vergewissern wollen, dass Sie sich nicht auf dem Holzweg befinden.
360
Kapitel 10: LATEX-Werkzeuge
HACK
Referenzen mit Pfiff
Abbildung 10-18: Die Inhaltsverzeichnis-Ansicht von RefTEX
HACK
#98
Referenzen mit Pfiff Verwenden Sie RefTEX, um in Ihrem Buch den Überblick zu behalten.
Beim Schreiben eines längeren Dokuments, insbesondere eines Dokuments mit vielen Verweisen und Literaturangaben (denken Sie an eine Examensoder Doktorarbeit), kann es schwierig werden, den Überblick zu behalten. Abhilfe schafft hier RefTEX von Carsten Dominik, eine weitere Emacs-Erweiterung, die ebenfalls mit AUCTEX harmoniert. RefTEX wird seit einiger Zeit mit GNU Emacs mitgeliefert und kann leicht aktiviert werden, indem Sie die folgenden Zeilen in Ihre $HOME/.emacs-Datei aufnehmen: (add-hook ’LaTeX-mode-hook ’turn-on-reftex) (setq reftex-plug-into-AUCTeX t) (setq reftex-use-external-file-finders t) (setq reftex-external-file-finders ’(("tex" . "kpsewhich -format=.tex %f") ("bib" . "kpsewhich -format=.bib %f"))
(Die letzten vier Zeilen sorgen für eine bessere Integration ins eigentliche TEXSystem.) Wenn Sie das gemacht und Emacs neu gestartet haben, sollte in der Menüleiste ein Eintrag namens Ref erscheinen, wenn Sie eine LATEX-Eingabedatei bearbeiten.
Inhaltsverzeichnis Die erste nützliche Eigenschaft von RefTEX ist eine Inhaltsverzeichnis-Ansicht (siehe Abbildung 10-18), die Sie bekommen, indem Sie in einer LATEX-Eingabedatei »C-c =« eingeben (also »Strg festhalten, c drücken, Strg loslassen, = Hack #98: Referenzen mit Pfiff
363
#98
HACK
#98
Referenzen mit Pfiff
drücken«). Sie können in dieser Ansicht mit den Pfeiltasten navigieren. Ein Leerzeichen zeigt die betreffende Stelle im Dokument, ohne das Inhaltsverzeichnis zu verlassen, ein »Tab« springt an die Stelle im Dokument, lässt aber das Fenster mit dem Inhaltsverzeichnis geöffnet, während ein »Return« an die Stelle im Dokument springt und das Fenster mit dem Inhaltsverzeichnis schließt. Mit »l« werden \labels und mit »i« Indexeinträge ein- und wieder ausgeblendet. Es gibt zahlreiche andere Kommandos, die Sie am besten der Dokumentation entnehmen.
Querverweise Mit RefTEX können Sie einfach \labels zu Ihrem Dokument hinzufügen, indem Sie an der entsprechenden Stelle »C-c (« eingeben. RefTEX fragt Sie dann nach dem Namen, den das \label haben soll, und macht dafür einen halbwegs intelligenten Vorschlag. Steht etwa \chapter{Erstes Kapitel}
unmittelbar vor dem Punkt, wo Sie das \label haben möchten, so dass es sich auf diese Kapitelüberschrift bezieht, antwortet RefTEX im Emacs-Minibuffer mit: Label: cha:erstes-kapitel
Sie müssen jetzt nur noch »Return« drücken, um diesen Namen zu bestätigen. (Natürlich können Sie auch einen völlig anderen Namen wählen.) Von Marken, die Sie »manuell« eingeben, indem Sie das \labelKommando selber tippen, bekommt RefTEX erst einmal nichts mit. Es findet sie erst, wenn Sie das Dokument erneut durchsuchen, etwa über Parse Document im Ref-Menü.
Bezüge auf Querverweise erzeugen Sie ebenso einfach mit »C-c )«. RefTEX antwortet dann mit der etwas kryptischen Zeile Label type: [ efinNst]
(?=Help)
und fordert Sie damit auf, einen »Markentyp« auszuwählen. Die Leertaste steht dabei für »irgendeine Marke«, »s« für Gliederungsmarken und so weiter (die Hilfe, die Sie mit »?« erhalten, zeigt das genauer an). Nachdem Sie sich entschieden haben, zeigt RefTEX Ihnen eine Gliederungsansicht Ihres Dokuments mitsamt den definierten \labels des entsprechenden Typs, wo Sie sich bequem das Ziel Ihres Querverweises aussuchen können (siehe Abbildung 10-19). Sie müssen übrigens nicht raten: Ein Druck auf die Leertaste zeigt Ihnen in einem anderen Fenster den »Kontext« des betreffenden \labels, und mit »f« können Sie den follow mode ein- und ausschalten, der Ihnen beim
364
Kapitel 10: LATEX-Werkzeuge
HACK
Referenzen mit Pfiff
Abbildung 10-19: Markenauswahl mit RefTEX
Blättern durch die \labels in der Gliederungsansicht immer den betreffenden Kontext zeigt.
Literaturverweise RefTEX unterstützt auch Literaturverweise. Dabei läuft es zu besonderer Form auf, wenn Sie BibTEX verwenden, um Ihre Zitate zu verwalten. Notfalls kommt es auch mit einer thebibliography-Umgebung im Dokument selbst zurecht, aber das ist dann nicht so komfortabel. Mit »C-c [« fragt RefTEX Sie nach einem regulären Ausdruck, der anschließend in den bib-Dateien gesucht wird, die Ihr Dokument verwendet (RefTEX orientiert sich dabei am Argument eines \bibliography-Kommandos). Sie können auch ein »logisches Und« verwenden: Ein Eintrag wie Stevens&&TCP
sucht nach Zitaten, die von einem Autor namens »Stevens« verfasst wurden und »TCP« enthalten.3 RefTEX schlägt das Wort vor dem Cursor als Suchbegriff vor – oftmals liegt es da gar nicht falsch, etwa bei Konstruktionen wie Laut Stevens _
Das Suchergebnis erscheint in einem neuen Emacs-Fenster, in dem Sie ähnlich wie in der Markenauswahl navigieren können, um den Eintrag zu finden, den 3
RefTEX ist da ziemlich tolerant: Der umgekehrte Fall – ein Werk, das von einem Autor namens »TCP« verfasst wurde und »Stevens« im Titel hat – würde auch gefunden . . . Sie wissen schon.
Hack #98: Referenzen mit Pfiff
365
#98
HACK
#98
Referenzen mit Pfiff
Abbildung 10-20: Literaturverweise mit RefTEX
Sie eigentlich haben wollen. Sie können mehrere Werke auf einmal zitieren, indem Sie sie mit »m« markieren. Die Leertaste zeigt in einem anderen Fenster den kompletten BibTEX-Datenbankeintrag für das aktuelle Werk, und auch hier aktiviert »f« einen follow mode, der beim Suchen in den gefundenen Einträgen immer den betreffenden Eintrag im anderen Fenster zeigt. Wie üblich bietet RefTEX viel mehr, als wir hier diskutieren können – schlagen Sie in der Dokumentation nach! RefTEX kommt mit diversen Zitiermethoden zurecht. Wenn Sie eins der Autor-Jahr-Pakete wie natbib, harvard oder jurabib benutzen, stellt es Ihnen beim Einfügen des Literaturverweises ein Menü von Kommandos zur Verfügung, die in Frage kommen. Es gestattet auch die Eingabe von optionalen Zusätzen der Form \cite[Kap.~3]{stevens}
Eine nützliche Funktion von RefTEX besteht darin, eine BibTEX-Datenbank zu erzeugen, die nur die Einträge für die im aktuellen Dokument zitierten Werke enthält. Das entsprechende Kommando lautet »M-x reftex-create-bibtex-file«.
Wer verweist auf mich? Wenn Sie den Cursor auf das Argument eines Makros stellen, das mit Queroder Literaturverweisen zu tun hat – normalerweise \label, \ref oder \cite –, und »C-c &« eingeben, zeigt RefTEX Ihnen in einem anderen Fenster die Stellen, die am »anderen Ende« des Verweises stehen: Bei \ref bekommen Sie das entsprechende \label gezeigt, bei \label können Sie mit wiederholten
366
Kapitel 10: LATEX-Werkzeuge
HACK
Von LATEX zu HTML
Eingaben von »C-c &« alle Stellen durchlaufen, die auf die betreffende Marke verweisen.
HACK
#99
Von LATEX zu HTML Benutzen Sie plasTEX, um aus Ihrem LATEX-Dokument HTML zu erzeugen.
DVI und PDF sind nicht immer die bequemsten Zielformate für ein Dokument – im Zeitalter des Internet kann es durchaus sein, dass Sie ein Dokument auch im HTML-Format ins Netz stellen wollen. Natürlich wäre es mehr als ärgerlich, Ihr schönes LATEX-Dokument mit der Hand zu etwas vergewaltigen zu müssen, was ein Webbrowser anzeigen kann. Eigentlich sollte das automatisch gehen. Die LATEX-Szene stellt eine ganze Reihe von Programmen zur Verfügung, die LATEX nach HTML konvertieren. Der Haken ist dabei normalerweise die Mathematik, die in HTML nicht direkt abgebildet werden kann (allen entsprechenden Versuchen, dafür einen Standard zu etablieren, zum Trotz). Der gängige Trick besteht darin, alles, was irgendwie nach komplizierter Mathematik aussieht, als Grafik darzustellen. Man kann sich natürlich darüber streiten, ob das eine gute Idee ist – es treibt den Aufwand für das Laden der entsprechenden Seiten in die Höhe und macht es nahezu unmöglich, sie ohne spezielle Software lokal abzuspeichern oder zu durchsuchen –, aber wenn die Alternative darin besteht, Formeln entweder als rohen LATEX-Code oder aber gar nicht anzuzeigen, ist die Lage relativ klar. Vergleicht man »traditionelle« Dokumente (etwa Monografien oder Bücher) und Dokumente im World Wide Web, werden einige Unterschiede offensichtlich. Traditionelle Dokumente sind in der Regel fortlaufend mit einer sich aufdrängenden Lesereihenfolge (das vorliegende Buch bildet da zum Beispiel eine Ausnahme), während Dokumente im World Wide Web, wie der Name schon sagt, einen »vernetzten« Charakter haben, bei dem nicht notwendigerweise eine bestimmte Lesereihenfolge vorgegeben ist (auch wenn das natürlich im Einzelfall vorkommen kann). Diese Beobachtung hat naheliegende Konsequenzen für die Übersetzung von LATEX nach HTML – wenn ein Übersetzungsprogramm schon nicht aus einem »linear« geschriebenen Text automatisch einen Hypertext im Sinne von Ted Nelson machen kann, dann kann es doch zumindest dafür sorgen, dass das resultierende Dokument aus einer Menge von überschaubaren Häppchen mit bequemen Navigationsmöglichkeiten besteht statt aus einer einzigen kilometerlangen HTML-Seite. Das Urgestein auf dem Gebiet der LATEX-nach-HTML-Konverter ist das Programm LATEX2HTML, ursprünglich von Nikos Drakos und zuletzt gewartet von Ross Moore. Andere ähnliche Programme sind im Umlauf, etwa TEX4ht Hack #99: Von LATEX zu HTML
367
#99
HACK
#99
Von LATEX zu HTML
von Eitan Gurari, aber die meisten haben die Eigenschaft gemeinsam, dass sich seit Jahren niemand mehr um sie kümmert (warum auch immer). Wir zeigen hier ein modernes System namens »plasTEX« von Kevin Smith, das zumindest den Eindruck erweckt, als wäre es noch am Leben. Außerdem verfolgt es den interessanten Ansatz, die Analyse des LATEX-Dokuments und die Erzeugung der HTML-Ausgabe so weit wie möglich zu trennen. Das macht es möglich, statt HTML auch ganz andere Ausgabeformen zu erzeugen (etwa Braille) oder die Ausgabe ganz anders zu strukturieren als die Eingabe (es gibt also noch Hoffnung für Mr. Nelson). plasTEX ist ein Python-Programm, und Sie finden es unter http://plastex.sourceforge.net.
plasTEX-Installation Wenn Sie mit plasTEX HTML-Seiten erzeugen wollen (die Hauptanwendung), brauchen Sie neben Python die Python Imaging Library (alles zu finden unter http://www.python.org/), eine LATEX-Distribution (sollten Sie bereits haben) sowie entweder Ghostscript oder besser dvi2bitmap oder dvipng. Letzteres ist auch für preview-latex nötig, so dass sich die Installation lohnt. Gut sortierte Linux-Distributionen wie Debian GNU/Linux enthalten diese Software in Form vorgefertigter Pakete, so dass Sie sich nur plasTEX besorgen und installieren müssen. Sind alle Vorbedingungen erfüllt, geht das einfach mit folgender Angabe im plasTEX-Distributionsverzeichnis: # python setup.py install
HTML erzeugen Im einfachsten Fall rufen Sie plasTEX mit dem Namen der zu konvertierenden Datei als Parameter auf: $ plastex sample2e.tex
plasTEX erzeugt dann eine HTML-Version der Datei in einem Unterverzeichnis, das so heißt wie die Datei selbst, aber ohne die Endung .tex: $ ls sample2e icons index.html __init__.pyc images __init__.py sect0001.html
sect0002.html styles
Dabei ist index.html die »Hauptseite« des Dokuments, die normalerweise ein Inhaltsverzeichnis enthält. Die zwei Abschnitte des ursprünglichen Textes korrespondieren mit den Dateien sect0001.html und sect0002.html. Im Unterverzeichnis icons befinden sich grafische Elemente für die Navigation, und in images stehen Bilddateien für alles, was plasTEX nicht in HTML umsetzen 368
Kapitel 10: LATEX-Werkzeuge
HACK
Von LATEX zu HTML
Abbildung 10-21: sample2e.tex als HTML-Dokument, mit plasTEX konvertiert
konnte (normalerweise mathematische Formeln). Das Unterverzeichnis styles enthält Stylesheets, die plasTEX automatisch erzeugt hat. Sie können diese Dateien anpassen, um das Aussehen der HTML-Version Ihres Dokuments zu ändern. Mit einem Webbrowser betrachtet sieht das Dokument aus wie in Abbildung 10-21. Beachten Sie die Navigationselemente und die abgesetzte Formel im Fenster rechts unten. Sie können das Verhalten von plasTEX über Kommandooptionen steuern. Zum Beispiel erzeugt $ plastex --theme=python sample2e.tex
Navigationselemente, die an die Online-Python-Dokumentation angelehnt sind; das Thema plain dagegen erzeugt schlichte textbasierte Navigationselemente. Mit der Option »--split-level« können Sie steuern, wie die Ausgabe in Dateien aufgeteilt wird. Der Parameter ist eine LATEX-Hierarchiestufe (siehe Tabelle 5-1), und für jedes Objekt auf einer Hierarchiestufe kleiner oder gleich dem
Hack #99: Von LATEX zu HTML
369
#99
HACK
#99
Von LATEX zu HTML
hier angegebenen Wert wird eine neue Datei angegeben. Der Standardwert 2 führt also dazu, dass außer für das ganze Dokument (index.html) auch für jeden Teil, jedes Kapitel, jeden Abschnitt und jeden Unterabschnitt eine eigene Datei angelegt wird. Die Option »--dir« (oder »-d«) dient dazu, das Verzeichnis für die Ausgabedateien festzulegen. Der Standardwert wird (wie erwähnt) vom Namen der Eingabedatei abgeleitet. Tatsächlich unterstützt plasTEX noch zahlreiche andere Kommandooptionen. Die plasTEX-Dokumentation enthält eine komplette Liste.
Interna Beim Einlesen konvertiert plasTEX das LATEX-Dokument in eine interne Darstellung, die dem DOM einer XML-Datei ähnelt. Tatsächlich können Sie als Python-Programmierer XML-DOM-Methoden verwenden, um auf die interne Darstellung zuzugreifen, sie zu verändern, Dinge zu löschen oder einzufügen – aber das würde für dieses Buch zu weit führen. plasTEX kann LATEX-Kommandos und -Pakete verstehen und als solche verarbeiten. Allerdings können Sie auch »Implementierungen« von Kommandos und Paketen in Python zur Verfügung stellen, die besondere Dinge tun. Damit haben Sie die volle Kontrolle darüber, was in die Ausgabe geschrieben wird, und können Fälle bequemer behandeln, die für plasTEX zu kompliziert wären, wenn sie in primitive TEX-Kommandos expandiert werden. Insbesondere können Sie die Expansion verhindern, wenn das Programm, das die Ausgabe für plasTEX erzeugt, mit der unexpandierten Eingabe mehr anfangen kann. Im einfachsten Fall können Sie plasTEX daran hindern, sich Dinge anzusehen, die für seinen kleinen Kopf zu kompliziert sind. plasTEX definiert beim Lesen einer LATEX-Datei ein internes TEX-Kommando \ifplastex, das immer auf »wahr« gesetzt ist. Sie müssen nur dafür sorgen, dass LATEX es als »falsch« interpretiert – etwas wie \newif\ifplastex \plastexfalse
genügt (tatsächlich sind neu angelegte \if...-Kommandos immer »falsch«, aber sicher ist sicher). Sie können dann dafür sorgen, dass plasTEX komplizierte Kommandos nicht zu sehen bekommt: \ifplastex \newenvironment{complicated}{}{} \else \newenvironment{complicated}{%
370
Kapitel 10: LATEX-Werkzeuge
HACK
Von LATEX zu HTML
% Etwas sehr Kompliziertes }{ % Noch etwas sehr Kompliziertes } \fi
Oder Sie können ein Kommando implementieren, das sich für LATEX und plasTEX unterschiedlich auswirkt: \newcommand{\bla}[1]{% \ifplastex\else\addvspace{1cm}\fi \textbf{\Large #1} \ifplastex\else\vspace*{1cm}\fi }
In Python werden sowohl Kommandos als auch Umgebungen als Klassen definiert. plasTEX bringt dafür die Basisklassen Command und Environment mit. Beide haben ein Attribut args, mit dem Sie vorgeben können, wie das Kommando bzw. das \begin der Umgebung mit Argumenten umgeht. Hier ist ein Beispiel aus der plasTEX-Dokumentation: from plasTeX import Command class framebox(Command): """ \framebox[width][pos]{text} """ args = ’[ width ] [ pos ] text’
Stößt plasTEX beim Verarbeiten der Eingabe auf das \framebox-Kommando, erzeugt es ein Python-framebox-Objekt und schreibt die drei Argumente (soweit vorhanden) in das Attribut attributes, ein Dictionary. Sie können auf die Werte dann über Konstrukte wie self.attributes[’width’]
zugreifen. Nicht tatsächlich vorhandene optionale Argumente haben in Python den Wert none. Es ist auch möglich, Datentypen anzugeben (die plasTEXDokumentation geht hier mehr ins Detail): class framebox(Command): """ \framebox[width][pos]{text} """ args = ’[ width:dimen ] [ pos:chr ] text’
Damit weiß Python, dass das erste Argument eine Länge ist und das zweite ein Text, der sich möglicherweise noch aus Kommandoexpansion ergibt. Die eigentliche Arbeit für ein Kommando oder eine Umgebung erledigt eine Methode namens invoke. Sie kümmert sich darum, die Argumente zu analyHack #99: Von LATEX zu HTML
371
#99
HACK
#99
Von LATEX zu HTML
sieren, etwaige Zähler zu erhöhen und so weiter, und in den meisten Fällen müssen Sie sich nicht gezielt darum kümmern, solange Sie die Basisklassen von plasTEX verwenden. Hier sehen Sie (wiederum angelehnt an die plasTEXDokumentation), wie Sie eine Umgebung colored definieren können, die ihren Inhalt in einer bestimmten Farbe darstellt. In HTML regeln wir das über das style-Attribut eines colored-Objekts, das bei der HTML-Ausgabe als Inline-CSS verwendet wird: from plasTeX import Environment def htmlcolor(arg): if ’,’ in arg: # RGB-Farbe red, green, blue = [float(x) for x in arg.split(’,’)] red = min(int(red * 255), 255) green = min(int(green * 255), 255) blue = min(int(blue * 255), 255) else: try: # Graustufe? red = green = blue = float(arg) except ValueError: # Benannte Farbe (ob das wohl gut geht?) return arg.strip() return ’#%.2X%.2X%.2X’ % (red, green, blue) class colored(Environment): args = ’color:str’ def invoke(self, tex): a = Environment.invoke(tex) self.style[’color’] = htmlcolor(a[’color’])
Auch hier geht die plasTEX-Dokumentation weit mehr ins Detail. In Python definierte plasTEX-Pakete werden von plasTEX geladen wie andere Python-Module auch, wenn in der Eingabe ein entsprechendes \usepackage oder \RequirePackage vorkommt. Wenn das Python-Modul für eine Klasse eine Funktion namens ProcessOptions enthält, wird diese Funktion mit zwei Argumenten aufgerufen, nämlich einem Dictionary, das die Optionen aus dem \usepackage enthält, und einem »Dokumentobjekt«, das plasTEX verwendet, um den Lesevorgang zu steuern. Es ist auch möglich, direkt im Dokumentobjekt neue Kommandos und Umgebungen zu definieren, wenn diese so einfach sind, dass es sich nicht lohnt, dafür extra eine Python-Klasse zu definieren.
372
Kapitel 10: LATEX-Werkzeuge
HACK
Ganz subversiv
Die dafür nötige Vorgehensweise ist in der plasTEX-Dokumentation in mehr Detail beschrieben. plasTEX ist ein durchaus vielversprechender Ansatz für die automatische Verarbeitung von LATEX-Code – die HTML-Erzeugung ist, wie erwähnt, nur eine Anwendung. Man könnte zum Beispiel daran denken, DocBook-XML oder OpenDocument zu generieren. Die saubere Trennung von Einlese- und Erzeugungsvorgang sowie die überschaubare objektorientierte Basis mit DOM sind sicherlich Vorteile gegenüber älteren Programmen wie LATEX2HTML oder TEX4ht. HACK
#100
Ganz subversiv Verwenden Sie das Revisionskontrollsystem Subversion.
Die wenigsten Dokumente fallen völlig fertig vom Himmel. Stattdessen ergeben sie sich über einen längeren Zeitraum hinweg in einem mehr oder weniger anstrengenden und chaotischen Prozess, der sich potenziert, je mehr Autoren an ihrer Erstellung beteiligt sind.4 In so einer Situation den Überblick zu behalten ist genauso lebenswichtig wie kompliziert. Viele Textverarbeitungsprogramme haben eine Funktion »Änderungen sichtbar machen«, mit der Löschungen und Hinzufügungen zwischen verschiedenen Versionen eines Dokuments angezeigt werden können. LATEX macht das nicht selbst, sondern erlaubt – da es ja so etwas ist wie eine Programmiersprache – die Anwendung sogenannter Revisionskontrollsysteme, die sonst benutzt werden, um Ordnung in große Programmierprojekte zu bringen. Das heißt einerseits, dass Sie noch ein externes Werkzeug auswählen und lernen müssen; andererseits gehen die Fähigkeiten gängiger Revisionskontrollsysteme weit über das hinaus, was Textverarbeitungsprogramme so zu bieten haben, und eventuell benutzen Sie ja schon ein solches System zum Programmieren, so dass es keinen Grund gibt, für Ihre Dokumente etwas anderes zu verwenden. Das Feld der frei verfügbaren Revisionskontrollsysteme ist weit und wird von diversen Projekten mit großem Elan bestellt. Wir zeigen Ihnen hier die Anfangsgründe von Subversion, einem vergleichsweise einfachen, aber weitverbreiteten Revisionskontrollsystem. Wenn Sie mehr über Subversion erfahren wollen, können Sie zum Beispiel das Buch Versionskontrolle mit Subversion von Ben Collins-Sussman, Brian W. Fitzpatrick und C. Michael Pilato lesen, das bei O’Reilly erschienen ist (ISBN 978-3-89721-460-6). 4
Dabei denken wir an Robert A. Heinleins Beobachtung: »Ein Komitee ist eine Lebensform mit sechs oder mehr Beinen und ohne Gehirn.«
Hack #100: Ganz subversiv
373
#100
HACK
#100
Ganz subversiv
Grundbegriffe von Subversion Subversion beruht auf der Idee eines zentralen Repository (hierzulande müsste man wohl »Lager« sagen, wenn das englische Wort noch keinen Eingang ins »Neudeutsche« gefunden hätte), in dem die »offiziellen« Versionen aller Dateien eines Projekts abgelegt sind. Benutzer können sich Arbeitskopien von Dateien im Repository holen, sie ändern und die Arbeitskopie dann wieder ins Repository zurückschreiben, wodurch sich eine neue Version des Repository ergibt. Subversion sorgt dafür, dass es keine Probleme gibt, wenn mehrere Benutzer gleichzeitig dieselbe Datei geändert haben: Entweder überlappen die Änderungen sich nicht, dann kann Subversion sie automatisch unter einen Hut bringen, oder sie überlappen sich, dann weigert Subversion sich, die späteren Änderungen ins Repository zu übernehmen, solange die Benutzer nicht dafür gesorgt haben, dass sich die Änderungen nicht widersprechen.
Arbeit mit Subversion Sie können mit Subversion folgendermaßen ein neues Repository anlegen: $ svnadmin create /home/hugo/project
Dadurch wird im Verzeichnis /home/hugo/project ein neues Repository angelegt. Wir gehen hier erst einmal davon aus, dass Sie der einzige Benutzer des Repository sind. Wenn Sie im Team arbeiten, sollten Sie das Repository an einer Stelle unterbringen, wo die anderen Teammitglieder auch darauf zugreifen können (etwa auf einer Platte in einem Netzwerkserver), oder es über das Netz zugänglich machen (mit Apache oder dem Subversion-eigenen Dateiserver). Diese Themen sind für diese Einführung aber zu abgehoben.
Anschließend können Sie sich eine (leere) Arbeitskopie holen: $ mkdir work; cd work $ svn checkout file:///home/hugo/project Ausgecheckt, Revision 0. $ cd work/project
In dieser Arbeitskopie können Sie jetzt Ihr Dokument neu anlegen oder Dateien aus einem anderen Verzeichnis kopieren. Anschließend müssen Sie diese Dateien bei Subversion anmelden, bevor Sie die aktuelle Version amtlich machen: $ svn add buch.tex kapitel1.tex kapitel2.tex A buch.tex
374
Kapitel 10: LATEX-Werkzeuge
HACK
Ganz subversiv
A kapitel1.tex A kapitel2.tex $ svn commit -m "Neu angefangen" Hinzufügen buch.tex Hinzufügen kapitel1.tex Hinzufügen kapitel2.tex Übertrage Daten ... Revision 1 übertragen.
Subversion hat den aktuellen Status Ihrer Dateien als Revision 1 gespeichert. Mit »svn log« können Sie sich ein Bild davon machen, welche Revisionen im Repository existieren: $ svn log 0:HEAD -----------------------------------------------------------------r1 | anselm | 2007-03-31 00:45:49 +0200 (Sa, 31 Mär 2007) | 1 line Neu angefangen ------------------------------------------------------------------
(HEAD bezieht sich immer auf die neueste Version im Repository.) Die Meldung hier ist das, was Sie beim »svn commit« mit der Option »-m« eingegeben haben. Diese Methode eignet sich gut für kurze Meldungen; wenn Sie keine solche Option angeben, dann startet Subversion einen Editor, in dem Sie eine Meldung eingeben können. Anschließend können Sie die Dateien in Ihrer Arbeitskopie beliebig verändern. Mit »svn status« können Sie abfragen, wie sich Ihre Arbeitskopie gegenüber der letzten Revision verhält, die Sie vom Repository geholt oder dorthin geschickt haben – Sie sehen also, welche Änderungen Sie in Ihrer Arbeitskopie gemacht haben: $ svn status ? kapitel3.tex M kapitel1.tex
Hier haben wir kapitel1.tex geändert (»M« wie modified), und kapitel3.tex ist neu dazugekommen – Subversion kennt die Datei noch nicht. Wenn wir sie hinzufügen und »svn commit« ausführen, werden alle Änderungen amtlich gemacht: $ svn add kapitel3.tex A kapitel3.tex $ svn status M kapitel1.tex
Hack #100: Ganz subversiv
375
#100
HACK
#100
Ganz subversiv
A kapitel3.tex $ svn commit Sende kapitel1.tex Hinzufügen kapitel3.tex Übertrage Daten ... Revision 2 übertragen.
Sie können auch Dateien kopieren, umbenennen oder löschen; statt der üblichen Kommandos cp, mv und rm sollten Sie aber »svn copy«, »svn move« und »svn delete« verwenden, damit Subversion die Änderungen protokollieren kann. Wenn Sie in der Arbeitskopie etwas geändert haben, können Sie sich mit »svn diff« die Unterschiede zwischen Ihren aktuellen Dateien und der letzten mit dem Repository abgeglichenen Fassung anzeigen lassen: $ vi kapitel2.tex # Hack, hack ... $ svn diff Index: kapitel2.tex ======================================================== --- kapitel2.tex (Revision 1) +++ kapitel2.tex (Arbeitskopie) @@ -2,7 +2,9 @@ \section{Erster Abschnitt des zweiten Kapitels} -Bla fasel. +Bla fasel blubb. +Zweite Zeile. +Letzte Zeile. \section{Zweiter Abschnitt des zweiten Kapitels}
Das erste Zeichen jeder Zeile gibt an, was mit der betreffenden Zeile passiert: Zeilen mit »-« fallen weg, Zeilen mit »+« am Anfang kommen neu dazu. Änderungen in einer Zeile führen dazu, dass die alte Zeile wegfällt und die geänderte Zeile dazukommt. Zeilen mit einem Leerzeichen am Anfang sind noch so, wie sie waren, werden aber mit angezeigt, um einen »Kontext« zu etablieren. Sie können beliebige alte Revisionen Ihres Dokuments rekonstruieren: $ svn checkout -r1 # Hole Version 1 zurück $ svn checkout -r {2007-03-29} # Version mit Datum
376
Kapitel 10: LATEX-Werkzeuge
HACK
Ganz subversiv
Ebenso können Sie die Unterschiede zwischen zwei beliebigen Revisionen bestimmen: $ svn diff -r1:HEAD
Sollten Sie sich mal schlimm vertan haben, ist es einfach, eine Datei auf den Stand vom letzten Repository-Abgleich zurückzubringen: $ svn revert kapitel2.tex Rückgängig gemacht: »kapitel2.tex«
Das gilt übrigens nicht nur für inhaltliche Änderungen, sondern auch für Änderungen des Status vis-à-vis Subversion. Zum Beispiel können Sie damit ein »svn add« oder »svn delete« stornieren.
Branches Interessant wird es, wenn mehrere Versionen Ihres Dokuments parallel existieren. Stellen Sie sich vor, ein paar Kapitel Ihres Buchs werden gerade von einem Korrektor in die Mangel genommen, der in den LATEX-Dateien diverse Tipp-, Rechtschreib- und Kommafehler geraderückt. In der Zwischenzeit machen Sie aber auch noch die eine oder andere kleine Änderung an den Dateien. Ihre Aufgabe ist später, diese Korrekturen wieder unter einen Hut zu bringen. Für diese Anwendung empfiehlt sich eine leicht veränderte Organisation Ihres Repository. Statt eines einzigen Verzeichnisses (project) sollten Sie zwei Verzeichnisse (project/trunk und project/branches) einrichten. Das ist auch nachträglich möglich (wenn auch nicht so schön): $ svn A $ for A sD A svD ... $ svn A $ svn
mkdir trunk trunk f in *.tex; do svn move $f trunk; done trunk/buch.tex buch.tex trunk/kapitel1.tex kapitel1.tex mkdir branches branches commit -m "Verzeichnisstruktur geändert"
Sie können jetzt einen Status Ihres Projekts »festnageln«, indem Sie ihn in ein Unterverzeichnis von project/branches kopieren: $ svn copy file:///home/hugo/project/trunk \ > file:///home/hugo/project/branches/korr \
Hack #100: Ganz subversiv
377
#100
HACK
#100
Ganz subversiv
>
-m "Branch für Korrektor angelegt"
Revision 4 übertragen. $ svn update A branches/korr A branches/korr/buch.tex ... Aktualisiert zu Revision 4.
(Das »svn update« am Schluss bringt die Arbeitskopie auf den neuesten Stand gegenüber dem Repository – das ist nötig, weil wir die Kopieroperation nur im Repository durchgeführt haben, nicht in der Arbeitskopie.) Anschließend können Sie die Dateien unterhalb von branches/korr an den Korrektor schicken. Wenn Sie das Resultat (oder ein Zwischenergebnis) zurückbekommen haben, stellen Sie es wieder in branches/korr und machen es amtlich: $ cd branches/korr # Dateien vom Korrektor hierhin kopieren $ svn commit
In Ihrem Repository gibt es damit zwei unabhängige »Entwicklungslinien« – Ihre eigene in trunk und die des Korrektors in branches/korr. Ihre Aufgabe ist als Nächstes, die Änderungen des Korrektors in Ihre eigene (möglicherweise auch geänderte) Entwicklungslinie einfließen zu lassen. Das heißt, Subversion bestimmt die Unterschiede zwischen der aktuellen Revision auf branches/korr und der Revision, die durch den Kopiervorgang von trunk nach branches/korr entstanden ist, und versucht diese Unterschiede in die letzte Version auf trunk zu integrieren: $ cd $HOME/project/trunk $ svn log --stop-on-copy \ > file:///home/hugo/project/branches/korr ... r4 | anselm | 2007-03-31 01:24:24 +0200 (Sa, 31 Mär 2007) | 1 line Branch für Korrektor angelegt -----------------------------------------------------------------$ svn update # Zur Sicherheit! Revision 6. $ svn merge -r 4:HEAD \ > file:///home/hugo/project/branches/korr U kapitel1.tex U kapitel2.tex
378
Kapitel 10: LATEX-Werkzeuge
HACK
Ganz subversiv
U kapitel3.tex $ svn commit -m "Änderungen vom Korrektor (-r4:6) integriert"
Mit »svn log« können Sie herausfinden, wo genau die Korrektorversion erzeugt wurde (falls Ihr Gedächtnis so schlecht ist wie unseres). Das »svn merge« integriert die Änderungen, die in branches/korr von dieser Version bis zum HEAD vorgenommen wurden, in die aktuellen Dateien in trunk, und mit »svn commit« werden diese Änderungen in der Hauptversion amtlich gemacht. Sie sollten auf jeden Fall protokollieren, welchen Bereich von Änderungen Sie integriert haben, da Subversion das nicht für Sie übernimmt und es zu Problemen kommen kann, wenn Sie dieselben Änderungen mehrmals übertragen wollen.
Ausblick Das beschließt unseren kleinen Subversion-Crashkurs. Sie können jetzt Änderungen an Ihren Dokumenten sauber verfolgen und sogar verschiedene Quellen von Änderungen auseinanderhalten und verwalten. Mit dem BranchesMechanismus können Sie auch eine »Entwicklungs«- und eine »stabile« Version Ihres Dokuments parallel führen. Dafür und für vieles andere mehr, etwa wie Sie sich ein Repository zu mehreren Autoren teilen können, verweisen wir Sie allerdings auf die entsprechende Literatur, zum Beispiel das oben genannte Subversion-Buch.
Hack #100: Ganz subversiv
379
#100
HACK
#100
Ganz subversiv
380
Kapitel 10: LATEX-Werkzeuge
Index
Symbole \, 57, 62 \- 10 \; 126 \@ 28
A Absätze 77, 83, 86 Layout visualisieren 94 signieren 14–15 Zeilenzahl ändern 87 Abschnittstitel 142–150 Formatierung 142–150 anpassen 144–146 Implementierung 142–143 visualisieren 98 \addcontentsline 154–155 \adddriver 249 \AddPageUpperLeft 84 \AddPageUpperRight 84 \addtocontents 154–155 \addtocounter 141 \addtolength 35 \AddToShipoutPicture 83 \addvspace 154–155, 157 Adobe-Font-Metrik 241 adrconv (Paket) 213 \afterpage 311–312
afterpage (Paket) 311 aktive Zeichen 7, 26, 58, 125 algorithm (Umgebung) 135–136 \alph 18–19 amsmath (Paket) 65–66 anderthalbzeilig setzen 22 Anthologie 201 \appendix 45 \applyCSVfile 213 \arabic 17–18, 76 Argumente, zwei optionale 54 arlatex 200 array (Umgebung) 65–66 array (Paket) 107, 117, 125 Arrays simulieren in TEX 149 Arseneau, Donald 33, 177, 196 article (Klasse) 89, 94, 129, 140–141, 155, 201, 233, 333, 343 ASCII 5 askinclude (Paket) 191 \AtBeginDocument 25, 174, 193 \AtEndDocument 116, 197 \AtEndTabular 116 \AtPageUpperLeft 83 \attachfile 306 attachfile (Paket) 305 AUCTEX 350–355 eigene Definitionen 353–355 Kommandos ausführen 351
381
TeX-fold-mode 352 Texteingabe 350–351 und RefTEX 363 Aufgaben setzen 42–45 Aufkleber 224 Aufzählungen 16–22 Nummerierung ändern 17 Aufzählungspunkte 16–17, 19 mit \label und \ref 18 Verweisformat für 18 Zeichen ändern 16 Ausgabe spiegeln 326 Ausgabeverzeichnis festlegen 193 \author 201
B babel (Paket) 6, 10, 26, 30, 99, 126, 179, 182 und parallele Texte 30 babelbib (Paket) 179, 181–182 backref (Paket) 172–174 \backrefalt 174 Backus-Naur-Form 70 Barr, Michael 284 Barroca, Leonor 121 Barthelmann, K. 70 \baselineskip 22–24 \baselinestretch 23–24 Bellantoni, Stephen 196 Bennett, Frank 284 Berry, Karl 235, 242, 327 Bertolazzi, Enrico 66 Beweise 64 Beweisende-Symbol 65 Bezos, Javier XII, 22, 144, 156 \bf 306 \bfseries 49 \bgroup 29, 275 bibentry (Paket) 175 \bibfootnote 176 \bibliography 177, 365
382
\bibliographystyle 177 BibTEX 166–182, 213 und RefTEX 365–366 bibunits (Paket) 178 Bindekorrektur 92 Bindestrich 4–7 \bitbox 67 Blindtext 99–100 blindtext (Paket) 99 Blocksatz 1, 24 BNF 70 Bombien, Volker XII book (Klasse) 75, 89, 129, 140–141, 143, 147, 156, 233, 335 \botfigrule 130 \bottomfraction 130–131 bottomnumber (Zähler) 130 Box zeilenweise auseinandernehmen 34 Brachiosaurus 121 Brüche 59–60 bstsample 166, 168, 170, 172 bundledoc 200 \@bychapter 76 Bytefelder 67–69 bytefield (Paket) 67, 69
C \c@page 76 cabextract 257 cal-bottom (Paket) 289 cal-side (Paket) 289 calc (Paket) 35 calendar (Paket) 284 calendar_barr (Paket) 284 calmonth (Umgebung) 286–287, 289 calxxxx (Paket) 284 \caption 119–121, 132–133, 136–137, 154 \@captype 133
Carlisle, David XII, 48, 82, 107, 110–111, 113, 115, 119, 147, 153, 266, 286, 311 cases (Umgebung) 66 cat 209 \catcode 27–28, 30, 43, 126, 275 cd (Paket) 221, 224 cd-cover (Paket) 224 cd-discid 221 CD-Hüllen 220–221 CD-Inlays 221, 224 cddb-cover.sh 221 cddbcmd 221 Center (Umgebung) 3 center (Umgebung) 3, 31, 105, 383 vs. \centering 3 \Centering 3 \centering 3, 143, 275, 383 vs. center 3 Chambert-Loir, Antoine 277 chappg (Paket) 77 \chapter 45, 76, 81, 140–147, 149, 155, 317 chapter (Zähler) 146–147, 333 chapterbib (Paket) 177–178 \chapterformat 146, 334 \chapterhack 149 \chaptername 85 chapterthumb (Paket) 326 \chaptertitlename 145 Chemie 72–73 Elemente 72 chemsym (Paket) 72–73 Chen, Pehong 82 chroot 48 \cite 73, 166, 168, 170, 175, 177, 366 classico (Paket) 241 \cleardoublepage 75 \clearpage 197, 311 \closeout 45 \clubpenalty 86–87
interne Verwendung 87 Cochran, Steven 134 Codierung 5, 242 Adobe 243 OT1 11, 245 T1 5, 11, 243, 248 TEX Base-1 243, 248 TS1 246 Collins-Sussman, Ben 373 \color 114, 306 color (Paket) 48, 51, 224 \colorrows 116–118 colortbl (Paket) 115 \coltocauthor 205 \coltoctitle 205 \columncolor 115 \columnwidth 122 combine (Klasse) 202, 205 combine (Paket) 205 combinet (Paket) 205 comment (Umgebung) 192 comment (Paket) 196 \contentslabel 158 \contentsline 155 \contentspage 158 contract (Klasse) 150, 153 convert 267, 269, 271, 292, 313 convert-for-dvips 271 \count0 332–333 count1to (Paket) 198, 332–333, 338 \count2 333 cp 376 \crop 325 crop (Paket) 322–323, 326 \csname 19–20, 149, 187 CSV-Format 124–129, 213–214 \csvtabular 127 \CSVtolongtable 214 csvtools (Paket) 213–214 \CSVtotabular 214 CTAN XIV, 241 383
\currentlist 99 \currentpage 98 custom-bib (Paket) 172 cverse (Umgebung) 32–33
D Dahlgren, Mats 13, 72 Daly, Patrick 172, 175 Dateien archivieren 200 Namensdatenbank 329 protokollieren 199 Datenbank 215–220 dcolumn (Paket) 110–111, 115 dcop 359–360 \declarebtxcommands 182 \DeclareGraphicsRule 268, 271 decode-fontname 339 \def 29, 41, 186–187, 190 vs. \newcommand 187 \defaulthyphenchar 5, 25 \define@key 286 \definecolor 303 \DefineNamedColor 56 Diarähmchen 214 Didot-Punkt 232 Diehl, Norman XII \ding 21 dingautolist (Umgebung) 22 dinglist (Umgebung) 17 discretionary (Paket) 5 \displaywidowpenalty 86 \do 43, 195 document (Umgebung) 201 \documentclass 201, 232 Dokumente 183–229 aufteilen 188–190 mehrere Versionen 191–196 selektiv bearbeiten 189 Dokumentklasse 86, 227 Dominik, Carsten 363
384
Donne, John 34 \dospecials 43 \dottedcontents 156, 158–159, 164 \@dottedtocline 155 doublespace (Umgebung) 23 \doublespacing 23–24 Drakos, Nikos 367 \draw 278–279 Drechsel, Sammy 4 dropcaps (Paket) 13 dropping (Paket) 13 DRY-Prinzip 186 Duden 238 Durchschuss 22 Dussa, Tobias 220 DVI 198, 301 DVI-Datei 8, 269 Seiten selektieren 331–333 dvi2bitmap 368 dvifontlist 343 dvipng 368 dvips 48–49, 122, 240–257, 265–270, 277, 287, 292, 300 dviselect 331–333 dvitype 339, 343
E easy (Paket) 66 easymat (Paket) 66 Eckermann, Matthias 25 \edef 186–187 Eßer, Hans-Georg 215 egplot (Paket) 276 \egroup 29, 275 Eijkhout, Victor 30, 34, 196 Einheiten, Physik 61–62 Einheiten, Typografie 232 Eisenbahndiagramme 69–72 Els, Danie 62 Emmel, Thomas 224
\emph 48, 351 \endfirsthead 120 \endfoot 120 \endhead 120 \endlastfoot 120 \enlargethispage 88 enumerate (Umgebung) 16–17, 105 enumi (Zähler) 17, 21 enumitem (Paket) 22 Enzyklopädie 82 EPS-Datei 268 EPS-Dateien 270, 272 \epsilon 19 epstopdf 271, 275, 277 eso-pic (Paket) 83 \evenweek 288–289, 292 everysel (Paket) 25 \everyshi 198 ex@solution (Umgebung) 44 \excludeversion 196 exercise (Umgebung) 42 \expandafter 20, 187, 319 expect 48 extarticle (Klasse) 233 extsizes (Paket) 233
F Fairbairns, Robin 77 Fallunterscheidung 66 fancybox (Paket) 138 fancyhdr (Paket) 81 \fancyhead 83 Farbe 48–56 für Gruppen 49 für Texte 48 in Tabellen 114–118 separat drucken 325 vordefiniert 49 Farbmodelle 49–50, 53–54 \fcolorbox 54
Felder simulieren in TEX 149 \field 214 fig2sty 103–105 figure (Umgebung) 120, 122, 131–132, 135, 137, 351, 362 \filcenter 157 \filinner 145 \fill 14–15 \filleft 157 find-chap 334–335, 338 Firth, David 101 Fitzpatrick, Brian W. 373 fix2col (Paket) 82 Flattersatz 1–3, 24 Fließtext 86 Flipo, Daniel 11 float (Paket) XI, 135–137 \floatname 136 \floatpagedesign 94, 98 \floatpagediagram 98 \floatpagefraction 130–131 \floatsep 130 \floatstyle 137 \flushbottom 86 FlushLeft (Umgebung) 3 flushleft (Umgebung) 2 FlushRight (Umgebung) 3 flushright (Umgebung) 2 fontinst (Paket) 244–246, 248–249, 252, 255–256, 259–264 \footnotedesign 98 \@for 195 \foreach 280 Fotokalender setzen 283–293 \frakfamily 238 Fraktur 237–239 \framebox 371 Franz, Melchior 322 freedb 221 \frontmatter 76 \futurelet 128 385
Fußzeile
85, 94
G Gäßlein, Hubert 78 Garcia, Federico 177 \gdef 28 Gedankenstrich 4 geometry (Klasse) 286 geometry (Paket) 89–90, 301, 322–323 german (Paket) 6, 10, 126 \Gin@extensions 270 Gleitobjekt-Stil 136 neu definieren 137–138 Gleitobjekte 37, 78, 94, 119, 129–135 eigene Typen definieren 135–139 mehrere Tabellen/Abbildungen im selben Objekt 131–133 Positionierung 129–131 Unterobjekte 133–135 Verweise auf 134 Gnuplot 272–276 gnuplot (Umgebung) 274–275 gnuplottex (Paket) 276 \@gobble 192 Goldberg, Jeff 198 \gothfamily 238 Grafikformate 266–267 Grafikregel 270 Graham, Ronald 136 graphics (Paket) 266, 326 \graphicspath 270 graphicx (Paket) 224, 266–268, 270 graphpap (Paket) 298 \greek 19–20 greet (Paket) 353–354 grep 241 Grunwald, Dirk 331 Günther, Karsten 33, 185
386
Gurari, Eitan 368 Guthöhrlein, Eckhart gvim 358
111
H \hack 147–149 \hackformat 148 \hacknum 148 Hailperin, Max 77 Hansen, Thorsten 178 Haralambous, Yannis 13, 237 Harders, Harald 179 Harris, Erica 23 harvard (Paket) 366 \hbadness 32 \hbox 125 \headingdesign 98 Heinlein, Robert A. 373 Heinrich, Volker XII Heinz, Carsten 36 helvet (Paket) 237 \hfill 158 Hilbert-Matrix 66 \hoffset 229 Holm, Christian 224, 326 \hspace 14 HTML erzeugen 367–373 \htntab 85 \Huge 162 Hull, Thomas 220 Hurenkinder 85–88 hy 9–10 hyperref (Paket) 139, 172, 174, 301–303, 308, 317, 319 \hypersetup 302–303 Hypertext 367 hyphen_show 7–10 hyphenat (Paket) 7, 25 \hyphenation 10 \hyphenchar 5, 24
I icomma (Paket) 59, 107 \if 82 \ifcase 19 \iffalse 138 \ifoddpage 78–80 ifpdf (Paket) 275 \ifplastex 370 \@ifstar 185–186 ifthen (Paket) 32, 157, 227, 314 \ifthenelse 78, 82, 319–320 \iftrue 138 \ifx 79 \ignoreenv 196 \ignorespaces 28 \immediate 42, 44–45 \import 202 \include 177, 189, 191, 202, 335 \includegraphics 148, 266, 270, 287, 311, 314 \includeonly 189, 191 \includepages 316, 319 includepages (Paket) 316–317 \includepdf 312 \includesolutions 45 \includetrainer 192–193 \includeversion 195–196 \index 164–165 Index 164–166 Begriffe automatisch indizieren 185 mehrere 165 index (Paket) 165–166 \indexmark 81 info 331 Inhaltsverzeichnis 78 Abschnittsnummer überbreit 155 als Absatz 159–161 am Kapitelanfang 162–164 Einträge machen 154–155
Formatierung Seitennummer überbreit 156 setzen 155–159 visualisieren 98 Initialen 11–13 \input 40, 189–190, 193, 202, 275, 318 inputenc (Paket) 153, 308 \installfont 261–263 \interlinepenalty 86 \intextsep 130 ISO Latin-1 60 ISO Latin-9 60 \item 345, 351 itemize (Umgebung) 16, 18, 105, 350 Iulius Caesar, Gaius 27
J Jankovi´c, Slobodan 284 Jeffrey, Alan 244 \jobname 46–47, 274 join 209 Jones, David M. 165 Jörn, Fritz 240 jurabib (Paket) 366
K Kakugawa, Hirotsugu 343 kalender (Paket) 284 Kapitälchen 11, 263–264 »falsche« 263 Kapitelanfänge 80 Kastrup, David 119, 361 Kategorie-Code 27 Kern, Uwe 49, 52, 118 Kernighan, Brian 184 keyval (Paket) 41, 286, 316 Kielhorn, Axel 213 Kile 343–347, 350 Kilfiger, James 233 387
\LenToUnit 84 \let 29, 43, 125, 196 lettrine (Paket) 11–13 Liang, Frank 11 Libes, Don 48 Lickert, Knut 99 Ligatur 238 Ligaturen 240, 245 \linebox 35 Lingnau, Anselm 135 Links 301–303 \listdesign 94 \listfiles 199–200 listings (Paket) 36–37, 40–41 Literaturliste 166–182 aufeinanderfolgende Zitate derselben Quelle 176 L im Text 174–175 l, C. Michael Pilato 373 in Fußnoten \l@section 155 ISBNs, ISSNs und URLs 182 \label 18, 21, 73, 78, 197–198, mehrsprachig 179–182 334–335, 350, 354, 364–366, Begriffe anpassen 182 382 mit Rückverweisen 172–174 \labelenumi 17–18 pro Kapitel 177–178 \labelitemi 16–17 Lobotomie 22 Lamport, Leslie XII longtable (Umgebung) 119–120, Lamprecht, Günther 7 214 langes s (bei Fraktur) 238 longtable (Paket) 33, 73, 115, 119 \lasthack 146 \looseness 87–88 lastpage (Paket) 198 Lorem ipsum 99 latex 300, 329 Loseblattsammlungen 74 LATEXDB 215 Lotz, Wolfhard 7 latexdb 219 lrbox (Umgebung) 80 \latinfamily 245, 252, 260–262, ls 47 264 lst-find 40 Lauwers, Fred 13 \lstdef 38–41 layout (Paket) 94 \lstinputlisting 37–38, 40 layouts (Paket) 94, 98–99 lstlisting (Umgebung) 37 \leftmark 81–82 \lstset 40 \leftskip 4 \lstuse 38–41 Legende 120–121, 137 LTchunksize (Zähler) 121 Lehman, Philipp 252 ltpage (Paket) 198, 200, 338 Knuth, Donald E. XII, 11, 136, 234 Kochrezepte 59 Kohm, Markus 89, 91, 235, 326 Kolumnentitel 81–82 KOMA-Script 91–93, 235 Komma im Mathemodus 57–59 Kommandos, interne 27 Kopfzeile 81–82, 85, 94 Kotthoff, Lars 276 kpdf 303, 306–307, 359 kpse-Werkzeuge 327–331 kpsepath 331 kpsewhere 330 kpsewhich 330–331
388
Lück, Uwe 196 Lyrik LyX 343, 347–350
M mailmerge 209 \mainmatter 76, 338 make 40, 193 make-calendar 285, 288, 290 \makeatletter 28, 133, 185 \makeatother 28, 133, 185 \makebox 138, 299 \makeindex 164–165 makeindex 82, 165, 351 \@makeother 43 \maketitle 201, 205 \MakeUppercase 145 man 271 Map-Dateien 248–250 \marginpar 81 \markboth 81 Marke 78–79 interne Darstellung 79 \markupcommand 186–188 \markversion 196 \mathcode 58 mathpazo (Paket) 237 mathptmx (Paket) 237 Matrizen 65–66 Hilbert- 66 mit Klammern 65 Matthias, Andreas 311 May, Wolfgang 63 McPherson, Kent 94 \measure 34–35 Metakommando 186 Minimalbeispiel 201 minipage (Umgebung) 31–34, 286–287 Minuszeichen 4 Mittelbach, Frank XII, 107, 112
mktexlsr 329 Mondrian, Piet 265 Moore, Ross 367 mparhack (Paket) 81 multicol (Paket) 73 \multicolumn 108, 110, 112 \multiput 93 Musterlösungen 42 einbinden 44 setzen 44 mv 376 MySQL 215
N named 49–50 \@namedef 38, 41, 51, 149–150, 187, 195 Namensschilder 224, 229 \@nameuse 20, 38, 150, 186–187 natbib (Paket) 175, 366 ncal 284 Nelson, Ted 367 \newcolumntype 110 \newcommand XIV, 28–29, 41, 54, 110, 178, 187–188, 202 vs. \def 187 \newcounter 202 \newenvironment 43, 202 \newfloat 136–137, 139 \newif 188 \newindex 166 \newlength 202 \newpage 143 \newtheorem 63, 351 newtheorem (Paket) 64 \newversion 195–196 \newwrite 42 NFSS 234, 240 ngerman (Paket) 10 nicefrac (Paket) 59–61 Niepraschk, Rolf 78, 83, 277
389
\nobibliography 175 \nocolorrows 116–118 \node 280 \noexpand 186 \nolinebreak 14–15 ntheorem (Paket) 63, 65 \num 62 \numberline 155 Nummerierung 140–141 Gliederungsebenen 140 im Inhaltsverzeichnis 141 mit deutschen Wörtern 146 mit griechischen Buchstaben 19 unterdrücken 141 Nutzen 224
O Oberdiek, Heiko 54, 172, 301, 303, 360 \obeylines 125 \oddweek 288–289, 292 onehalfspace (Umgebung) 23 \onehalfspacing 23 opcit (Paket) 177 optima (Paket) 255 optional (Paket) 196 Origami 220 overpic (Paket) 277
P page (Zähler) 75–76, 80, 332–333 \pagenumbering 76, 197, 332, 335 \pageref 79, 197–198 \pagestyle 202 Pakin, Scott 67, 200, 266, 305 palatino (Paket) 236 \papercdcase 220 \paperheight 301 papers (Umgebung) 202 \paperwidth 84, 301 \par 54 390
\paragraph 44, 141–142 paragraph (Zähler) 333 \paragraphdesign 94 Parallel (Umgebung) 26, 29–30 parallel (Paket) 25 Parallele Texte 25–30 ParallelX (Umgebung) 29 \parfillskip 4, 14–15 \parshape 105 \parskip 143 \part 141, 143, 155 part (Zähler) 333 Passmarken 322–325 Patashnik, Oren 136, 172 PDF 10, 101, 221, 232, 271, 300–321 Document Information Dictionary 307 Kapitel finden 333–338 Lesezeichen 317–320 Metadaten 307–311 Rechte 320–321 Seiten einbinden 311–312 Vorschaubilder erzeugen 303–304 PDF-Attachments 304–306 \pdfcompresslevel 301 pdffonts 341–342 \pdfinfo 307–308 pdfinfo 309 pdfLATEX 48, 101, 122, 221, 257, 266–267, 271, 300–321, 347, 390 pdfnup 101, 312 \pdfoutput 301 \pdfpageheight 301 pdfpages (Paket) 205, 311–312, 314, 316 \pdfpagewidth 301 pdfsync (Paket) 358–359 pdfTEX 241, 243, 277, 300–301 Verschlüsselung 320 pdftex 101, 300
pdftk 305–306, 320, 334, 338 pdftoppm 292 pdftricks (Paket) 277 Penalties 86 pgf (Paket) XVI, 277–278, 283, 362 photocal (Klasse) 285–286 picture (Umgebung) 83–84, 92, 226, 265, 277, 298 pifont (Paket) 16–17, 22 plasTEX 368–373 pltotf 244 PNG-Dateien 267, 270, 303, 313 \pnt 62 \@pnumwidth 156 Poster 103 PostgreSQL 215 PostScript 232, 242, 300 PostScript-Punkt 232 Präambel 11, 60, 87, 189, 199, 224 preview-latex 360–362 \printcontents 162, 164 \printindex 165 Probst, Axel 276 Programmlistings 36–41 symbolische Namen für 37 Protokolldateneinheiten 67–69 \providecommand 202 \provideenvironment 202 Prozessfarbe 49 pstoedit 267 pstricks (Paket) 277–278 Punkt 232 purifyeps 266–267 \put 298
Q Querformat 121 Querverweise, Überblick behalten 363–367 quotation (Umgebung) 105
R Radhakrishnan, C. V. 277 ragged2e (Paket) 2–3, 24 \raggedbottom 87 \RaggedLeft 3 \raggedleft 2 \RaggedRight 2, 24 \raggedright 2, 24 Rahtz, Sebastian 121, 266, 271, 301 Raichle, Bernd 42, 45 rail (Umgebung) 70 \railalias 70 \railterm 70 \raisebox 148 Rajagopal, C. V. 277 Randnotizen 81 Raute 26 rccol (Paket) 111 Rechtschreibung, traditionelle 6 -recorder 200 \ref 18, 79, 134, 198, 302, 366, 382 \reflectbox 326 RefTeX 363–367 Registermarken 322, 326 Reichert, Axel 36, 59, 61 \relax 79, 192 \@removefromreset 147 remreset (Paket) 147, 153 \renewcommand 130, 156, 188, 235 \renewenvironment 192 report (Klasse) 75, 89, 129, 140–141, 143, 233 \RequirePackage XIV, 372 \resetstr 249 \restylefloat 137 Richter-Federmann, Ulla 36 \rightmark 81–82 \rightskip 4
391
\rm 25 \rmdefault 234–235, 237, 255 \rmfamily 238 Rohner, Marcel 103 \roman 18 \romannumeral 149 Rooijakkers, L. W. J. 70 rotating (Paket) 121 \rowcolor 115–117 \rowcolors 118 \rowcounter 117 Rowley, Chris 42, 45 Rückwärtssuche 355–360 DVI 357–358 PDF 360 \rule 143 run-kpdf 360 runcmd 47–48 rundes s (bei Fraktur) 238
S \S 153 Sandmann, Søren 233 Satz, anderthalbzeiliger 22 Satz, registerhaltiger 87 Sätze (Mathematik) 63–65 Beweise 64 Nummerierung 63 Theoremstile 63 Satzspiegel 36, 89–93 Experimente 98 visualisieren 94–99 Sauer, Jonathan 146 \savebox 34, 80 scale (Paket) 233 Schäfer, Torsten XII \@schapter 143–144 Schedler, Andreas 63 Schiedrum, Eva XII Schlagschatten 138 Schmidt, Arno 89
392
Schmidt, Walter 237, 240 Schmuckfarben 49 Schnittmarken 224, 322–325 Schöpf, Rainer XII, 42, 45 Schreibmaschinenschrift 5, 24, 60, 234 und Silbentrennung 24 Schrell, Andreas 13 Schriften 231 auflisten (DVI) 339 auflisten (PDF) 341 Familiencodes 235, 242, 252 für Überschriften 143 komprimierte 262 kursive 259 LATEX-Pakete für 236 schräg gestellte 259–262 Schriftfamilie ändern 234–237, 251, 255 Schriftgrößen wählen 231–233 skalierbare 13 TrueType 256–259 Type 1 240–257 virtuelle 243–244, 246 Schriftfamilie 234 ändern 234–237 Schriftgröße 232 wählen 231–233 Schriftnamen 242 Schröder, Martin 2, 25, 198, 332 Schusterjungen 85–88 scrlttr2 (Klasse) 212, 348 \secdef 143–144 secnumdepth (Zähler) 140–141, 144 \section VIII, 45, 81, 85, 140–142, 146–148, 153, 155, 317, 376 section (Zähler) 142, 147, 333 \sectionformat 148 sed 205, 310, 331, 342 Seite verlängern 88
Seiten, linke und rechte 77–81 Seitennummerierung 82–85 absolute 198 für kombinierte Dokumente 202 i von n 197–198 kapitelweise 74–77 Seitenränder 36, 89–93 Experimente 98 visualisieren 94–99 Seitenstile 82–85 in diesem Buch 82, 84 Seitenumbruch 86 Serienbriefe mit CSV-Dateien 213–214 mit KOMA-Script 210–213 mit LinuxWerkzeugen 205–209 \setcounter 21, 121, 130, 141 \setfoot 83, 85 \setfootrule 83 \sethead 83 \setheadrule 83 \setlength 130 \@setref 79 setspace (Paket) 23, 152 \setstretch 24 \settowidth 35 \sfdefault 234, 255 \sffamily 148, 238 Sgouros, Tom 81 \shadowbox 138–139 \shell 46 shell (Umgebung) 46, 48 -shell-escape 47 \shelldefaultdir 47 Shellkommandos 45–48 als Sicherheitslücke 47 aus TEX 46 \shipout 198 \showtypearea 92–93 \SI 62 Sicherheitslücke 47
sidecap (Paket) 78–79 sideways (Umgebung) 122 sidewaysfigure (Umgebung) 122 sidewaystable (Umgebung) 122–123 \signed 15 Silbentrennung 2–11 an Schrägstrichen 6 Ausnahmeliste 10 manuell 10 mit Schreibmaschinenschrift 24 Simonic, Aleksander 355 singlespace (Umgebung) 23 sistyle (Paket) 62 \smash 85 Smith, Kevin 368 \so 145 Söhner, Jörg 284 solution (Umgebung) 43–44 solution (Paket) 42 soul (Paket) 145 \spacefactor 28 \spacing 24 \special 355, 358, 360 srcltx (Paket) 355 \@startsection 142–143 \stepcounter 75 Steward, Sid 320 Stickschrift erstellen 293–299 Straub, Pablo A. 191 Streckenstrich 4 subfig (Paket) 134–135 \subfloat 134 \subref 135 \subsection 141–142, 153, 155 Subversion 308, 310 Arbeit mit 374–377 Branches 377–379 Repository anlegen 374 sudo 255 svn 375–379 \swabfamily 238 Syntaxdiagramme 69–72 393
Système International (SI)
62
TDS 247 Tennent, Bob 241 tex 200, 300, 329, 343 T TEX Directory Standard 247 Tabelle 85 TEX-Font-Metrik 240 Tabellen TEX-Konfiguration 328 aus CSV-Dateien 124–129 tex-t1font 252, 255–256 Ausrichtung am Komma 109–111 \texdbdef 219–220 Farbe in 114–118 \texdbfor 219 Fußzeilen 120 texhash 329 Kopfzeilen 107, 120 Text sperren 145 neue Spaltenkürzel 107, 110 Text zentrieren 3 Semikolons als Spaltentrenner textarea (Paket) 94 125 \textattachfile 306 Spalten färben 114 \textbf 48, 306 Spalten im Mathemodus 106–108 \textcolor 306 superriesenlange 121 \textfloatsep 130 überbreite 121–124 \textfraction 130 überlange 119–121 \textonehalf 60 Variable Spalten 111–114 \textonequarter 60 Zeilen färben 115 \textrm 72 Tabellenziffern 109 \textsc 187 \table 251 \textthreequarters 60 table (Umgebung) 119–120, 122, \texttt 188 124, 131–132, 135, 137, \textwidth 122 351 Thành, Hàn Thê´ 300 \tableofcontents 154 \thanks 205 tabular (Umgebung) 107, 119, \the 17–18, 21, 44 125, 214, 286, 289 thebibliography (Umgebung) 166, tabular* (Umgebung) 111, 114–115 174, 178, 365 tabularx (Umgebung) 111–112, \thecontentslabel 157 114 \theenumi 17–19, 21 tabularx (Paket) 111, 115 theorem (Umgebung) 63 tabulary (Umgebung) 113–114, Theoremstile 63 122 \theoremsymbol 65 tabulary (Paket) 113 thumb (Paket) 326 Tagungsbände 201–205 thumbpdf (Paket) 303 Talbot, Nicola 213 ticket (Paket) 224, 226–227 Tanenbaum, Andrew S. 308 \ticketdefault 229 Tantau, Till 277 TikZ 278 tar 200 tikzpicture (Umgebung) 278 TDF-Datei 227 \tikzstyle 280 394
Tilde 26 times (Paket) 236 \title 201 \titlecontents 156–159, 164 \titleformat 144, 146, 153 titlesec (Paket) 80, 82, 144–145, 147–148, 153, 156–157, 161–162, 334 \titlespacing 153 titletoc (Paket) 156, 159, 161–162 \to 280 Tobin, Geoffrey 23 tocdepth (Zähler) 141, 144, 155, 163 \tocdesign 98 Token-Register 43 \topfigrule 130 \topfraction 130 topnumber (Zähler) 130 Torek, Chris 331 totalnumber (Zähler) 130 trainer (Umgebung) 192, 194 Trema 11 Trennstrich 4–7 TrueType-Schriften 233, 256–259 \try 98–99 \trytextwidth 98 Tschichold, Jan 85, 93 \ttdefault 235, 255 ttf2pt1 257–258, 261 twoopt (Paket) 54 \tymax 114 \tymin 113 Type-1-Schriften 233, 240–257 typearea (Paket) 89, 91–92, 232, 301, 323 \typein 190
U Überschriften 3 Ulrich, Stefan 81, 355
Umeki, Hideo 89 Umgebung in Datei kopieren 42 \unhcopy 35 Unicode 60 \unit 61–62 \unitfrac 61 \unitlength 92–93, 226, 229, 298 units (Paket) 61–62 \unskip 15 Unterschneidung 258 updmap-sys 249 Urinstinkt 7
V \value 21 van Oostrum, Piet 81–82 Van Zandt, Timothy 138, 277 varwidth (Paket) 33 \vbox 36 \vcard 226 verbatim (Umgebung) 42–43, 46, 125, 191 verbatim (Paket) 1, 42–45, 191–192 \verbatim@processline 43, 46 \verbatim@start 44 Verfasserangabe 14 verse (Umgebung) 31–32 version (Paket) 196 versions (Paket) 196 Vertragstexte 150–153 Vigna, Sebastiano 221 vim 357–358 Visitenkarten 224–229 Größe 90 TDF-Datei 227 \voffset 229 Vorschau im Editor 361 Vorwärtssuche 355–360 DVI 356–357 PDF 358–360
395
vpe (Paket) 360 vptovf 244 vrsn (Paket) 196 \vspace 154 \vtotalwidth 35 \vwidth 32
W Wall, Larry XIV \weekdays 288–289 Weibezahn, Roland 7 wget 313 \whiledo 227, 320 Wiche, Burkhard XII \widowpenalty 86–87 \widthof 35 Wilson, Peter R. 7, 25, 94, 202 \windowpenalty 86 Woodcock, Robert 221 \wordbox 67 Wortzwischenräume 24 \write 44, 47, 275 WYSIWYG 183
X X11 51 x11cdefs (Paket) 51, 54 x11color (Paket) 51 xcolor (Paket) 49, 52, 118 \xdef 319 xdvi 48, 240, 243, 246, 248–249, 266, 356–357 xfig 74, 102–103 xindy 165 xpdf 292, 309, 341, 359 xtem 7 xterm 357
Y yfonts (Paket) 396
238–239
yinit (Paket)
13
Z zahl2string (Paket) 146 Zahlen formatieren 62 Zähler Ausgabeformat 147 automatisch zurücksetzen 75, 147, 153 Zapf Dingbats 17, 20 Zapf, Hermann 241 Zeichentabelle ausgeben 250 Zeilenumbruch 14 zentrieren Gedichte 31 letzte Zeile eines Absatzes 3 optisch 33–36 Text 3 Zuse, Konrad 5 zweizeilig setzen 23
Kolophon Bei dem Metallwerkzeug, das auf dem Cover von LATEX Hacks zu sehen ist, handelt es sich um einen Winkelhaken. Ein Winkelhaken wurde von Schriftsetzern beim Zusammensetzen einer Zeile aus Drucktypen für den Buch- oder Hochdruck eingesetzt. In der Fach- und Umgangssprache der Setzer wurde der Winkelhaken »Kelle« genannt. Er wurde bereits von Johannes Gutenberg entwickelt, jedoch durch die Einführung der Setzmaschine aus den Druckwerkstätten verdrängt. Das Druckerwerkzeug ist eine winkelförmige Schiene, die meist aus einer Nickel-Kupfer-Zink-Legierung gefertigt wurde. Es verfügt über einen feststehenden und einen verschieb- und feststellbaren Anschlag (»Frosch«), wobei der Abstand zwischen diesen Anschlägen der gewünschten Zeilenlänge entspricht. Je nach Verwendungszweck gab es unterschiedlich lange Winkelhaken. Durch Verwendung des Winkelhakens wurde sichergestellt, dass alle Zeilen exakt die gleiche Länge hatten und ein so genannter »geschlossener Satz« erstellt werden konnte. Der Umschlagsentwurf dieses Buches basiert auf dem Reihenlayout von Edie Freedman und stammt von Hanna Dyer. Das Coverlayout der deutschen Ausgabe wurde von Hanna Dyer mit Quark XPress 4.1 unter Verwendung der Schriftarten Helvetica Neue und ITC Garamond von Adobe erstellt. Das Buch selbst hat Anselm Lingnau in LATEX gesetzt. Als Textschrift verwenden wir die Linotype Birka, die Überschriftenschrift ist die Adobe Helvetica Neue Condensed, und die Nichtproportionalschrift für Code ist TheSans Mono Condensed von LucasFont.