+ All Categories
Home > Documents > Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum...

Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum...

Date post: 05-Feb-2018
Category:
Upload: phamkiet
View: 229 times
Download: 1 times
Share this document with a friend
34
Lass doch L A T E X rechnen! Rechnerei für den Alltag – Eine Einführung (ohne calc)– 1 \def\MM#1{ 2 \@tempdima=#1 3 \@tempdima=.35146\@tempdima 4 \def\vn##1.##2!!{% 5 \global\edef\vara{##1}% 6 \global\edef\varb{##2}% 7 }% 8 \expandafter\vn\the\@tempdima!!% 9 \vara.% 10 \def\ziffer{% 11 \@tempdimb=0.\varb% 12 \@tempdimb=10\@tempdimb% 13 \expandafter\vn\the\@tempdimb!!% 14 \vara% 15 }% 16 \ziffer\ziffer\ziffer\ziffer\ziffer~mm 17 } Bernd Kosubek 2006-06-18 letzte Änderung: 2012-01-10
Transcript
Page 1: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

Lass doch LATEX rechnen!Rechnerei für den Alltag– Eine Einführung (ohne calc) –

1\def\MM#1{2 \@tempdima=#13 \@tempdima=.35146\@tempdima4 \def\vn##1.##2!!{%5 \global\edef\vara{##1}%6 \global\edef\varb{##2}%7 }%8 \expandafter\vn\the\@tempdima!!%9 \vara.%

10 \def\ziffer{%11 \@tempdimb=0.\varb%12 \@tempdimb=10\@tempdimb%13 \expandafter\vn\the\@tempdimb!!%14 \vara%15 }%16 \ziffer\ziffer\ziffer\ziffer\ziffer~mm17}

Bernd Kosubek

2006-06-18 letzte Änderung: 2012-01-10

Page 2: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

Satz:

Bernd Kosubek

[email protected]

© 2006 – 2012, Bernd Kosubek

Page 3: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

Zum InhaltFür viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen Schritte für Berechnungen an LATEXabzugeben. Das hängt weniger mit „nicht wollen“ zusammen als vielmehr mit dem berühmten „gewusst wie“.

In den meisten Literaturen zum Thema LATEX wird dieser Punkt ganz ausgespart, weil dies zu sehr in die „Innereien“gehen würde und man dies dem Leser nicht zumuten möchte. Häufig genug schreckt aber der Autor selbst davorzurück.

Im Teil „Probleme!?“ werden einige Beispiele aufgeführt, bei denen es Sinn macht Berechnungen an LATEXabzutreten.

„Nimm’s leicht!“ beschäftigt sich mit Berechnungen für zwischendurch, also Aufgaben, die nicht routinemäßiganfallen. Der Schwerpunkt liegt auf Berechnungen, die man genauso gut nebenbei auf dem Papier machen könnte,um dann die fertigen Resultate als Literale zu übergeben.

Sinn und Nutzen von Registern – darum geht es im Kapitel „Register“.

Der Abschnitt „Ausgelagerte Berechnungen“ geht schon mehr in die „Innereien“ von TEX/LATEX. Da bestimmte Be-fehle nicht direkt in LATEX eingegeben werden können, und auch nicht soll(t)en (Pakete wie at einmal ausgeklammert),werden die hier vorgestellten Routinen üblicherweise in .sty-Files geschrieben und mit \usepackage eingebunden.

Es wird nicht nur das Verhalten beim Rechnen mit Registern beschrieben, sondern es werden auch Routineaufgabenbehandelt, die im LATEX-Alltag eine Menge Arbeit abnehmen können. Alle vorgestellten Routinen lassen sich nochoptimieren (etwa durch zusammenziehen mehrerer Schritte).

Da hier der Einstieg in die Thematik vermittelt werden soll, wurde in der Regel die „Langschreibweise“ (z. B.\setlength{\PicHeight}{13mm}) statt der häufig anzutreffenden Kurzschreibweise (\PicHeight13mm)verwendet. So lässt sich für den Einsteiger leichter nachvollziehen, was gerade geschieht.

Aus dem selben Grund wurde auf die Einbindung und Beschreibung des Pakets calc verzichtet. Der interessierteLeser sollte sich aber ergänzend damit beschäftigen, da das Paket weitaus mehr kann als die hier gezeigten „einfachen“Rechnereien.

Ein paar Fehler beim Probieren und man hat wieder etwas gelernt!

Noch ein Hinweis:In diesem Werk wird die althergebrachte männliche Form verwendet, gemeint sind dann aber immer alle Ge-schlechter, also auch Androgyne und das Kind.Der Grund dafür ist recht einfach: Es sollte ein Werk über ein bestimmtes Thema geschrieben werden, bei demdie thematischen Gedanken zusammengehalten werden müssen; da stört jede unnötige Überlegung, ob jetztschon wieder in dieser oder jener Formulierung eine Geschlechterdiskriminierung steckt oder nicht.

Page 4: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

1 Probleme!? 1

2 Nimm’s leicht! 32.1 Ein wenig Prozentrechnen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 Grundrechenarten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2.1 Begriff „Definition“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2.2 Addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2.3 Subtraktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2.4 Multiplikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2.5 Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.3 Approximationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Register 93.1 count-Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.2 dimen-Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.3 skip-Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.4 Registertypen kombinieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.4.1 skip dimen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.4.2 count dimen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.4.3 count skip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.4.4 dimen count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.4.5 dimen skip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.4.6 skip count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4 Ausgelagerte Berechnungen 154.1 Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.2 Zwischenspeicher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.3 Tabellen mit Abbildungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.3.1 . . . für Einzelfälle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164.3.2 . . . für Bildserien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.4 pt! mm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.5 Rechnen in Tabellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4.5.1 Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.5.2 Was muss beachtet werden? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.5.3 Lösung: Routinen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.6 list-Umgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

Literatur 27

Index 29

Page 5: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

1

1 Probleme!?

Greifen wir ein paar Beispiele auf, bei denen uns LATEXeine Menge Arbeit abnehmen kann.

In einigen Fällen muss etwas tiefer in die Trickkistegegriffen werden, in anderen Fällen wiederum überhauptnicht:

• Minipages, Parboxen, gerahmte Boxen

Hier könnten beispielsweise die Ausmaße in Relationzum Satzspiegel berechnet werden (Siehe Kapitel 2.1(Seite 3)).

• Breiten von Tabellen

Wenn ein gegebener Satzspiegel einzuhalten ist,muss die tatsächliche Breite einer Tabelle ermitteltoder festgelegt werden. Im zweiten Fall kann dieSpaltenbreitenberechnung zu einem großen Teil anLATEX abgegeben werden (Beispiele siehe Kapitel 2.2(Seite 3)).

• Umrechnung von Einheiten

Statt die Umrechnung von beispielsweise GradCelsius in Grad Fahrenheit für jeden einzelnen Wertmit dem Taschenrechner auszuführen und das Ergeb-nis abzuschreiben, kann dies automatisch von LATEXerledigt werden (Siehe Beispiel unter Kapitel 2.3(Seite 7)).

• Verschübe mittels Raiseboxen

Raiseboxen bieten sich an um beispielsweise Legen-den oder Titel neben Abbildungen zu setzen. Hierzumuss gegebenenfalls die Höhe der Abbildung ermit-telt werden, damit der notwendige Verschub entspre-chend berechnet werden kann (Beispiele sind in Ka-pitel 4.3 (Seite 16) aufgeführt).

• Abstände zwischen Abbildungen/Tabellen und Text,um wieder Registerhaltigkeit zu erlangen.

Tabellen und Abbildungen sind in der Regel nicht ge-nau x Zeilen hoch. Man könnte sich daher ausrechnenlassen, um wieviel der Abstand zwischen Objekt und

Text angepasst werden muss, um wieder Registerhal-tigkeit zu erlangen.

Kein übermäßig großer Aufwand. Um die Sache ein-fach zu halten, ist aber der Einsatz der hier nichtbesprochenen Box-Register sinnvoll, daher hier keinBeispiel.

• Ermittlung der Höhe und/oder Breite von Abbildun-gen/Tabellen

Es kann wichtig sein, die Maße von Tabellen/Abbildungen zu ermitteln, um sie beispielsweise pro-portionsrichtig neben-/übereinander zu stellen.

Keine eigenen Beispiele – ergibt sich größtenteils ausden anderen Beispielen.

• Rechnungen schreiben mit LATEX

Auch wenn es viele Leser vielleicht nicht glauben,aber man kann LATEX auch dazu bringen tabellaricheRechnungen selbst zu kalkulieren. Ein möglicher Lö-sungsweg ist in Abschnitt Kapitel 4.5 (Seite 18) be-schrieben.

• Berechnung der Marken- und Textbreiten in list-Umgebungen

Listen unter LATEX sind in der Regel etwas einge-rückt. Soll dies beispielsweise unterbleiben (so wiehier) muss LATEX verschiedene Maße mitgeteilt be-kommen, die sich zumindest zum Teil berechnen las-sen. Der Umgang mit Lineal und Mikrometerschrau-be kann dabei auf Null sinken.

Am Ende von Kapitel 4.6 (Seite 25) finden Sie einunkommentiertes Beispiel, dessen Arbeitsweise sichnach all dem Geschriebenen selbst erklären sollte.

• . . .

Wenn nicht anders angegeben, wird in diesem Ar-tikel die Dezimaltrennung durch einen Punkt (.) undnicht durch das Komma (,) dargestellt. Der Grund dafürist, dass Werte in der Punktform an TEX/LATEX-Routinenübergeben werden müssen.

Page 6: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

2 KAPITEL 1. PROBLEME!?

Page 7: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

2.2. GRUNDRECHENARTEN 3

2 Nimm’s leicht!

2.1 Ein wenig Prozentrechnen – dieeinfache Art sich das Leben zuerleichtern

LATEX-Anwender, die eher in den „geistigen Fachrich-tungen“ angesiedelt sind, brauchen diesen Text nicht vorSchreck gleich fallen lassen. Hier wird keine „höhere“Mathematik benötigt. Es genügt zu wissen, dass die ers-te Nachkommastelle 10 % und die zweite Nachkommas-telle 1 % bedeuten und alles was vor dem Komma stehtsind entsprechend viele „100prozente“.

Wenn beispielsweise eine Minipage benötigt wird, die47 % der Satzspiegelbreite einnehmen soll, dann kanndieser Wert, nach oben genannter Regel, direkt als Fak-tor für die Breite verwendet werden.

Beispiel 1Prozentangaben

1 \begin{minipage}{.47\textwidth}

2

...3 \end{minipage}

In Zeile 1 werden also 47=100 der Satzspiegelbreite\textwidth als Maß für die Breite der Minipage an-gesetzt.

Diese Vorgehensweise lässt sich in der Regel immeranwenden, wenn auf interne Register zurückgegriffenwird (dimen, skip, count, . . . ). In den späteren Bei-spielen wird hiervon noch reichlich Gebrauch gemacht.

2.2 Punkt-Punkt-Komma-Strich –oder wie war das doch gleichmit den Grundrechenarten?

Relevante Befehle (Kurzübersicht)

\advance \arraycolsep\arrayrulewidth by\def \divide\doublerulesep \multiply\newcount \newdimen\newlength \settowidth\setlength \tabcolsep

Wie breit ist eigentlich eine Tabelle wirklich, die dreiSpalten zu je 30 mm Platz für den Zelleninhalt be-reitstellt? Viele LATEX-Anwender staunen nicht schlecht,wenn sie das Ergebnis nachmessen.

Zuerst muss der Nutzer wissen, dass zu den 3 �30 mm= 90 mm noch der Raum links und rechts bis zumZellenrand addiert werden muss. Außerdem sind noch

die Linienstärke für vorhandene vertikale Linien und beiDoppellinien auch noch deren Abstand zu berücksichti-gen.

Per Definition finden wir in \tabcolsep(default in book und article: 6 pt) beziehungsweise\arraycolsep (default in book und article: 5 pt) denAbstand zwischen Zelleninhalt und Zellenrand.

In \tabcolsep und \arraycolsep ist nur dasMaß für eine Seite der Zelle abgelegt!

Beispiel 230 mm Tabellenspalten mit Standardlinienstärke

1 \begin{tabular}{|p{30mm}|p{30mm}||p{30mm}|}2 \hline

3 Spalte 1 & Spalte 2 & Spalte 3\\4 \hline5 \end{tabular}

Spalte 1 Spalte 2 Spalte 3Abbildung 2.1: Die Tabelle mit je 30 mm Platz für Text

In \arrayrulewidth (gilt für Tabellen und Arrays– den Befehl \tabrulewidth gibt es nicht!) wirddie Linienstärke für vertikale und horizontale Linien be-reitgestellt (default in book und article: .4 pt) und in\doublerulesep (default in book und article: 2 pt)der Abstand zwischen Doppellinien. Es wird übrigenstatsächlich der Abstand zwischen den beiden Linien in

\doublerulesep festgelegt und nicht der Abstandvon Mitte der linken Linie bis zur Mitte der rechten Li-nie. Dies lässt sich leicht überprüfen, indem extrem di-cke Linien gewählt werden (vgl. Abbildung 2.2). DerAbstand bleibt erhalten, die Linien laufen nicht inein-ander!

Spalte 1 Spalte 2 Spalte 3

Abbildung 2.2: Wie Abbildung 2.1, jedoch mit 4 mm starken Linien

Page 8: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

4 KAPITEL 2. NIMM’S LEICHT!

Wir müssen also eine ganze Menge Daten addieren,um auf die tatsächliche Breite zu kommen.

In Abbildung 2.3 sind die einzelnen Summanden gutablesbar, wobei p für die Spaltenbreite steht wie sie üb-licherweise an die Tabular-Umgebung übergeben wird:

6\arrayrulewidth

� -p 6\arrayrulewidth

� -p

HHY\arrayrulewidth

6\doublerulesep

6\arrayrulewidth

� -p 6\arrayrulewidth

Zelleninhalt Zelleninhalt Zelleninhalt

?\tabcolsep

?\tabcolsep

?\tabcolsep

?\tabcolsep

?\tabcolsep

?\tabcolsep

Abbildung 2.3: Eine Tabellenzeile

Aber da war doch noch . . . ?! Genau, wir müssen unse-re Millimeterangaben irgendwie mit den Punkt angabenverrechnen. Also doch wieder „Dreisatz“?!

Nein – keine Bange! LATEX hat keine Probleme mitden unterschiedlichsten Einheiten umzugehen. Wir kön-nen einfach alle zulässigen Maßeinheiten wie in (inch),cm, mm und pt zusammen verwursten. Die lesbareAusgabe von LATEX erfolgt immer in pt mit maximal5 Nachkommastellen [1 in = 72,27 pt; nicht(!) bp(1 in = 72 bp)], während intern immer mit sp (scaledPoint) gearbeitet wird.

Leider muss an dieser Stelle auch von einem Nachteildie Rede sein – und zwar geht es um Rundungsfehler.Durch die interne Umrechnung von beliebigen Maßein-heiten in sp ergeben sich häufig Rundungsfehler:

\newdimen\test\test=1.00001pt\the\test

liefert 1.00002pt.

Da sieht zwar gravierend aus, wenn man sichaber überlegt wie groß 0.00001pt tatsächlich ist (�0:000003515 mm� 3:515�10�6 mm) dann ist der Run-dungsfehler in der Regel verschwindend gering. Da sichdie übergebenen Berechnungen in den meisten Fällenauf Layouteinstellungen beziehen dürften, kann davonausgegangen werden, dass Fehler kleiner 0.1 mm auchvon „pingeligen“ Lesern nicht wahrgenommen werden.

Jetzt aber endlich zu den Befehlen, mit denen wir dieDaten verrechnen können: Für Addition und Subtraktionsteht \advance, für Multiplikation \multiply, fürdie Division \divide zur Verfügung. Die Syntax istrecht simpel:

\befehl\name by wert

wobei wert ein Literal, ein anderes Register, eine Defini-tion, . . . , sein kann.

Irgendwo müssen wir das Ergebnis unserer Berech-nung speichern. Also brauchen wir eine Art Speicher-platz. Der Speicherplatz wird mit einem Namen nameversehen und kann darüber jederzeit angesprochen wer-den. Für unser Beispiel bieten sich die dimen-Registeran. Nähere Einzelheiten zu den Registern sind in Kapi-tel 3 (Seite 9) beschrieben. Hier sei nur schon einmalbemerkt, dass dimen-Register automatisch mit der Maß-einheit sp verknüpft sind, wobei 65536 sp = 1 pt. dimen-Register können bequem mit \newdimen\name er-zeugt und mit \name=wert beschickt werden.

2.2.1 Begriff „Definition“Es wurde eben der Begriff „Definition“ als Quellefür wert verwendet. Darunter verstehe ich eine ArtKonstante. Diese Konstante wird mit

\def\name{const}

erklärt, wobei const eine Zeichenkette meint, die einendefinierten Wert widerspiegelt. Diese schwammige For-mulierung ist begründet in der Vielseitigkeit von const.

So kann const etwa folgendermaßen aussehen:

\def\mfg{mit freundlichen Grüßen}

\def\b{125.4pt}

\def\x{12}

\def\PIC{

\includegraphics[height=15mm]{bild01}

}

und so weiter. Eine Definition lässt sich somit als Text-baustein genauso gut verbraten wie als Wert für Berech-nungen oder um Werte indirekt zu bilden. Im Folgendenwerden daher Definitionen und wert gleichgesetzt.

2.2.2 AdditionWie breit ist denn nun unsere Tabelle (Abbildung 2.1)?Lassen wir es uns ausrechnen:

Page 9: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

2.2. GRUNDRECHENARTEN 5

Beispiel 3Addition

1 \newdimen\tabwidth % Summenvariable definieren2 \tabwidth=90mm % 3 x 30 mm = 90 mm3 \advance\tabwidth by 5\arrayrulewidth % 5 Linienstärken4 \advance\tabwidth by \doublerulesep % 1 Abstand Doppellinie5 \advance\tabwidth by 6\tabcolsep % lrlrlr = 6 mal Abstand Zelleninhalt bis Zellenrand6 Die Tabelle ist \the\tabwidth\ breit. % Kalkulationsausgabe

Die Tabelle ist 296.07477pt breit.

(Bei einer Linienstärke von 4 mm (vergleiche Ab-bildung 2.2) ergibt sich bereits eine Breite von350.98024pt.)

In Zeile 1 richten wir unseren Summen-Speicherplatzmit dem namen \tabwidth ein. Dann (Zeile 2) über-geben wir an ihn unsere 3� 30 mm (puh, das ging ge-rade noch so im Kopf). In Zeile 3 wird auf die bereitskennen gelernte Prozentrechnung zurückgegriffen. An-statt 5� Linienstärke können wir genauso gut auch von5� 100 % = 500 % Linienstärke sprechen. In Zeile 4wird 1 mal (quasi 100 %, der Faktor 1 kann weggelas-sen werden; Prozentrechnung) der Doppellinienabstandaddiert. Da das Maß für den Abstand zwischen Zellen-inhalt und Zellenrand in \tabcolsep nur einmal ent-halten ist, jedoch in jeder Zelle doppelt vorkommt (linksund recht) und 3 Zellen zu berücksichtigen sind ist derFaktor also 6 (600 %).

Zu guter Letzt lassen wir uns einfach einmal ausge-ben was LATEX da zusammengerechnet hat (Zeile 7) (wieschon gesagt, die Ausgabe erfolgt immer in pt, siehe Ka-pitel 2.2 (vorherige Seite)):

Unser Ergebnis 296.07477pt in Millimeter um-gerechnet ergibt eine Breite von „ungefähr genau“104.05715 mm (stolze 14 mm, bei 4 mm Linienstärke(Tabellenbreite: 123.35398 mm) sogar rund 1=3 mehr alsunsere ursprünglich angesetzten 90 mm).

Wie diese Umrechnung an LATEX übergeben werdenkann wird später gezeigt (Abschnitt 4.4 (Seite 18)). Hierbegnügen wir uns damit das Ergebnis in Abb. 2.1 bezie-hungsweise in Abb. 2.2 einfach nachzumessen.

2.2.3 SubtraktionFür den umgekehrten Weg, wenn also, um beim Tabel-lenbeispiel zu bleiben, die maximale Gesamtbreite gege-ben ist und die Spaltenbreiten kalkuliert werden sollen,muss subtrahiert werden.

Gehen wir wieder von einer 3spaltigen Tabelle aus,die maximal textspaltenbreit werden darf. Die mittlereTabellenspaltenbreite soll LATEX selbst ermitteln. Unter-stellen wir ferner, dass die erste Spalte nicht mehr Platzbeanspruchen darf als eine 4stellige Zahl und die letz-te Spalte höchstens so breit ist wie das Wort „Schna-bel“.

Außer \columnwidth (Textspaltenbreite bei mehr-spaltigem beziehungsweise \textwidth = Satzspie-gelbreite bei einspaltigem Layout; \columnwidth =Spaltenbreite bei mehrspaltigem Layout) kennen wirscheinbar keinerlei Maße. Das sieht etwas wenig aus, istes aber nicht. Schließlich haben wir ja noch die indirek-

ten Maße vierstellige Zahl und Schnabel. Wie soll LATEXaber daraus alles Notwendige ermitteln?

Nur weil wir keine Zahlen kennen, heißt das nicht,dass LATEX sie auch nicht kennt! Was wir tatsächlichbenötigen ist eigentlich nur noch eine Möglichkeit dieBreite eines beliebigen Ausdrucks festzustellen.

Anstelle der dimen-Register verwenden wir hierskip-Register. Der Grund liegt einfach darin, dassuns skip-Register diese Möglichkeit durch den Befehl\settowidth frei Haus liefern: Packen wir’s also an:

Beispiel 4Subtraktion

1 \newlength{\ci} % (c)olumn(i)2 \newlength{\cii} % (c)olumn(ii)3 \newlength{\ciii} % (c)olumn(iii)4 \settowidth{\ci}{0000}5 \settowidth{\ciii}{Schnabel}6 \setlength{\cii}{\columnwidth}7 \advance\cii by -\ci8 \advance\cii by -\ciii9 \advance\cii by -4\arrayrulewidth

10 \advance\cii by -6\tabcolsep11

12 \noindent13 \begin{tabular}{|p{\ci}|p{\cii}|p{\ciii}|}14 \hline15 1234 & wie lang? \the\cii & Schnabel\\16 \hline17 \end{tabular}

Mal sehen was raus kommt:

1234 wie lang? 130.51714pt Schnabel

Abbildung 2.4: Die passgenaue Tabelle

Na also – geht doch!

In den Zeilen 1, 2 und 3 werden die Register (also dieSpeicherplätze) zur Aufnahme der Spaltenbreiten einge-richtet. In den Zeilen 4 und 5 werden die Längen derLiterale „0000“ und „Schnabel“ an die Speicherplätzefür die Spalten 1 (\ci) und 3 (\ciii) übergeben. Undin Zeile 6 teilen wir dem Register \cii mit wie breitdie Tabelle werden darf. Davon werden dann in den Zei-len 7 – 10 alle notwendigen Daten abgezogen. Fertig.

Jetzt brauchen wir nur noch \ci bis \ciii als end-gültige Maße an die p-Spalten der tabular-Umgebungweiterreichen (Zeile 13) und – siehe da – unsere Tabellesieht aus wie erhofft.

2.2.4 MultiplikationEine Art der Multiplikation haben wir bereits kennen ge-lernt. Der Faktor wird einfach vor ein Register geschrie-ben (siehe Kapitel 2.1 (Seite 3)).

Es gibt aber auch noch die bereits erwähnte Variantemit \multiply . Hierbei wird das Produkt von Regis-ter und wert wieder in das Register geschrieben.

Page 10: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

6 KAPITEL 2. NIMM’S LEICHT!

Ein Beispiel:Nehmen wir an, wir haben ein Journal mit einem festenSeitenumfang von, sagen wir mal, 48 Seiten. Dann istes doch unsinnig, die Anfangsseitenzahl und die Heft-nummer bei jedem neuen Heft manuell an die Eingabe-maske zu übergeben. Wesentlich einfacher ist es doch,wenn nur die Heftnummer oder nur die Anfangsseiten-zahl angegeben wird und der entsprechende andere Wertdaraus ermittelt wird. Zuerst wollen wir, dass LATEX ausder Heftnummer die resultierende Startseitenzahl ermit-telt.

Prinzipiell müssten wir folgende Rechnung anstellenum die Startseitenzahl zu ermitteln:

He f tnr�(Anzahl Seiten)

He f t� (Anzahl Seiten)+1 (2.1)

oder (und diese Version wird verwendet)

(He f tnr�1)�(Anzahl Seiten)

He f t+1 (2.2)

Da wir keine Einheiten benötigen werden, verwendeich statt der dimen-Register nun count-Register (nähereszu count-Register in Kapitel 3.1 (Seite 9)). Diese lassensich ebenso einfach wie dimen-Register erzeugen, näm-lich mit

\newcount\name.

Die Zuweisungen von werten an diese Register ent-spricht der von dimen-Register. Der wert wird über „=“(gleich) an den Namen des Registers angehängt.

Legen wir zunächst fest um welche Nummer des Jour-nals es sich handeln soll: Zum Beispiel 4. Daraus folgt,dass bisher 3� 48 = 144 Seiten veröffentlicht wurden.Ausgabe 4 beginn folglich bei Seite 145.

Beispiel 5Startseitenzahl

1 \newcount\Heft2 \newcount\PageCalc3 \Heft=44 \PageCalc=\Heft5 \advance\PageCalc by -16 \multiply\PageCalc by 487 \advance\PageCalc by 18 \setcounter{page}{\the\PageCalc}

Das sieht alles furchtbar umständlich aus – ist es auch.Es lässt sich problemlos vereinfachen, zeigt aber gut dieKombination aus den bisher behandelten OperationenAddition und Subtraktion und der neuen Multiplikation.

Im Einzelnen liest sich das so:In den Zeilen 1 und 2 werden neue Speicherplätze an-gelegt (\Heft und \PageCalc). In Zeile 3 überge-ben wir an \Heft die aktuelle Ausgabennummer. Da-mit diese auch für andere Zwecke (Titelseite, Kopf- oderFußzeilen, . . . ) verwendet werden kann, wird sie in Zei-le 4 an ein anderes Register (\PageCalc) weiterge-reicht (kopiert).

In Zeile 5 wird die Heftnummer vermindert (ent-spricht dem Linken Ausdruck unserer Formel). In Zeile 6berechnet LATEX daraus die bereits erschienenen Seiten(hier ist unsere Multiplikation) und erhöht diese in Zei-le 7 auf die neue Startseitenzahl. Abschließend wird dasErgebnis an den Seitenzähler weitergereicht (Zeile 8).

Und jetzt sehen wir noch kurz nach was LATEX da ge-rechnet hat:

Ausgabe \number\Heft\ beginnt

mit Seite \number\PageCalc.

Ausgabe 4 beginnt mit Seite 145.

Und siehe da: Es stimmt.

2.2.5 DivisionWie bei der Multiplikation (Kapitel 2.2.4 (Spalte vor-her)) kann auch hier unsere Prozentrechnerei (Kapi-tel 2.1 (Seite 3)) verwendet werden. Ein paar Daten wie1=4 = :25, 1=8 = :125, . . . hat man ja üblicherweise imKopf und kann sie entsprechend direkt als Faktor für ei-ne Multiplikation einsetzen.

Anders sieht es aus, wenn die Brüche nicht im Kopfabrufbar sind. Hier bietet sich der Befehl \divide an.Auch hierbei wird das Register mit dem Ergebnis derBerechnung überschrieben:

registerwert

! register

Nehmen wir als Beispiel noch einmal das 48 Seitenumfassende Journal. Anstatt die Heftnummer einzuge-ben und die Startseitenzahl berechnen zu lassen, kannnatürlich auch die Seitenzahl eingegeben werden undLATEX berechnet daraus die Heftnummer. Unterstellenwir hier also, dass das aktuelle Heft auf Seite 337 begin-nen soll. Welche Ausgabe wird also gerade bearbeitet?

337�1(anzahl Seiten)

He f t

+1 =337�1

48+1 =

33648

= 8 (2.3)

Beispiel 6Heftnummer

1 \newcount\Heft2 \Heft=3373 \advance\Heft by -14 \divide\Heft by 485 \advance\Heft by 16 Zur Zeit wird Ausgabe \number\Heft\7 bearbeitet

Zur Zeit wird Ausgabe 8 bearbeitet.

Auch diese Antwort ist, wie nicht anders zu erwarten,richtig.

Page 11: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

2.3. APPROXIMATIONEN 7

2.3 Approximationen –Ein bisschen was zumRumprobieren

Tabelle 2.1: Approximationen

Konstante Wert Approximation Fehlerp2 1,41421356. . . 17/12 1,7 �10�3

99/70 5,1 �10�5

577/408 1,5 �10�6

19601/13860 1,5 �10�9p

3 1,73205080. . . 19/11 2,8 �10�3

97/56 5,3 �10�5

989/571 1,0 �10�6

18817/10864 1,1 �10�9p

10 3,16227766. . . 19/6 1,4 �10�3

117/37 3,7 �10�5

721/228 9,6 �10�7

22936/7253 5,7 �10�9

12p

3 1,05946309. . . 18/17 1,0 �10�4

196/185 3,4 �10�6

26797/25293 1,0 �10�9

π 3,14159265. . . 22/7 4,0 �10�4

355/113 8,5 �10�8

e 2,71828182. . . 19/7 1,5 �10�3

193/71 1,0 �10�5

2721/1001 4,1 �10�8

28667/10546 5,5 �10�9

c 2,9979248. . . 1445/482 1,7 �10�7

24559/8192 1,6 �10�9

g 9,80665 196133/20000 genau

Durch entsprechende Brüche lassen sich prinzipiell al-le Konstanten – mit ausreichender Genauigkeit – auchohne Fließkommaarithmetik darstellen. Einige Beispie-le sind in Tabelle 2.1 angegeben. Bei geschicktem Ein-satz der LATEXmöglichkeiten kann häufig auf externe Be-rechnungen (Taschenrechner, Papier, Tabellenkalkulati-on, . . . ) verzichtet werden.

Soll beispielsweise in einem Text wiederholt nebenGrad Celsius auch die Temperatur in Fahrenheit ange-geben werden, ist es doch wesentlich einfacher dies au-tomatisch erledigen zu lassen, als jedesmal die Werte miteinem Taschenrechner auszurechnen und die Ergebnisseabzutippen. Schalten wir diese Fehlerquelle aus und kre-ieren einen neuen Befehl (zum Beispiel \CF genannt),der dies für uns erledigt:

° F =°C�9

5+32 (2.4)

Beispiel 7Fahrenheit aus Grad Celsius

1 \newcommand{\CF}[1]{% F = x*9/5+32 gradC2 \newcount\C3 #1~symbol{6}C4 \C=#15 \multiply\C by 96 \divide\C by 57 \advance\C by 328 (\the\C~\symbol{6}~F)9 }

10

11 \paragraph{Wasser (H$_{\mathbf{2}}$O)}12 Siedepunkt: \CF{100},13 Gefrierpunkt \CF{0},14 Schmelzpunkt \CF{4}.

Wasser (H2O) Siedepunkt 100 ˚C (212 ˚ F) , Gefrier-punkt 0 ˚C (32 ˚ F) , Schmelzpunkt 4 ˚C (39 ˚ F) .

Page 12: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

8 KAPITEL 2. NIMM’S LEICHT!

Page 13: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

3.1. COUNT-REGISTER 9

3 Register –In der Registratur sind noch Stellen frei

Relevante Befehle (Kurzübersicht)

\newcount \number\typeout \global\newdimen \the\newskip \setlength\settowidth \settoheight\settodepth \addtolength

Im vorherigen Teil wurden bereits verschiedene Re-gister vorgestellt und diese auch verwendet. Was hat esaber damit auf sich?

TEX stellt eine ganze Reihe unterschiedlicher Re-gistertypen zur Verfügung: count -, dimen -, skip -,muskip -, box - und token-Register . In diesem Textwerden aber nur die drei erstgenannten Registertypen be-handelt.

Jeder dieser drei Typen stellt 256 Register zur Verfü-gung, wovon jeweils ein kleiner Teil bereits reserviertist. Um Kollisionen mit den reservierten oder von ande-ren Paketen verwendeten Registern zu vermeiden, müs-sen diese irgendwie verwaltet werden. Dies kann zwar„per Hand“ vorgenommen werden, das führt aber hierzu weit (wen es interessiert sei auf [2], [5], [9] und [7]verwiesen) – aber man muss sich ja das Leben nicht un-nötig schwer machen. Daher werden hier nur die Befeh-le verwendet, die die Verwaltung für uns übernehmen.

In der Regel sind das Befehle, die Register deklarieren.Wir müssen also LATEX mitteilen welches Register wirverwenden wollen. Dummerweise unterscheidet sich dieSyntax dieser Befehle bei den einzelnen Registertypenetwas (siehe also dort und beim bisherigen Einsatz).

Im Folgenden wird name (in dieser Schreibweise) füreinen frei wählbaren Registernamen verwendet, der kei-ne anderen Zeichen als Buchstaben enthalten darf und,in gängiger LATEX-Manier, „case-sensitiv“, also mit pin-geliger Unterscheidung von Groß- und Kleinbuchstaben,ausgewertet wird.

Deklarieren wir ein Register in einer .sty-Datei, stehtauch noch der „Klammeraffe“(@; neudeutsch: at –sprich: ät) für die Namensvergabe zur Verfügung (eskönnen auch andere Zeichen hinzukommen, das wäreaber nicht LATEXkonform und wird hier nicht beschrie-ben). Es genügt zu wissen, dass sich durch Verwendungdes Klammeraffen beispielsweise Befehle oder auch Re-gister erzeugen lassen, die dem normalen Anwendernicht zugänglich sind, so dass dieser keine Chance be-kommt, hiermit Unfug zu treiben.

Die Einrichtung weiterer Register vom selben Typmit gleichem Namen ist nicht zulässig und wird vonLATEX dementsprechend auch angemeckert: „ERROR:LaTeX Error: Command \name alreadydefined.“. Ein Register kann nach der Einrichtungimmer wieder verwendet/überschrieben werden.

3.1 count-Register –Der Kandidat hat 99 Punkte

Neue Befehle\newcount

\number

\global

\typeout

Beginnen wir mit dem einfachsten Registertyp: demcount-Register.

count-Register haben nichts mit den sicherlichbekannten countern, etwa page, footnote,figure, . . . , zu tun (siehe zu countern [6])!

Ein count-Register kann man sich als einen Speicher-platz für ganze Zahlen vorstellen. Mit solch einem Spei-cherplatz lassen sich Modulo-Rechnungen durchführen,oder anders formuliert: Weist das Ergebnis der Berech-nung einen von Null verschiedenen Nachkommateil auf,wird dieser ohne Rundung entfernt – und ward nie wie-der gesehen!

Nach der Einrichtung mit

\newcount\name

muss ein count-Register initialisiert , also mit einemStartwert versehen werden. Die Syntax hierzu lautet:

\name=wert

wobei wert ein Literal, ein anderes Register oder ein Pro-dukt aus beiden sein kann.

Für Berechnungen stehen die bereits bekannten Be-fehle

\advance\name by wert\multiply\name by wert\divide\name by wert

zur Verfügung. Das ergebnisaufnehmende Register na-me kann selbstverständlich auch als wert oder Bestand-teil von wert verwendet werden. Um beispielsweise eineZahl im Register quadrat zu quadrieren kann

\multiply\quadrat by \quadrat

geschrieben werden.

Page 14: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

10 KAPITEL 3. REGISTER

Soll der Inhalt eines count-Registers als Ausgabe imDokument erscheinen, kann dieser mit

\number\name

ausgegeben werden.

Der gleichnamige Inhalt eines count-Registers ineiner Gruppe kann von dem Inhalt außerhalb

dieser Gruppe abweichen, wobei hier als Gruppeabgeschlossene Bereiche wie { . . .},

\begingroup . . .\endgroup, Umgebungen,u. s. w., gemeint sind. Der Inhalt des Registers wirdbei Eröffnung einer Gruppe zwischengespeichert

und nach Beendigung wieder restauriert.

Ein Beispiel soll dies demonstrieren:

Beispiel 8Count-Register (Restaurierung nach Gruppenbildung)

1 \newcount\a2 \a=13 \number\a\quad4 {%5 \advance\a by \a6 \number\a\quad7 }8 \number\a

In Zeile 2 wird das neu angelegte Register \a (Zei-le 1) mit „1“ initialisiert und als Ergebnis ausgedruckt(Zeile 3). In Zeile 4 wird eine Gruppe eröffnet. Hierinwird \a mit sich selbst addiert (Zeile 5), in \a befindetsich nun also die Zahl „2“, was auch wieder protokolliertwird (Zeile 6). Anschließend wird die Gruppe wiedergeschlossen (Zeile 7). Da die Zeilen 4 – 7 eine Gruppebilden, wurde der Inhalt von a vor der Ausführung derGruppe intern zwischengespeichert. Nachdem die Grup-pe abgearbeitet ist, wird \a restauriert – protokolliert inZeile 8. Es müsste sich jetzt also die Zahlenfolge „1 21“ ergeben. Prüfen wir es nach:

1 2 1

Soll die Restaurierung unterbleiben, muss innerhalbder Gruppe der Befehl \global vor die letzte regis-termanipulierende Operation geschrieben werden. UnserBeispiel sollte dann „1 2 2“ liefern:

Beispiel 9Count-Register (keine Restaurierung nach Gruppenbildung)

1 \newcount\a2 \a=13 \number\a\quad4 {%5 \global\advance\a by \a6 \number\a\quad7 }8 \number\a

1 2 2

Manchmal möchte man aber auch nur kontrollieren,ob die Zwischenergebnisse stimmen und sie nicht imText ausgeben, dann kann die Ausgabe auf den Bild-schirm umgelenkt werden:

\typeout{ausgabe}

In unserem Beispiel sieht das etwa so aus:

Beispiel 10Count-Register (Inhaltskontrolle)

1 \newcount\a2 \a=13 \typeout{^^JReg a vorher: \number\a^^J}4 {%5 \global\advance\a by \a6 \typeout{Reg a während: \number\a^^J}7 }8 \number\a9 \typeout{Reg a nachher: \number\a^^J}

wobei ^^J (3 Zeichen! Bitte so eingeben!) für einenZeilenumbruch, genauer gesagt für ein linefeed steht(ASCII 10; Ctrl-J; dies funktioniert in dieser Form nurinnerhalb des \typeout-Befehls).

3.2 dimen-Register –Das Maß aller Dinge

Neue Befehle\newdimen

\the

Was sind dimen-Register?

Es handelt sich hierbei um Register, die mit der Maß-einheit sp (scaled point) fest verknüpft sind. Jede Größe(also eine Zahl mit Einheit), die an ein dimen-Regis-ter übergeben wird, wird in sp umgerechnet. Wichtig zuwissen ist, dass die absolute übergebene Größe nicht grö-ßer als 230 = 1073741824 sp werden darf.

Scaled points gehören zum Wertebereich derganzen Zahlen!

Da 65536 sp = 1 pt sind, lassen sich also Maße bis zurGröße 16348 pt� 226:7 inch oder grob 5.75 m verarbei-ten. Das ist doch schon was! Wer also eine eigene Tapetegestalten will . . .

Doch zurück zum Thema.Wie bei den count-Registern, müssen auch dimen-

Register erst einmal eingerichtet werden. Hierzu stelltLATEX den Befehl

\newdimen\name

bereit.

Page 15: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

3.3. SKIP-REGISTER 11

Anschließend muss auch dieses Register initialisiertwerden:

\name=wert

wobei wert, wie bereits erwähnt, eine einheitenbehafteteZahl sein muss. Bei dieser Zahl muss es sich aber nichtzwangsläufig um ein Literal handeln, sondern es könnenauch andere Register hierzu herangezogen werden.

In den Kapiteln 2.2.2 (Seite 4) bis 2.2.5 (Seite 6)wurden bereits einige Rechenbeispiele gezeigt. Auchhier stehen die von den count-Registern bekanntenRechenbefehle

\advance\name by wert\multiply\name by wert\divide\name by wert

zur Verfügung.

Jedoch ist der Wertebereich auf den der reellen Zahlenerweitert. Wie bei den count-Registern werden auch hierdie Ergebnisse der Rechenoperationen in das mit namebezeichnete Register geschrieben.

Die Ausgabe im Dokument erfolgt mit dem Befehl

\the\name

eine Kontrollausgabe auf dem Bildschirm während desLATEXlaufs kann mit

\typeout{\the\name}

erreicht werden.Da nur Größen als wert erlaubt sind, können count-

Register nicht direkt an dimen-Register übergeben wer-den. count-Register können aber als Faktor für zum Bei-spiel 1 pt (\@pt) verwendet werden.

3.3 skip-Register –Eine klebrige Angelegenheit

Neue Befehle\newskip

\newlength

\setlength

\settowidth

\settoheight

\settodepth

\addtolength

skip-Register sind mit dimen-Registern vergleichbar.Der Unterschied besteht darin, dass skip-Register überzusätzliche Informationen verfügen können (Streckung/Stauchung und Schrumpfung, dazu gleich mehr). Auchskip-Register müssen erst einmal deklariert werden,bevor sie angewendet werden können. Hierzu stehen nunzwei Möglichkeiten zur Verfügung („althergebracht“zuerst, dann die alternative). Ich empfehle Anfängernin der Materie jeweils die Alternativ, da sie vielleichtintuitiver sein kann. Zum einen die bereits bekannteVariante über newregister:

\newskip\nameund alternativ:\newlength{\name}

Anschließend erfolgt, wie üblich, die Initialisierung.Auch hier gibt es wieder zwei Möglichkeiten:

name=wert1 plus wert2 minus wert3oder:\setlength{\name}{%

wert1 plus wert2 minus wert3}

wobei wert1 einen Grundwert darstellt, der um die Maßewert2 und wert3 schwanken darf. KOPKA [2] spricht indiesem Zusammenhang von „elastischen Maßen“ wäh-

rend CREMER [4] von „Leim“ (engl. glue) schreibt.Die Bezeichnung glue wurde für diesen Zweck vonKNUTH [8] eingeführt. Bei SCHWARZ/POTUCEK [3]wird dieses Verhalten mit „Federn“ verglichen. GenaueBeschreibungen des Verhaltens des „Leims“ sind beiKOPKA [2] und CREMER [4] zu finden.

Es ist nicht unbedingt nötig eine Schrumpfung und/oder Dehnung anzugeben. Wird eine der beiden Anga-ben oder beide Angaben nicht verwendet, bleibt ihr ur-sprungswert erhalten, wurde kein Ursprungswert übwer-geben ist dieser „0sp“.

Außerdem stehen zur Initialisierung auch noch dieBefehle

\settowidth{\name}{wert}\settoheight{\name}{wert}\settodepth{}name}{wert}

zur Verfügung.Der Befehl \setlength kann beispielsweise als:

\setlength{\a}{15mm}

oder\setlength{\a}{17dd plus 5pt minus 5bp}

oder\setlength{\a}{5\b},

aufgebaut sein, wobei im ersten Beispiel ein Literal ohneToleranzgrenzen, im zweiten Beispiel ein Literal mit To-leranzgrenzen und zum Schluss das Produkt aus Literalund einem Register/einer Definition eingesetzt wurden,wobei das Register/die Definition folglich eine einhei-tenbehaftete Zahl beinhalten muss.

Die drei anderen Befehle können in der Form

\settowidth{\a}{ab5d\hspace{20mm}8888}

oder\settoheight{\a}{\PIC}

oder

Page 16: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

12 KAPITEL 3. REGISTER

\settodepth{\a}{{\huge Guppi}}

verwendet werden, wobei hier für wert im ersten Fallein zusammengesetztes Literal, im zweiten Fall eineBox/eine Definition (etwa ein Bild), und schließlichnoch ein Literal beispielhaft aufgeführt wurden.

Betrachten wir die drei letztgenannten Zuweisungsbe-fehle genauer. \settowidth ermittelt die Breite desübergebenen wertes, \settoheight wiederum dieHöhe des wertes (und zwar ab der Gundlinie nach oben;bei Versalien also die Versalhöhe) und \settodepthdie Unterlänge von wert (also das benötigte Maß von derGrundlinie nach unten; beispielsweise bis zum Fußpunkteines der Buchstaben „g“, „ j“, „p“, „q“, „y“). Um alsodie Gesamthöhe des aktuellen Zeichensatzes zu erhalten,müssen die mit \settoheight und \settodepthermittelten Werte addiert werden.

In den Kapiteln 2.2.2 (Seite 4) bis 2.2.5 (Seite 6)wurden bereits einige Rechenbeispiele gezeigt. Nebenden dort vorgestellten Befehlen

\advance\name by wert\multiply\name by wert\divide\name by wert

existiert hier ein vereinfachter Additionsbefehl:

\addtolength{\name}{wert}

Jeder der drei Werte der Addition/Subtraktion kannfür sich geändert werden:

\advance\name by wert1 plus wert2 minus wert3

Entfällt bei Addition/Subtraktion beispielsweise derTeil „plus wert2“ wird das ursprüngliche Streckmaßbeibehalten und nur der Grundwert und der Stauchungs-wert angepasst.

Bei der Multiplikation/Divion eines skip-Registerswird jedes einzelne Maß in name mit dem einheiten-

freien(!) wert multipliziert beziehungsweise durch die-sen geteilt:\multiply\name by wert

\divide\name by wert

Wenn also beispielsweise \medskipamount ausTabelle 3.1 mit, sagen wir einmal, „3“ multipliziert wird:

Beispiel 11Skip-Register (Multiplikation)

1 \multiply\medskipamount by 3

dann erhalten wir „18pt plus 6pt minus 6pt“.

Wofür sind skip-Register aber letztendlich gut?

Nehmen wir ein einfaches Beispiel:Wir haben ein Layout, bei dem eine bestimmte AnzahlZeilen für eine Seite in Brotschriftgröße (Grundschrift-größe) vorgesehen ist. Wenn jetzt eine Tabelle auf die-ser Seite ausgegeben werden soll und diese nicht ge-nau soundsoviele Zeilen hoch ist (der Regelfall), dannversucht LATEX den Inhalt der Seite so zu strecken oderzu stauchen, dass er am unteren Rand wieder bündigmit dem Satzspiegel ist. Dieses automatische Streckenoder Stauchen darf aber nur in einem für den Heraus-geber/Verlag akzeptablen Rahmen passieren. Und genausolche Toleranzgrenzen werden hinter wert1 angegeben.hinter plus wird die zulässige Streckung und hinterminus die zulässige Schrumpfung übermittelt.

Um den Zweck weiter zu verdeutlichen, habe ich inTabelle 3.1 ein paar skip-Register zusammengestellt. Da-neben gibt es noch eine ganze Reihe skip-Register, dieohne „Leim“ initialisiert sind. Dies hat den Vorteil, dasssie sehr leicht den eigenen Bedürfnissen angepasst wer-den können. Das Wort „skip“ muss nicht zwangsläu-fig Bestandteil des Namens sein (siehe zweiter Eintragin Tabelle 3.1), es hat sich aber als guter Stil durchge-setzt.

Tabelle 3.1: Einige skip-Register

Register default (bei Brotschriftgröße 10pt)

\parskip 0pt plus 1pt (vertikal)\indexspace 10pt plus 5pt minus 3pt (vertikal)\abovedisplayskip 10pt plus 2pt minus 5pt (vertikal, bei normalsize in der Book-Klasse)\medskipamount 6pt plus 2pt minus 2pt (vertikal)\baselineskip plus1ex minus1ex 12pt �1 ex (vertikal, bei 10pt Schriftgröße)

3.4 Registertypen kombinieren –Äpfel mit Birnen verrechnen

3.4.1 skip dimen

KOPKA schreibt in [2], dass ein dimen-Register nichteinem skip-Register zugewiesen werden kann, „da ei-nem \skip-Register zwingend ein elastisches Maß zu-

geordnet werden muß“, aber diese Aussage kann so nichtstehen bleiben. Vielmehr handelt es sich dann ledig-lich um ein skip-Register ohne Dehnung und Schrump-fung (also plus 0pt minus 0pt), statt mit Stre-ckung/Schrumpfung wie beispielsweise in Tabelle 3.1bei \baselineskip plus1ex minus1ex. Dieswird an folgendem Beispiel deutlich, welches:

Page 17: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

3.4. REGISTERTYPEN KOMBINIEREN 13

Beispiel 12Äpfel = Birnen

1 \newdimen{\aepfel}2 \aepfel=5pt3 \newskip{\birnen}4 \birnen=\aepfel5 Birnen = Äpfel: \the\birnen\\6 \advance\birnen by 0pt plus 0pt minus 0pt7 Birnen mit Placebo-Leim: \the\birnen\\8 \advance\birnen by 0pt plus 0pt minus 1pt9 Birnen mit Honig: \the\birnen\\

Birnen = Äpfel: 5.0ptBirnen mit Placebo-Leim: 5.0ptBirnen mit Honig: 5.0pt minus 1.0pt

liefert.Die Zeilen 1 und 2 deklarieren und initialisieren das

dimen-Register aepfel, dessen Inhalt in Zeile 4 an dasskip-Register birnen (Zeile 3) weitergereicht wird, wieZeile 5 beweist. In Zeile 6 packen wir noch ein wenig„Placebo-Leim“ drauf und sehen in Zeile 7 nach, wasrausgekommen ist. Es hat sich, wie erwartet, nichts geän-dert. In Zeile 8 wird es dann richtig klebrig, wie Zeile 9beweist. Da in den Zeilen 6 und 8 der gleiche Rechenbe-fehl verwendet wurde und das Ergebnis von Zeile 7 mitdem Ergebnis von Zeile 5 identisch ist, kann man dar-aus schlussfolgern, dass sich sehr wohl Äpfel mit Birnen– pardon dimen-Register mit skip-Register – verrechnenlassen; die Toleranzen (glue) bewegen sich lediglich imRahmen plus 0pt minus 0pt.

Was passiert aber, wenn wir ein skip- an ein di-men- oder count-Register übergeben? Wie müssen/kön-nen count-Register aufbereitet werden, damit sie dimen-/skips-registertauglich sind? . . . ?

Zur Frage:„Wie stellt man fest, wie groß das aktuelle Schrumpf-/Streckmaß ist?“ oder anders gefragt, wie können dieseAngaben auf einfache Weise abgefragt werden ohne dierechtlichen Daten mit ausgegeben zu bekommen? Aufdiese Fragen konnte ich bis jetzt, trotz intensiver Nach-forschungen, keine befriedigende Anwort finden. Viel-leicht kann mir der eine oder die andere hierbei weiter-helfen.

3.4.2 count dimenMit welchem Ergebnis ist zu rechnen, wenn wir den In-halt eines dimen-Register an ein count-Register weiter-reichen. Beispiel:

Beispiel 13Dimen- nach Count-Register

1 \newcount\ziel2 \newdimen\quelle3 \quelle=5pt4 \ziel=\quelle

Die Vermutung liegt nahe, dass in \ziel der Wert„5“ steht (also ohne Einheit). Prüfen wir es nach:

\number\ziel 327680

Ups! Wie das? Naja, eigentlich ist es logisch. LATEXwandelt die „5pt“ in „327680sp“ um. Und dies um sei-

ne Einheit beraubt ergibt unser Ergebnis. Um wieder aufden erhofften Wert „5“ zu kommen, muss \ziel alsonoch durch 65536 (zur Erinnerung: 1pt = 65536sp) ge-teilt werden:

Beispiel 14Count- nach Dimen-Register (Ausgabeanpassung)

1 \divide\ziel by 655362 \number\ziel

5

Und siehe da, jetzt stimmt’s.

3.4.3 count skip

Hier kann ich mich kurz fassen. Die Streck- undSchrumpfmaße werden ignoriert und das Grundmaß, wieim Kapitel 3.4.2 beschrieben, behandelt.

3.4.4 dimen count

Da dimen-Register zwingend eine Maßeinheit verlan-gen, müssen wir der „blanken“ Zahl im count-Registerirgendwie eine Einheit mit auf den Weg geben.

Beispiel 15Count- nach Dimen-Register

1 \newdimen\Einheit2 \Einheit=1in3 \newdimen\ziel4 \newcount\inch5 \inch=26 \ziel=\inch\Einheit7 \the\ziel

oder kurz

Beispiel 16Count- nach Dimen-Register (kurz)

1 \newdimen\ziel2 \ziel=1in3 \newcount\inch4 \inch=25 \multiply\ziel by \inch6 \the\ziel

144.53998pt

Und das stimmt mit dem zu erwartenden Ergebnis über-ein (1in = 72.27pt; 2in = 144.54pt).

3.4.5 dimen skip

Übergeben wir den Inhalt eines skip-Registers an eindimen-Register. Die Vermutung liegt nahe, dass der„Leim“ einfach ins Nirwana verfrachtet wird und nur derGrundwert übrig bleibt. Probieren wir es aus:

Page 18: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

14 KAPITEL 3. REGISTER

Beispiel 17Skip- nach Dimen-Register

1 \newlength{\birnen}2 \setlength{\birnen}{6pt plus 3pt minus 1pt}3 \the\birnen\\4 \newdimen\aepfel5 \aepfel=\birnen6 \the\aepfel\\

6.0pt plus 3.0pt minus 1.0pt6.0pt

Auch hier verhält sich LATEX wie erwartet.

3.4.6 skip countHier kann ich mich wieder kurz fassen. Auch hier giltdas bei Kapitel 3.4.4 (Spalte vorher) Gesagte. Durcheine Addition der Streck- und Schrumpfmaße wirddaraus ein vollwertiger skip-Registerinhalt.

Page 19: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

4.2. ZWISCHENSPEICHER 15

4 Darf’s auch etwas mehr sein? –Ausgelagerte Berechnungen

Relevante Befehle (Kurzübersicht)

\@cclv \@cclvi \@m\@M \@Mi \@Mii\@Miii \@Miv \@MM\@ne \@tempcnta \@tempcntb\@tempdima \@temdimb \@tempdimc\@tempskipa \@tempskipb \@xxxii\closein \closeout \immediate\input \m@ne \newread\newwrite \openin \openout\p@ \read \sixt@@n\thr@@ \two \write\z@ \z@skip

Unter „ausgelagerte Berechnungen“ verstehe ichhier Berechnungen, deren Formalismen in .sty-Filesabgelegt sind. Sie können bei Bedarf mittels

\usepackage{stylefile}

in Dokumente eingebunden werden. Es handelt sich alsovorwiegend um Routineaufgaben.

Bevor ich Beispiele bringe, möchte ich einige Re-gister und Kürzel vorstellen, die die Arbeit erleichternhelfen.

4.1 Zahlen

Die in Tabelle 4.1 vorgestellten Zahlen schreiben sichin der Regel länger als der Einsatz eines Literals,haben aber den Vorteil, dass sie weniger Speicherplatzbenötigen und bei einer De-tokenisierung einfacher zuhandhaben sind (Einzelheiten erspare ich mir in diesemText).

Tabelle 4.1: Zahlkürzel

Befehl Wert Befehl Wert

\z@ 0 \@cclvi 256\@ne 1 \@m 1000\m@ne �1 \@M 10000\tw@ 2 \@Mi 10001\thr@@ 3 \@Mii 10002\sixt@@n 16 \@Miii 10003\@xxxii 32 \@Miv 10004\@cclv 255 \@MM 20000

4.2 ZwischenspeicherHilfreich, schnell und platzsparend, so kann man die inTabelle 4.2 aufgeführten Zwischenspeicher zusammen-fassen. Nach Möglichkeit sollte von ihnen Gebrauch ge-macht werden.

Daneben gibt es noch die Kürzel „\p@“, das mit „1pt“vordefiniert ist und mit einem vorangestellten Faktor an-

gepasst werden kann sowie \z@skip, das das skip-Maß „0pt plus 0pt minus 0pt“ liefert.

Weitere Kürzel werden durch die unterschiedlichstenPakete bereitgestellt und können in deren Beschreibun-gen (meistens) nachgelesen werden.

Doch nun endlich zu den Beispielen.

Tabelle 4.2: Temporäre Speicher

Befehle Zweck

\@tempcnta \@tempcntb count-Register\@tempdima \@tempdimb \@tempdimc dimen-Register\@tempskipa \@tempskipb skip-Register

Page 20: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

16 KAPITEL 4. AUSGELAGERTE BERECHNUNGEN

4.3 Tabellen mit Abbildungen

4.3.1 . . . für Einzelfälle

Ich habe häufiger mit Tabellen zu tun, in denen kleineAbbildungen vertikal zentriert neben Text stehen sollen.„Wo ist das Problem?“, wird sich mancher jetzt fragen.Na ja, sehen wir es uns an:

Beispiel 18Tabelle mit Abbildung (ungewuenscht)

1 \begin{table}[h]2 \caption{Ein Bild}3 \begin{tabular*}{\columnwidth}{4 @{\extracolsep{\fill}}lll}5 \hline6 links & Bild & rechts\\7 \hline8 gxH\rule{10mm}{.4pt}9 & \includegraphics[width=20mm]{platzhalter}

10 & \rule{10mm}{.4pt}Hjx\\11 gxH\rule{10mm}{.4pt}12 & \includegraphics[width=20mm]{platzhalter}13 & \rule{10mm}{.4pt}Hjx\\14 \hline15 \end{tabular*}16 \end{table}

Tabelle 4.3: Bild auf Grundlinielinks Bild rechts

gxH Hjx

gxH Hjx

Und? Was fällt auf? Das Bild sitzt nicht vertikal zen-triert in der Zeile! An den gezeichneten Hilfslinien, dieauf der Grundlinie stehen, kann man gut erkennen, dassdie Abbildung ebenfalls auf der Grundlinie steht.

Zur Lösung des Problems gibt es zwei Ansätze. ZumEinen können die Texte nach oben, zum Anderen kanndie Abbildung nach unten geschoben werden. Egal, wel-chen Weg wir auch einschlagen, wir müssen in jedemFall wissen wie hoch das Bild ist, damit wir die Hälf-te berechnen (lassen) können. Außerdem muss noch dieSchriftgröße berücksichtigt werden; und dann muss ent-schieden werden, ob die Mitte des Bildes auf der Grund-linie, auf der „x“-Höhe, auf der halben Zeichenhöhen(von Oberlänge bis Unterlänge) oder mittig, bezogen aufden Zeilenabstand, stehen soll. Es handelt sich dabeizwar jeweils nur um geringe Unterschiede, aber selbstungeübte Augen merken diese sofort. Und als ob dasnicht schon genug Überlegungen wären, müssen wir na-türlich auch noch berücksichtigen, dass durch den Ver-schub ein normaler Zeilenumbruch in der Tabelle nichtreicht. Auch hier muss noch entsprechend nachgebessertwerden.

Ich entscheide mich in der Regel für die halbe Zei-chenhöhe und verschiebe, bei mehr Text- als Bildspal-

ten, die Abbildung. Probieren Sie zur Übung doch ein-fach einmal die zweite Variante aus. Ein paar Gedankenvorab und es sollte funktionieren.

Zuerst ermitteln wir die Bildhöhe:

Beispiel 19Tabelle mit Abbildungen (Bildhöhenermittlung)

1 \def\Pic{\includegraphics[width=20mm]{platzhalter}}2 \newlength{\PicHeight}3 \settoheight{\PicHeight}{\Pic}4 \divide\PicHeight by 2

In Zeile 1 wird ein Befehl definiert, der das Bild auf-ruft. Dieser Schritt ist eigentlich überflüssig, hat aberden Vorteil, dass ich den \includegraphics-Befehlnicht zweimal eintippen muss, einmal hier zur Berech-nung und dann in der Tabelle zur Bildausgabe – dazubin ich dann doch zu faul. In Zeile 2 richte ich dann nocheinen Speicherplatz ein, an den in Zeile 3 die Höhe derAbbildung übergeben wird. Das ganze wird dann nochhalbiert (Zeile 4) – fertig.

Stopp! Wir wollen ja auch noch die Zeichenhöhe be-rücksichtigen:

Beispiel 20Tabelle mit Abbildungen (Schriftzeichenhöhe ermitteln)

1 \newlength{\LetSize}2 \settoheight{\LetSize}{O}3 \settodepth{\@tempdima}{g}4 \advance\LetSize by \@tempdima5 \divide\LetSize by 2

In Zeile 1 richte ich den Speicherplatz für die Zeichen-größe \LetSize ein und packe da schon einmal dieVersalhöhe des Buchstabens „O“ hinein (Zeile 2; „O“deshalb, weil der Bogen am oberen Ende in der Regeletwas über die Versalhöhen von „H“ oder „M“, die übli-cherweise verwendet werden, hinausragt). Anschließend(Zeile 3) wird die Unterlänge an einen temporären Spei-cher übergeben, um dann in Zeile 4 zur Versalhöhe ad-diert zu werden. Da ja nur die halbe Höhe benötigt wird,erfolgt in Zeile 5 noch eine Halbierung der Summe.

Schön, nun haben wir also die halbe Bildhöhe und diehalbe Zeichenhöhe – und jetzt? Jetzt werden die beidenErgebnisse kombiniert (subtrahiert) und an eine Raise-box weitergereicht.

Beispiel 21Tabelle mit Abbildungen (Bildhöhe minus Schrifthöhe)

1 \advance\PicHeight by -\LetSize

Beispiel 22Tabelle mit Abbildungen (Übergabe an raise-Box)

1 \begin{table}[h]2 \caption{Ein Bild --3 jetzt aber vertikal zentriert}4 \begin{tabular*}{\columnwidth}{5 @{\extracolsep{\fill}}lll}6 \hline7 links & Bild & rechts\\8 \hline9 \\

10 gxH\rule{10mm}{.4pt} &11 \raisebox{-\PicHeight}[\PicHeight]{\Pic}12 & \rule{10mm}{.4pt}Hjx\\13 \\

Page 21: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

4.3. TABELLEN MIT ABBILDUNGEN 17

14 gxH\rule{10mm}{.4pt} &15 \raisebox{-\PicHeight}[\PicHeight]{\Pic}16 & \rule{10mm}{.4pt}Hjx\\[\PicHeight]17 \hline18 \end{tabular*}19 \end{table}

Mal seh’n was rauskommt:

Tabelle 4.4: Ein Bild – jetzt aber vertikal zentriertlinks Bild rechts

gxH Hjx

gxH Hjx

4.3.2 . . . für BildserienNun das Ganze allgemeingültig für eine durchgezählteBildserie. Es wird dabei unterstellt, dass alle Abbildun-gen die gleiche Breite haben. Versuchen Sie die Routineso zu ändern, dass auch mehrere Abbildungen pro Zei-le möglich sind. Oder sie benötigen immer Abbildungenmit fester Höhe und variabler Breite? Probieren Sie ru-hig ein wenig herum. – Sie wissen ja „Übung macht denKönner“.

Doch zurück zum Thema:Die Höhe der Abbildungen wird proportionsrichtig für

jedes einzelne Bild neu bestimmt und ein neuer Befehl(\pcr) für den Zeilenumbruch eingerichtet, der die Ab-bildungshöhe berücksichtigt.

Die unten stehenden Zeilen können so wie sieda stehen in eine .sty-Datei, nennen wir sie ein-fach „VPicInTab.sty“ (VertikalPicturesInTables), ge-schrieben werden. Sie müssen dann bei Bedarf mittels\usepackage{VPicInTab} eingebunden werden.

Der Aufbau der gerade einmal 14 Zeilen umfassendenLösung ist so simpel, dass sich weitere Erklärungen er-übrigen, zumal der Text auch noch gut auskommentiertwurde.

Beispiel 23Tabellen mit Abbildungen (mehrere Abbildungen)

1 \newcommand{\PicBreite}[1]{\def\PB{#1}} % Alle Bilder gleich breit2 \newcommand{\PicName}[1]{\def\PN{#1}} % Zur Übergabe des Seriennamens3 \newcommand{\PIC}[1]{%4 \def\pic{\includegraphics[width=\PB]{\PN#1}} % Bild "SeriennameNummer" holen5 \settoheight{\@tempdima}{\pic} % Bildhöhe bestimmen6 \divide\@tempdima by \tw@ % Bildhöhe halbieren7 \settoheight{\@tempdimb}{O} % Oberlänge8 \settodepth{\@tempdimc}{g} % Unterlänge9 \advance\@tempdimb by \@tempdimc % Oberlänge + Unterlänge

10 \divide\@tempdimb by \tw@ % Halbe Schriftgröße11 \advance\@tempdima by -\@tempdimb % Bildhöhe - Schriftgröße12 \raisebox{-\@tempdima}{\pic} % Bild ausgeben13 \global\def\pcr{\tabularnewline[\@tempdima]} % pic carriage return14 }

Probieren wir unseren neuen Stil aus:Nicht nur, dass das Ergebnis sich jetzt sehen lassen

kann, auch der Aufbau der Tabelle (siehe unten) ist, ge-genüber der manuellen Version (Beispiel 22), jetzt we-sentlich einfacher und übersichtlicher geworden:

Beispiel 24Tabelle mit Abbildungen (Einfache Tabelle)

1 \PicBreite{20mm}2 \Serie{rmst}3 \begin{table}[h]4 \caption{Eine Bildserie --5 -- automatisch vertikal zentriert}6 \begin{tabular*}{\columnwidth}{7 @{\extracolsep{\fill}}lll}8 \hline9 links & Bild & rechts\\

10 \hline11 Bild 1 & \PIC{01} & Der Rahmen\pcr12 Bild 2 & \PIC{02} & Ein Trapez\pcr13 Bild 3 & \PIC{03} & Noch eins\pcr14 Bild 4 & \PIC{04} & Ein Kreis\pcr15 Bild 5 & \PIC{05} & Zusammen\pcr16 \hline17 \end{tabular*}18 \end{table}

Tabelle 4.5: Eine Bildserie – automatisch vertikal zen-triert

links Bild rechts

Bild 1 Der Rahmen

Bild 2 Ein Trapez

Bild 3 Noch eins

Bild 4 Ein Kreis

Bild 5 Zusammen

Page 22: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

18 KAPITEL 4. AUSGELAGERTE BERECHNUNGEN

4.4 pt! mmWie in Kapitel 2.2.2 (Seite 4) bereits versprochen wurde,soll auch eine Möglichkeit gezeigt werden, wie die Aus-gabe eines Registers im Dokument statt in „pt“ in „mm“erreicht werden kann.

Beispiel 25pt nach mm

1 \def\MM#1{2 \@tempdima=#13 \@tempdima=.35146\@tempdima4 \def\vn##1.##2!!{%5 \global\edef\vara{##1}%6 \global\edef\varb{##2}%7 }%8 \expandafter\vn\the\@tempdima!!%9 \vara.%

10 \def\ziffer{%11 \@tempdimb=0.\varb%12 \@tempdimb=10\@tempdimb%13 \expandafter\vn\the\@tempdimb!!%14 \vara%15 }%16 \ziffer\ziffer\ziffer\ziffer\ziffer~mm%17 }

Was passiert hier?Die notwendigen Variablen (\@tempdima und

\@tempdima) stellt LATEX bereits zur Verfügung. InZeile 1 wird der Befehl zur Umrechnung aufgebaut. Zei-le 2 kopiert das Maß in einen Zwischenspeicher (Sicher-heit ist angesagt! – wir wollen ja unser Original nichtkaputtschreiben).

Jetzt beginnt die eigentliche Rechnerei. Um Über-/Unterläufe des zulässigen Bereichs möglichst zu umge-hen wird nicht 72.27 beziehungsweise 25.4 als Umrech-nungszahlen für pt nach inch und inch nach mm gear-beitet, sondern direkt mit 25:4

72:27 = 0:35146 (Zeilen 3).

Auch wenn jetzt schon die Umrechnung, bezogen aufdie Werte, stattgefunden hat, ausgegeben würde uns dasErgebnis aber immer noch in pt (richtige Zahl, falscheEinheit).

Zerlegen wir also die „richtige“ Zahl in ihren Vor-und Nachkommateil. Hierzu brauchen wir die Subrou-tine \vn (Zeilen 4 bis 7). Der Vorkommateil wird in\vara, der Nachkommateil wird in varb (Zeilen 5und 6) abgelegt. Nach der übergabe des Wertes an vn(Zeile 8) wird der Vorkommateil vara gefolgt von ei-nem Punkt (nach Bedarf kann hier auch ein Komma ein-gesetzt werden) ausgegeben (Zeile 9). Leider kann derNachkommateil nicht unmittelbar an ein Register über-geben werden, da dann automatisch führende Nullen ent-fernt werden. Daher wird in der nun folgenden Subrouti-ne \ziffer (Zeilen 10 bis 17) 0. (Zeile 11) vor denNachkommateil geschrieben. Nun kann die erste Stel-le des Nachkommateils in den Vorkommateil verscho-ben werden (Multiplikation mit 10; Zeile 12). Jetzt zerle-gen wir wieder Vor- und Nachkommateil mit \vn (Zei-le 13) und geben den Vorkommateil (vara; Zeile 14)aus. Nach dem Abschluss der Subroutine (Zeile 15) wer-den alle 5 Stellen (mehr werden nie ausgegeben) abge-arbeitet und ~mm angehängt (Zeile 16). In Zeile 17 wirdunser Macro beendet.

Angewendet auf unser Beispiel bei der Addition(siehe Kapitel 2.2.2 (Seite 5)) ergibt sich also für:

\MM{\tabwidth}

das Ergebnis:

104.05715 mm.

4.5 Rechnen in Tabellen –Ober! Zahlen!

Viele LATEX-Nutzer werden sich das schon häufiger ge-wünscht haben. Doch leider, leider, . . . – ein Trost vorneweg: Und sie dreht sich doch!

4.5.1 Aufgabenstellung

Wir sind ein Betrieb, der seine Rechnungen „unbedingt“mit LATEX erstellen möchte. In der ersten Spalte steht dieLiefermenge (beschränken wir uns hier auf den Zahlen-raum der natürlichen Zahlen), in der zweiten Spalte mö-ge die Artikelbeschreibung, in der dritten Spalte ein Son-derzuschlag (in Form eines Erschwernisfaktors) in dervierten Spalte der Einzelpreis und in der fünften Spalteder Gesamtpreis stehen. Zum Schluss werden noch alleGesamtpreise addiert und die Umsatzsteuer (Mehrwert-steuer) draufgerechnet.

Bisher nahm man sich den Taschenrechner zur Handund tippte und tippte und übertrug die Ergebnisse in dieTabelle. Etwas umständlich, zumal wir doch eine Re-chenmaschine (unseren Computer) direkt vor uns stehen

haben – soll die Kiste doch endlich einmal tun, wofür sieangeschafft wurde: Rechnen.

KOPKA [2] hat in seinem Werk schon einen Anhalts-punkt für die Lösung gebracht, in dem er ein Bestellfor-mular vorstellt. Wir brauchen aber ein wenig mehr.

4.5.2 Was muss beachtet werden?

Wenn unsere Rechnung beliebig lang werden soll (undwir keine Kassenrolle einsetzen), muss feststehen, anwelcher Position die Tabelle beginnt, wie hoch sie ak-tuell ist und wieviel Platz noch zur Verfügung steht bisdie Seite voll ist. Dann muss eine Zwischensumme gebil-det und ausgegeben werden. Anschließend muss sie alsÜbertrag auf der nächsten Seite automatisch eingetragenwerden (wer Spaß daran hat, möge sich hierzu eine ent-sprechende Routine ausdenken – hier wird dieser Punktjedenfalls nicht behandelt).

Ebenfalls nicht behandelt wird die automatische In-krementierung der Rechnungsnummer. Hier müssennämlich noch Sperrroutinen eingebaut werden, die da-für sorgen, dass ein neuerlicher LATEXlauf des gleichenDokuments die Nummer nicht nach oben jubelt (manu-elle Bestätigung, Kontrollzähler, . . . ). Gleichwohl wird

Page 23: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

4.5. RECHNEN IN TABELLEN 19

aber die Rechnungsnummer, neben der Kundennummerund dem aktuellen Tagesdatum, verwendet, um tempo-räre Dateinamen zu erzeugen. Hierüber lassen sie sicheindeutig identifizieren, und können später als überflüs-sige Dateien wieder gelöscht werden (hierzu habe ich bisjetzt noch keine LATEX-Funktion gefunden).

Wer schon einmal versucht hat den Tabellenspalten-trenner („&“) automatisch setzen zu lassen (zum Bei-spiel in einer Schleife), wird ganz schnell festgestellt ha-ben, dass dies nicht so funktioniert wie es hätte funk-tionieren sollen. Was aber klappt, ist eine komplette Ta-bellenzeile (einschließlich der notwendigen Trenner) auseiner externen Datei einzulesen. Also brauchen wir unse-re aktuelle Tabellenzeile nur auszulagern und dann wie-der einzulesen – umständlich(!), aber es funktioniert.Bei geschicktem Aufbau der ausgelagerten Daten kannder Tabellenkörper einfach wie ein Textbaustein mittels\input{datei} eingebunden werden.

Es kann zu unvorhersehbaren Ergebnissenführen, wenn eine Datei gleichzeitig für Schreib-

und Lesezugriffe verwendet wird.

Um sicher zu gehen, werden also erst alle Daten ge-schrieben und später gelesen. Nutzen wir doch einfachdiese Unzulänglichkeit und packen alle zu änderndenDaten nach vorne und alles was nicht geändert wird nachhinten. Dadurch sieht das Ganze wieder recht aufge-räumt aus.

Was wir brauchen ist also ein Befehl, der LATEXveranlasst, alle notwendigen Daten einer Zeile aufzu-nehmen, zu kalkulieren und auszulagern. Zum Schlussbrauchen wir noch einen Befehl, der die Mehrwertsteuerausrechnet, ausgibt und zur Gesamtsumme addiert. Unddamit das Ganze schön bequem wird, muss LATEX selbsterkennen, wann alle Daten zusammen sind.

((Der Rest dieses Abschnitts wird einspaltig darge-stellt, da die Absaätze teilweise zu kurz für 2spaltigenSatz sind und der Text dadurch zerrissen würde.))

Lösung: Eingabemaske – Muster für eine Setzerei

1 \usepackage{tabcalc}2 \begin{document}3 \def\kndnr{11} % <-- ANPASSEN4 \def\rechnr{24} % <-- ANPASSEN5 \mwst=16 % <-- ANPASSEN (ggf.)6

7 \immediate\openout\rechn=\rech.tab8 \immediate\openout\rechntmp=\rech.tmp9

10 % Werte anpassen !!!!11 \Zeile{000}{Seiten Satz und Umbruch} {1,00}{8,75}12 \Zeile{000}{Seiten Satz und Umbruch -- kleine Schrift}{1,15}{8,75}13 \Zeile{000}{Abbildungen scannen} {1,00}{1,00}14 \Zeile{000}{0,25 h Bearbeiten von Abbildungen} {1,00}{11,50}15

16 \immediate\closeout\rechntmp17 \immediate\closeout\rechn18

19 \KalkSum20

21 \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}r|p{100mm}|r|r|r}22 \multicolumn{1}{l|}{\tiny{Menge}}23 & \tiny{Auftragsbeschreibung}24 & \multicolumn{1}{l|}{\tiny{Faktor*}}25 & \multicolumn{1}{l|}{\tiny{Preis}}26 & \multicolumn{1}{l}{\tiny{Gesamt}}\\27 \hline\hline28 \input{\rech.tab}29 \multicolumn{4}{r|}{{\scriptsize * = Erschwernis}\hfill Summe}30 & \summe \EUR\\+31 \multicolumn{4}{r|}{+16 \% MwSt} & \vat \EUR\\32 \cline{5-5}+33 \multicolumn{4}{r|}{Total} & \total \EUR\\34 \cline{5-5}\multicolumn{1}{l}{}\\[-10dd] % <-- Abhängig von35 % gewählter Schriftgröße36 \cline{5-5}37 \end{tabular*}38

39 \end{document}

In Zeile 1 laden wir unsere Kalkulationsroutinen und was wir sonst noch an Neuerungen brauchen. Anschließend (Zeilen 3 bis 5)werden noch ein paar Literale übermittelt, wobei die ersten beiden im hier fehlenden Briefbogen und für temporäre Dateinamenherangezogen werden und \mwst den aktuellen Steuersatz für die Mehrwertsteuerberechnung zugewiesen bekommt (es werdennatürliche Zahlen unterstellt).

Page 24: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

20 KAPITEL 4. AUSGELAGERTE BERECHNUNGEN

In den Zeilen 7 und 8 werden dann Dateien zur Aufnahme der Tabellenzeilen und Zwischenergebnisse geöffnet. In die Datei mitder Endung .tab werden die einzelnen Tabellenzeilen und in die Datei mit der Endung .tmp die berechneten Ergebnisse jeder Zeile.In den Musterzeilen 11 bis 14 werden die Daten jeder Tabellenzeile als in geschweifte Klammern gesetzte Parameter an den neuenBefehl \Zeile übergeben. Die Reihenfolge, entspricht der in unserer Aufgabenstellung festgelegten Anordnung. Längere Text-passagen für die Artikelbeschreibung werden automatisch umgebrochen. Bei Bedarf können Zeilen entfernt oder weitere Zeilenhinzugefügt werden. Die Einträge dienen sowohl als Muster, können aber auch (zum Beispiel bei immer wieder gleichen Arbei-ten für einen Auftraggeber) als Vorgaben verstanden werden. Da die Preise und Faktoren sich für die einzelnen Arbeiten ändernkönnen, werden sie als Literale übergeben. Wer möchte, kann sich ja eine kleine Artikeldatenbank aufbauen, die direkt die Artikel-beschreibung, Preise und Erschwernisfaktoren enthält und übergibt auch diese Daten automatisch an die Tabelle.Nachdem alle Informationen exportiert wurden, können die Dateien wieder geschlossen werden (Zeilen 16 und 17).Mit \KalkSum (Zeile 19) werden alle notwendigen Berechnungen in und mit den externen Dateien durchgeführt.In den Zeilen 21 bis 37 wird die Tabelle aufgebaut und ausgegeben. Der relevante Teil der Tabelle wird in Zeile 28 einfach wie einTextbaustein geladen. In den Zeilen 29 bis 33 werden noch der Nettobetrag, die Mehrwertsteuer und der Bruttobetrag ausgegebenund fertig ist unsere automatisch berechnete Tabelle.

Beispiel: Unterstellen wir 48 Seiten Satz in Brotschrift, 12 Seiten mit kleinerer Schrift, 5 Abbildungscans und 0,5 h Bildbearbeitung,dann sehen unsere Zeilen 11 bis 14 etwa so aus:

Beispiel 26Ausgefüllte Eingabemaske

1 \Zeile{48}{Seiten Satz und Umbruch} {1,00}{ 8,75}2 \Zeile{12}{Seiten Satz und Umbruch -- kleine Schrift}{1,15}{ 8,75}3 \Zeile{ 5}{Abbildungen scannen} {1,00}{ 1,00}4 \Zeile{ 2}{0,25 h Bearbeiten von Abbildungen} {1,00}{11,50}

Nach dem LATEXlauf liefert unsere Maske folgende Tabelle:

Menge Auftragsbeschreibung Faktor* Preis Gesamt

48 Seiten Satz und Umbruch 1,00 8,75 420,00 ¤12 Seiten Satz und Umbruch – kleine Schrift 1,15 8,75 120,75 ¤5 Abbildungen scannen 1,00 1,00 5,00 ¤2 0,25 h Bearbeiten von Abbildungen 1,00 11,50 23,00 ¤

* = Erschwernis Summe 568,75 ¤+16 % MwSt 91,00 ¤

Total 659,75 ¤

Als nächstes sehen wir uns die Kalkulationsroutinen, die mittels \usepackage{tabcalc} zugeladen wurden, etwas näher an.Alle Routinen sind praxiserprobt. Sie werden bei sksatz, so wie sie da stehen, eingesetzt (wir gehören nämlich zu denen, dieunbedingt ihre Rechnung mit LATEX schreiben wollen). Der Einfachheit halber sind alle Kommentare mit aufgeführt, somit ist dasListing weitestgehend selbsterklärend.

4.5.3 Lösung: tabcalc.sty – Kalkulation, Datentransfer

Vorspann – zusätzliche Speicherplätze

1 \usepackage{marvosym}2

3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%4 %%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%5 %%%% %%%%6 %%%% Bereitstellen zusätzlicher Count-Register %%%%7 %%%% %%%%8 %%%% Bernd Kosubek, 2005-12-03 %%%%9 %%%% %%%%

10 %%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%11 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%12

13 \newcount\mwst % Mehrwertsteuersatz14 \newcount\tmpa % verschieden verwendbar15 \newcount\tmpb % verschieden verwendbar16 \newcount\v@ra % Vorkommastellen: Wert a17 \newcount\n@cha % Nachkommastellen: Wert a18 \newcount\v@rb % Vorkommastellen: Wert b19 \newcount\n@chb % Nachkommastellen: Wert b20

Dieser Teil (Zeilen 1 – 20) sollte keinerlei Fragen aufwerfen. Außer \mwst, das in der Eingabemaske mit dem notwendigen Da-tum versehen wird, dienen alle anderen Register lediglich für interne Berechnungen. Anstelle von marvosym kann jedes andereeurozeichenliefernde Paket verwendet werden.

Page 25: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

4.5. RECHNEN IN TABELLEN 21

muliixii – 2�2 = 2 Nachkommastellen

21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%22 %%%%%%% %%%%%%%23 %%%%% Multiplikation zweier Werte mit jeweils 2 Nach- %%%%%24 %% komastellen und anschließender kaufmännischer %%25 % Rundung auf 2 Nachkommastellen %26 % %27 % Übergabe: VKa: Vorkommateil (VK) von Wert a %28 % NKa: Nachkommateil(NK) von Wert a %29 % VKb von Wert b %30 % NKb von Wert b %31 % Rückgabe: \v@ra := VK des Ergebnisses %32 % \n@cha := NK des Ergebnisses %33 % %34 % Verwendete Ganzzahlspeicher: %35 % \v@ra %36 % \n@cha %37 % \v@rb %38 % \n@chb %39 % \@tempcnta %40 % \@tempcntb %41 %% %%42 %%%%% Bernd Kosubek, 2005-12-03 %%%%%43 %%%%%%% %%%%%%%44 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%45

46 \def\muliixii#1#2#3#4{%47 \v@ra=#148 \n@cha=#249 \v@rb=#350 \n@chb=#451 % Plausibilitätsprüfung52 \ifnum\n@cha>9953 \errhelp{%54 ^^Jmul2x2:^^J55 Die Nachkommastellen dürfen max. 2stellig sein !!!^^J56 Der eingegebene Wert ist zu groß !!!^^J57 Bitte kontrollieren !!!^^J58 }59 \errmessage{Inhalt von \string\n@cha\space ist zu groß !!!}60 \fi61 \ifnum\n@chb>9962 \errhelp{%63 ^^J64 mul2x2:^^J65 Die Nachkommastellen dürfen max. 2stellig sein !!!^^J66 Der eingegebene Wert ist zu groß !!!^^J67 Bitte kontrollieren !!!^^J68 }69 \errmessage{Inhalt von \string\n@chb\space ist zu groß !!!}70 \fi71 % Wert a Zusammensetzen72 \@tempcnta=\v@ra73 \multiply\@tempcnta by 10074 \advance\@tempcnta by \n@cha % = 100a75 % Wert b Zusammensetzen76 \@tempcntb=\v@rb77 \multiply\@tempcntb by 10078 \advance\@tempcntb by \n@chb % = 100b79 % a * b80 \multiply\@tempcnta by \@tempcntb % a*b (tempcntb wird frei)81 \@tempcntb=\@tempcnta % Produkt merken82 \divide\@tempcnta by \@M % letzte 4 Stellen abscheiden83 \v@ra=\@tempcnta % VK -> v@ra ***84 \multiply\@tempcnta by \@M % 4 Stellen wieder dran, als Nullen85 \advance\@tempcntb by -\@tempcnta % tempcntb := b-a -> 4stelliger NK86 % (tempcnta wird frei) ***87 % b runden88 \@tempcnta=\@tempcntb % merken89 \divide\@tempcnta by 100 % letzte 2 Stellen abschneiden90 \n@cha=\@tempcnta % erste 2 Stellen merken91 \multiply\@tempcnta by 100 % 2 Stellen wieder dran, als Nullen92 \advance\@tempcntb by -\@tempcnta % letzte 2 Stellen in tempcntb93 \ifnum\@tempcntb>49 % >= 50 ?94 \advance\n@cha by \@ne % NK inkrementieren (aufrunden)95 \fi96 \ifnum\n@cha>99 % >=100 ?

Page 26: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

22 KAPITEL 4. AUSGELAGERTE BERECHNUNGEN

97 \advance\v@ra by \@ne % Übertrag auf Einer98 \advance\n@cha by -100 % NK korrigieren99 \fi

100 }101

In den Zeilen 52 und 70 wird geprüft ob die übergebenen Daten auch wirklich nur zwei Nachkommastellen aufweisen. Wenn alleso. k. ist, werden in den Zeilen 71 bis 78 der Vorkomma und der Nachkommateil der jeweiligen Faktoren wieder zusammengesetzt.In den Zeilen 80 bis 85 wird die Multiplikation durchgeführt, wobei, laut Adam Riese, vier Nachkommastellen gebildet werden.Diese werden in den Zeilen 88 bis 99 auf zwei Stellen gerundet. Wobei in Zeile 93 geprüft wird, ob die letzten beiden Stellen desvierstelligen Nachkommateils größer oder gleich 50 sind (Test auf größer 49). Wenn dem so ist, dann werden die ersten beidenNachkommastellen um 1 erhöht (Zeile 94). Anschließend muss noch überprüft werden, ob das neue Ergebnis der ersten beidenNachkommastellen größer oder gleich 100 geworden ist (Test auf größer als 99; Zeile 96). Falls ja, muss der Vorkommateil erhöhtund der Nachkommateil entsprechend vermindert werden (Zeilen 97 und 98). Abschluss der Routine in Zeile 100.

vknk – Zerlegung in Vor- und Nachkommateil102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%103 %%%%%%% %%%%%%%104 %%%%% Zerlegen eines Wertes in Vorkommateil und %%%%%105 %% Nachkommateil (2stellig) %%106 % %107 % %108 % Übergabe: hundertfacher Wert %109 % %110 % %111 % %112 % Rückgabe: \v@ra := Vorkommateil (VK) %113 % \n@cha := Nachkommateil(NK) %114 %% %%115 %%%%% Bernd Kosubek, 2005-12-03 %%%%%116 %%%%%%% %%%%%%%117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%118

119 %120 \def\vknk#1{%121 \@tempcnta=#1122 \n@cha=\@tempcnta % 100fachen Wert merken123 \divide\@tempcnta by 100 % letzte 2 Stellen weg124 \v@ra=\@tempcnta % als VK speichern125 \multiply\@tempcnta by 100 % wieder 2 Nullen anfügen126 \advance\n@cha by -\@tempcnta % NK speichern127 }128 % Ende129

Diese Zerlegung in Vor- und Nachkommateil sollte sich nach dem bisher Gelernten von selbst erklären, so dass ich mir hierEinzelheiten spare.

deldecpoint – Ohne Dezimalzeichen130 % Anwendung -- z.B.:131 % \temp=\expandafter\deldecpoint #1!!132 %133 % wobei \temp dann den 100fachen Wert von #1 enthält134 % Aus Kopka, Band 3, S. 355 ff.135

136 \def\deldecpoint#1,#2!!{#1#2}137

Dieser Einzeiler (Zeile 136) hat’s in sich: Der Vorkommateil „#1“ und der Nachkommateil „#2“, separiert durch das deutscheDezimaltrennzeichen „,“ (gegebenenfalls durch die englische Schreibweise austauschen) wird ohne Dezimaltrennzeichen gemerkt(zum Beispiel werden aus Euro auf diese einfache Weise Cent). Der Clou sind die beiden Ausrufezeichen („!!“). Sie verhindern,dass die nachfolgende öffnende geschweifte Klammer als Endemarkierung von „#2“ angesehen wird und dadurch „verschluckt“würde (vergleiche KOPKA [2], Kapitel 5.6.2, Seite 258 ff. und Kapitel 6.5.3, Seite 355 ff.). Prinzipiell kann an Stelle der beidenAusrufezeichen jedes beliebige Zeichen eingesetzt werden. Ich habe aber einfach Herrn Kopkas Idee übernommen.

vat – Berechnung der MwSt138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%139 %%%%%%% %%%%%%%140 %%%%% Berechnung der Mehrwertsteuer: %%%%%141 %% %%142 % %143 % Übergabe: Vorkommateil (VK) Netto %

Page 27: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

4.5. RECHNEN IN TABELLEN 23

144 % Nachkommateil(NK) Netto %145 % \mwst (von "außen") %146 % Rückgabe: \v@ra := VK MwSt %147 % \n@cha := NK MwSt %148 % \v@rb := VK Brutto %149 % \n@chb := NK Brutto %150 % %151 % Verwendete Ganzzahlspeicher: %152 % \tmpa := VK Netto %153 % \tmpb := NK Netto %154 % \@tempcnta %155 % %156 % Verwendete Ganzzahlspeicher (in muliixii): %157 % \v@ra %158 % \n@cha %159 % \v@rb %160 % \n@chb %161 % \@tempcnta %162 % \@tempcntb %163 %% %%164 %%%%% Bernd Kosubek, 2005-12-03 %%%%%165 %%%%%%% %%%%%%%166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%167

168 \def\vat#1#2{%169 \tmpa=#1 % VK Netto170 \tmpb=#2 % NK Netto171 \typeout{Netto: \the\tmpa,\the\tmpb; MwSt: \the\mwst}172 \muliixii{1}{\mwst}{\tmpa}{\tmpb}173 \typeout{Brutto: \the\v@ra,\the\n@cha}174 \v@rb=\v@ra % VK Brutto175 \n@chb=\n@cha % NK Brutto176 \@tempcnta=\tmpa177 \multiply\@tempcnta by 100178 \advance\@tempcnta by \tmpb % 100VK+NK (Netto)179 \multiply\v@ra by 100180 \advance\v@ra by \n@cha % 100VK+NK (Brutto)181 \advance\v@ra by -\@tempcnta % Brutto-Netto = MwSt182 \vknk{\v@ra} % MwSt zerlegen in VK und NK183 }184

Hier ist nur die Zeile 172 erwähnenswert. Eigentlich handelt es sich nur um die Multiplikation zweier nachkommabehafteterZahlen und um eine Subtraktion. Das Interessante ist das Literal „1“. Hierüber kann der Mehrwertsteuersatz ohne Umwege in dieBerechnung einfließen. Hier greifen im Prinzip wieder unsere Grundlagen der Prozentrechnung (Steuersatz: 16 % ! Netto mal1,16 = Brutto – oder anders formuliert: Der Bruttobetrag ist 116 % Nettobetrag). Wir schreiben also den Vorkommateil in die ersteund den Nachkommateil in die zweite Klammer (siehe Beschreibung der Routine muliixii).Nach diesen Vorarbeiten kommen wir nun zur eigentlichen Tabellenbildung.

Dateitransfer – Vorbereitung185 \newread\rechn \newread\rechntmp \newread\rechnsum186 \newwrite\rechn \newwrite\rechntmp \newwrite\rechnsum187

Damit LATEX Informationen in eine Datei schreiben oder aus ihr lesen kann, muss erst einmal der Zugriff geregelt werden. Jeder zuöffnenden Datei muss eine sogenannte Kanalnummer zugewiesen werden. Die Verwaltung der Nummern kann man wieder getrostLATEX überlassen. Der Anwender muss lediglich festlegen, ob er schreibend oder lesend auf die Datei zugreifen will und welchenNamen der Kanal haben soll. Beide Zugriffsarten dürfen den gleichen Namen haben, werden aber strikt durch die Teilbegriffe„read“ für lesenden und „write“ für schreibenden Zugriff unterschieden.

\Zeile – DER neue Befehl188 \newcommand{\Zeile}[4]{%189 \tmpa=#1 % Menge (Ganze)190 \tmpb=\expandafter\deldecpoint #3!! % Erschwernis (in Cent)191 \multiply\tmpa by \tmpb192 \vknk{\tmpa}193 \v@rb=\v@ra194 \n@chb=\n@cha195 \tmpb=\expandafter\deldecpoint #4!! % Einzelpreis (in Cent)196 \vknk{\tmpb}197 \muliixii{\the\v@ra}{\the\n@cha}{\the\v@rb}{\the\n@chb}198 \immediate\write\rechn{#1 & #2 & #3 & #4 &199 \the\v@ra,\two@digits\n@cha\ \string\EUR\string\\\string\hline}200 \immediate\write\rechntmp{\the\v@ra}

Page 28: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

24 KAPITEL 4. AUSGELAGERTE BERECHNUNGEN

201 \immediate\write\rechntmp{\two@digits\n@cha}202 }203

Der neue Befehl

\Zeile{menge}{beschr}{fakt}{epreis}

dient dazu unsere Tabellendaten aufzunehmen und in verschiedene Dateien zu schreiben. Die Reihenfolge der Datenentspricht der unserer anfänglichen Überlegung. Um die Länge des Eintrags für die Artikelbeschreibung brauchen wiruns keine Gedanken machen (bitte keine Romane), da unsere Tabelle an dieser Stelle eine p-Spalte aufweist. Nachdemdie notwendigen Berechnungen (Zeilen 191 bis 197) durchgeführt wurden, werden diese an die Datei mit der Endung.tab im Kanal \rechn in der Schreibweise für eine Tabellenzeile geschrieben.

Alle Schreibvorgänge müssen unmittelbar erfolgen („\immediate“) (Zeilen 198 und 199), damit dieaktuellen Werte nicht durch folgende Werte überschrieben werden!

Der Befehl \two@digits\reg sorgt dafür, dass die Nachkommastellen gegebenenfalls mit einer führenden „0“(Null) ausgegeben werden. Andernfalls würden aus beispielsweise 2 Cent plötzlich 20 Cent („ ,2“ statt „ ,02“). Diebeiden \string-Befehle sind wichtig, da alle Informationen, eines \write-Befehls vollständig expandiert werden,was hier natürlich nicht gewünscht ist.Nachdem also die Zeile in die Zieldatei geschrieben wurde, muss das Ergebnis der Zeile für die Gesamtsumme zwi-schengespeichert werden. Der Einfachheit halber habe ich die Daten ebenfalls in eine Datei (Dateiendung: .tmp)ausgelagert. In der Datei (im Kanal \rechntmp) werden jeweils zwei Datenzeilen für ein Ergebnis angelegt, nämlicherst der Vorkommateil und anschließend der Nachkommateil (Zeilen 200 und 201). Auch dieser Schreibvorgang mussjeweils, aus den genannten Gründen, direkt erfolgen.

\KalkSum – Ein paar Zwischen- und Endergebnisse204 \newcommand{\KalkSum}{%205 %%%206 %%% Berechnung der Summe der letzten Spalte (ist ok.)207 %%%208 \v@ra=0%209 \n@cha=0%210 \immediate\openin\rechntmp\rech.tmp211 \loop%212 \immediate\read\rechntmp to \vor213 \ifeof\rechntmp214 \else215 \immediate\read\rechntmp to \nach216 \advance\v@ra by 0\vor%217 \advance\n@cha by 0\nach%218 \repeat%219 \immediate\closein\rechntmp220 \ifnum\n@cha>99%221 \tmpa=\n@cha%222 \divide\tmpa by 100%223 \advance\v@ra by \tmpa%224 \multiply\tmpa by 100%225 \advance\n@cha by -\tmpa%226 \fi%227 \immediate\openout\rechnsum\rech.sum228 \immediate\write\rechnsum{\the\v@ra,\two@digits\n@cha}229 % Summe in Datei schreiben

Nachdem alle Endergebnisse der einzelnen Zeilen in eine Datei geschrieben wurden, ist es nun an der Zeit sie wie-der zurückzuholen und zu addieren. Hierzu werden die Daten wieder „direkt“ benötigt (Zeile 210), in einer Schleife(Zeilen 211 bis 218) nacheinander gelesen (Zeilen 212 und 215) und die Vorkommateile (Zeile 216) sowie die Nach-kommateile (Zeile 217) separat addiert.Nach dem wir die Datei wieder geschlossen haben (Zeile 219), wird überprüft, ob die Summe der Nachkommateilegrößer oder gleich 100 (Test auf größer 99; Zeile 220) ist, dann muss nämlich ein Ausgleich mit dem Vorkommateilstattfinden (Zeilen 221 bis 225).Anschließend wird das Ergebnis (Nettobetrag) in eine andere Datei (Dateiendung: .sum) (direkt) ausgelagert.

Page 29: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

4.6. LIST-UMGEBUNG 25

230 %%%231 %%% Berechnung der Umsatzsteuer (ist ok.)232 %%%233 \typeout{^^JRoutine vat^^J}234 \vat{\v@ra}{\two@digits\n@cha}235 % MwSt in Datei schreiben:236 \immediate\write\rechnsum{\the\v@ra,\two@digits\n@cha}237 % Gesamt in Datei schreiben:238 \immediate\write\rechnsum{\the\v@rb,\two@digits\n@chb}239 \immediate\closeout\rechnsum240 %241 \immediate\openin\rechnsum\rech.sum242 % Summe aus Datei lesen:243 \immediate\read\rechnsum to \summe244 % MwSt aus Datei lesen:245 \immediate\read\rechnsum to \vat246 % Gesamt aus Datei lesen:247 \immediate\read\rechnsum to \total248 % Kontrollausgabe249 \typeout{Summe: \summe; VAT: \vat; Total: \total}250 \immediate\closein\rechnsum251 }252

In die selbe Datei (Dateiendung: .sum) werden dann noch die Mehrwertsteuer und der Bruttobetrag geschrieben. Hier-zu wird einfach die entsprechende Routine aufgerufen und das Ergebnis zwischengespeichert. Zur Kontrolle werdenalle Daten noch auf dem Bildschirm ausgegeben und die Datei wieder geschlossen.

Dateiname – alles das Selbe/Gleiche248 \def\rech{%249 \kndnr_\rechnr_\number\year\two@digits\month\two@digits\day250 }

Zum Schluss sorgen wir noch dafür, dass die temporären Dateien (Dateiendungen: .tab, .tmp und .sum) alle dengleichen Dateinamen erhalten. Dieser setzt sich zusammen aus der Kundennummer (\kndnr), der Rechnungsnum-mer (\rechnr) und dem aktuellen Tagesdatum in der Form JJJJMMTT. Die einzelnen Daten werden mit einemUnterstrich („_“) separiert.

4.6 Erst eins, dann zwei, dann drei,dann vier – list-Umgebung

Wie zu Anfang schon erwähnt, können auch list-Umgebungen von LATEX zum Teil durchkalkuliert wer-den. Ich beschränke mich jetzt hier auf die horizontalenMaße, da diese den meisten Frust verursachen. Unter-stellen wir einmal, wir brauchen eine Liste, deren Mar-ke römische Ziffern im Bereich von 1 bis 24 sein sol-len. Die Marke selbst soll gegenüber dem Fließtext nichteingerückt sein und der Abstand von der Marke zum Lis-tentext ein „em“ betragen. Der Listentext wiederum sollgeblockt (das heißt links- und rechtsbündig) dargestelltwerden. Außerdem sollen die Zahlen linksbündig statt,wie von den Listumgebungen vorgesehen, rechtsbündigausgegeben werden.

Für das weitere Vorgehen müssen wir nur feststellen,welche der römischen Zahlen den meisten Platz bean-sprucht. Hierzu ließe sich eine Schleife aufbauen, die al-le Zahlen durchgeht und dies für uns ermittelt. Das las-sen wir an dieser Stelle aber sein, ich brauche ja nochMaterial für die Fortsetzung. Unterstellt, dass als Schriftdie Times (Proportionalschrift) gewählt wurde, ist dielängste Zahl die 24.

Wie sieht also unsere Listendeklaration aus?

Beispiel 27Nummernliste

1 \begin{list}2 {\roman{enumi}\hfill}3 {%4 \usecounter{enumi}5 \settowidth{\labelwidth}{xxiv}6 \setlength{\labelsep}{1em}7 \setlength{\leftmargin}{\labelwidth}8 \advance\leftmargin by \labelsep9 }

10 \item Advent,11 \item Advent,12 \item ein Lichtlein brennt13 \item erst eins,14 \item dann zwei,15 \item dann drei,16 \item dann vier,17 \item und wenn das fünfte \ldots18 \item \ldots Weihnachten verpennt.19 \item Puuuust!20 \end{list}

In Zeile 8 wird gerechnet – und in Zeile 19 wird’s duster!

So, das soll’s erst einmal gewesen sein. Ich hoffe,die paar Zeilen haben die/den Eine(n) oder Ande-re(n) zu eigenen Versuchen veranlasst. Macht ruhigFehler – LATEX nimmt’s nicht krumm und man lernteine Menge dabei.

Vor allem – Lass LATEX doch für uns rechnen!

Page 30: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

26 KAPITEL 4. AUSGELAGERTE BERECHNUNGEN

Page 31: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

LITERATURVERZEICHNIS 27

Literaturverzeichnis

[1] Klöckl, I.: LATEX 2ε – Tips & Tricks. (2000);dpunkt.verlag.

[2] Kopka, H.: LATEX – Erweiterungen. Band 3, (1997);Addison-Wesley-Longman.

[3] Schwarz, S. und Potucek, R.: Das TEXikon – Refe-renzhandbuch für TEX und LATEX. (1997); Addison-Wesley.

Dateien

[4] Cremer, F.: Das kleine TEXBuch. 1993-07-05.

[5] Braams, J., Carlisle, D., Jeffrey, A., Lamport, L.,Mittelbach, F., Rowley, C., Schöpf, R.: ltlength.dtx.1995-08-11.

[6] Braams, J., Carlisle, D., Jeffrey, A., Lamport, L.,Mittelbach, F., Rowley, C., Schöpf, R.: ltcounts.dtx.1998-05-16.

[7] Eijkhout, V.: TEX by Topic, A TEXnician’s Refe-rence – Electronic Version 1.1. August 2004.

[8] Knuth, D. E., Bibby, D. R.: The TEXbook. 1984.

[9] Knuth, D. E.: ltplain.dtx – The file plain.tex, modi-fied for LATEX (Modified by Lamport, L., Mittelbach,F., Schöpf, R., Carlisle, D.). 2004-02-24.

Page 32: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

28 LITERATURVERZEICHNIS

Page 33: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

Index

\@cclvi, 15\@cclv, 15\@Miii, 15\@Mii, 15\@Miv, 15\@Mi, 15\@MM, 15\@M, 15\@m, 15\@ne, 15\@tempcnta, 15\@tempcntb, 15\@tempdima, 15\@tempdimb, 15\@tempfimc, 15\@tempskipa, 15\@tempskipb, 15\@xxxii, 15\advance, 3, 9, 11, 12\arraycolsep, 3\arrayrulewidth, 3\columnwidth, 5\def, 3, 4\divide, 3, 6, 9, 11, 12\doublerulesep, 3\global, 9, 10\includegraphics, 16\input, 19\m@ne, 15\multiply, 3, 5, 9, 11, 12\newcount, 3, 6\newdimen, 3–5, 10\newlength, 3, 5, 11\newskip, 11\p@, 15\setlength, 3, 11\settodepth, 11\settoheight, 11\settowidth, 3, 5, 11\sixt@@n, 15\string, 24\tabcolsep, 3\textwidth, 3, 5\the, 11\thr@@, 15\tw@, 15\two@digits, 24\typeout, 9, 10

\ˆˆJ, 10\usepackage, 15\write, 24\z@skip, 15\z@, 15\immediate, 24@, 9&, 19

cm, siehe Maßeinheitenin, siehe Maßeinheitenmm, siehe Maßeinheitenpt, siehe Maßeinheitensp, siehe Maßeinheiten

Addition, 4–5Approximation, 7at, siehe @

Bildserien, 17by, 3

counter, 9

Datei laden, siehe \inputDateiname, 25Dateinamen

temporäre, 19Dateitransfer, 23

Kanal, 24Kanalnummer, 23read, 23write, 23

„Definition“, 4Deklaration

count-Register, 9dimen-Register, 10skip-Register, 11

Dezimalzeichen, 22Division, 6Dreisatz, 4

Einheiten, siehe Maßeinheitenelastische Maße, siehe glueEurozeichen, 20

Federn, siehe glueFließkommaarithmetik, 7

glue, 11Grundrechenarten, 3–6Gruppen, 10

inch, siehe MaßeinheitenInitialisierung

dimen-Register, 11

Klammeraffe, siehe @Konstante, siehe „Definition“

Literal, 4, 19

marvosym, 20Maßeinheiten, 4, 10

cm, 4in, 4mm, 4pt, 4

29

Page 34: Lass doch LaTeX rechnen! -- Rechnerei für den Alltag (ohne ...anamorphose.de/rechnen.pdf · Zum Inhalt Für viele LATEX-Nutzer, vor allem für Einsteiger, ist es schwer die notwendigen

30 INDEX

sp, 4Multiplikation, 5–6MwSt., 22

Nachkommastellen, 21

Prozentrechnen, 3

Raisebox, 16Register, 9

-name, 9-typen, 9-typen kombinieren, 12box, 9count, 6, 9\newcount, 9\number, 9Deklaration, 9Inhalt ausgeben, 10Initialisierung, 9Kontrollausgabe, 10Restaurierung, 10Wertzuweisung, 9

dimen, 4, 9–11Ausgabe in Datei, 11Kontrollausgabe, 11

muskip, 9skip, 9, 11token, 9

Rundung, kaufmännische, 21

Scaled points, siehe MaßeinheitenSchleife, 19, 25Speicher, temporär, 15Subtraktion, 5

Tabellenkörper, 19Tabellenspaltenbreite, 5Tabellenspaltentrenner

see&, 1Textbaustein, 4, 19Textspaltenbreite, siehe \textwidthToleranzgrenzen, 12typeout, siehe \typeout

Umbegunglist, 25

UmgebungenTabular, 4

Zahlen, vordefiniert, 15Zahlenzerlegung, 22Zeichenkette, 4Zwischenergebnis, 20Zwischenergebnisse kontrollieren,

siehe \typeout


Recommended