TeX mit Anschlu� Adressensuche und -einbindung in TeX Ein nicht unbekannte Situation: Man beginnt einen Brief aufzusetzen, doch von der Anschrift haften nur Bruchst�cke im Ged�chtnis. TeX-Anwender k�nnen jetzt beruhigt aufatmen, schlie�lich ist ihr Favorit erweiterbar. Was also lag n�her, als dem Satzsystem ein 'Datenbankfeature' zu liefern, genauer, LaTeX um eine Funktion zu erweitern, die es m�glich macht, allein durch die Angabe der Fragmente, die von der Adresse noch bekannt sind, den Rest selbst�ndig zusammenzusuchen. Die erste �berlegung galt den zu verwaltenden Daten, den Adressen und dem Format, in dem diese vorliegen sollen. Ich habe ein einfaches Format gew�hlt, somit l��t sich eine Exportsdatei aus Adimens bzw. dBase leicht einbinden. Die Adressen, also Name, Strasse, Ort und Telefon m�ssen zeilenweise in einer ASCII-Datei vorliegen, wobei jeder Adressenblock vom folgenden durch eine Leerzeile getrennt wird: Otto Normal Beethovenstr. 13 6100 Darmstadt 01234/56789 Karl Mustermann ... Jede Adresse mu� exakt so in der Datei, wie sie sp�ter im Adressenkopf des Briefes erscheinen soll. Daher d�rfen in der Datendatei keine Zeichen vorkommen, die nicht zu einer Adresse geh�ren. Genauso mu� die Zeilenanzahl jeder Adresse konstant gehalten sein. Nicht ausgef�llte Daten sind durch Leerzeilen zu ersetzen, wie dies bei den Exportdateien �blich ist. Was Umlaute in den Adressen betrifft, so h�ngt dies ganz davon ab, wie solche in der vorliegenden LaTeX-Version behandelt werden. Allgemein gilt jedoch, da� man alle weiteren Sonderzeichen in bekannter LaTeX-Schreibweise einzugeben hat. Einbinden Das LaTeX-Dokument mu� lediglich um den Optionsstyle 'finder' und zwei Befehle erweitert werden, um die M�glichkeiten des finder.sty nutzen zu k�nnen: \documentstyle[finder]{letter} \begin{document} \findname[]{} \addressfile{} \begin{letter}{\name \\ \street \\ \city } ... \end{letter} \end{document} Man erkennt, da� durch die Angabe eines (in geschweiften Klammern) bzw. zweier Suchworte im Makro \findname und dem anschlie�enden Aufruf des \addressfile-Makros mit dem zugeh�rigen Adre�dateinamen danach die Makros \name, \street und \city (und \telephone) zur Verf�gung stehen. Bei erfolgreicher Suche enthalten diese die vollst�ndige Adresse. In Serie Wenn das Makropaket eine Adresse finden kann, sollte es sich auch auf die Bearbeitung von Serienbriefen ausdehnen lassen. Dazu mu� man lediglich einen Standardbrief, der die Variablen \name, \street und \city enth�lt, an das Makro \serienbrief{...} �bergeben. Damit entf��lt bei dieser Anwendung entf�llt die Angabe von Suchw�rtern. Die Datendatei wird vollst�ndig abgearbeitet. \documentstyle[finder]{letter} \begin{document} \serienbrief{ % \begin{letter}{\name \\ \street \\ \city } ... \end{letter} } \addressfile{} \end{document} Aufspalten Nachdem der Benutzer in seinem Brief ein bzw. zwei Worte angegeben hat, kann die Suche in einer Adressendatei beginnen. Dabei wird die Datei zeilenweise von dem Makrokomplex eingelesen und Wort f�r Wort nach zu findenen Daten durchsucht. Im Aufspalten der Zeile in einzelne, nur durch Leerzeichen getrennte W�rter liegt das gr��te Problem, dessen L�sung kennzeichnet zugleich das Herzst�ck des finder.sty. Verlief die Suche nach den vorgegebenen W�rtern erfolgreich, wird die gefundene Adresse in Variablen verpackt und kann von dem Anwender in dessen LaTeX-Dokument weiterverarbeitet werden. Der Anfangsbereich des Styles beinhaltet neben einer Meldung alle vor dem ersten Durchlauf des Makropaketes notwendigen Grunddefinitionen. Viele der Einstellungen m�ssen in den Makros wiederholt werden, da es auch m�glich sein soll, das Makropaket mehrmals in einem LaTeX-Dokument aufzurufen. Einmal odert immer? Der finder.sty setzt sich aus drei Makros zusammen, deren Beschreibung gem�� des Programmdurchlaufs erfolgt. Soll nach einer Adresse gesucht werden, so m�ssen an \findname[...]{...} ein oder (optional) zwei Suchw�rter �bergeben werden. \findname ist so programmiert, da� es, falls nur ein Suchwort (in geschweiften Klammern) angegeben wurde, dieses zweimal an \findn@me weiterliefert. Dort werden die Suchw�rter in den Variablen \firstname und \secondname abgelegt. Beiden Makros lassen sich damit auch nach dem \findname-Aufruf im LaTeX-Dokument verwenden. Eine Kontrolle stellt sicher, da� keine Leerzeichen �bergeben wurden. Danach sind alle Flags so gestellt, da� die Suche zum ersten Mal oder ggf. wieder neu beginnen kann, falls dies die zweite Adresse ist, nach der gesucht werden soll. Will man einen Serienbrief starten, so speichert das \serienbrief-Makro den �bergebenen Text des Serienbriefes ab und setzt die zugeh�rigen Flags dementsprechend. Suche... Der erste Schritt besthet im Aufruf von \addressfile und der Angabe der zu durchsuchenden Datei. Aber auch dieses Makro ist nicht das eigentliche Ausf�hrende, sondern es trifft nur eine Vorentscheidung. Sollen beispielsweise mehrere Dateien durch mehrmaliges Aufrufen des \addressfile-Befehls nach einer Adresse durchsucht werden und ist die Suche schon in einer der ersten Dateien erfolgreich, so hat sich das Weitersuchen in allen nachfolgenden Dateien er�brigt. Das Makro bricht in diesem Fall mit einer Bildschirmmeldung ab. Die Suche startet mit dem \analysefile-Makro, das vom \addressfile-Makro aufgerufen wird. Hier wird zuerst die Datendatei ge�ffnet, danach gekl�rt, ob eine Suche �berhaupt stattfindet oder ob ein Serienbrief an alle Adressen geschrieben werden soll. Nach der Startmeldung beginnt eine Schleife. Jeder Durchlauf entspricht dem Einlesen eines Adressenblocks. Somit existieren im vorliegenden Falle vier nahezu gleiche Bl�cke f�r \name, \street, \city und \telephone. Als f�nftes schlie�t sich eine Zeile an, die die Leerzeile zwischen den Adressenbl�cken einliest. Jeder der vier Bl�cke hat drei Aufgaben. Die erste besteht im Einlesen der n�chsten Datenzeile und der �bergabe an das entsprechende Makro. Darauf findet, falls keine Leerzeile eingelesen wurde, ein Weitergabe der Zeile zum Durchsuchen an das \lookat-Makro statt. Sollte jedoch eine Leerzeile eingelesen worden sein, so wird das zugeh�rige Makro gel�scht und mit einer entsprechenden Bildschirmmeldung versehen. Das L�schen ist unbedingt n�tig, da ansonsten TeX das zugeh�rige Makro nicht mit einer Leerzeile, sondern mit einem \par f�llt. Dies k�nnte beim Verwenden des Makros im LateX-Dokument unangenehme Folgen haben. Bevor ich auf die Analyse der gelesenen Zeile durch das \lookat-Makro eingehe, m�chte ich die Beschreibung des Endes des \analysefile-Makros vorziehen. Die Situation am Ende der vier Bl�cke unterscheidet sich durch drei F�lle: Das schlechteste Ergebnis der Suche w�re ein Mi�erfolg. In diesem Fall werden zusammen mit einer entsprechenden Bildschirmmeldung die vier Adre�variablen gel�scht. Einer erneuten Suche in einer anderen Datei steht dennoch nichts im Wege. Es mu� nur ein \addressfile-Aufruf mit einer anderen Adressendatei folgen. Bei einer erfolgreichen Suche wird \stillmore auf 'false' gesetzt und damit die Suche vorzeitig abgebrochen. Das Ergebnis der Suche kommt auf dem Bildschirm zur Angezeige. Im dritten Fall, der Serienbriefanwendung, wird die gerade gelesenen Adresse auf dem Bildschirm ausgegeben und der Text des Serienbriefes an TeX weitergereicht. Die darin enthaltenen Adressenvariablen haben dabei den Inhalt der aktuellen Adresse. Am Ende des \analysefile-Makros wird dann entweder eine neue Schleife gestartet oder die Adressendatei geschlossen und das Makro beendet. ... und finden Die eigentliche Suche findet im \lookat-Makro statt. Von gr��ter Wichtigkeit ist hierbei, da� die eingelesenen Zeile expandiert an dieses Makro �bergeben wird. Da� hei�t, die Zeile darf nicht in einem \line-Makro verpackt, sondern mu�, wie in der Datei, explizit hinter dem \lookat-Aufruf stehen. Nun kommt es darauf an, die Zeile Wort f�r Wort zu zerhacken und dabei in einer bestimmten Variable immer nur ein Wort der Zeile zur Verf�gung zu haben. Dieses l��t sich dann sehr einfach mit den Suchw�rtern vergleichen. Eine Suche kann nur erfolgreich sein bei exakter �bereinstimmung zwischen dem in der Datedatei extrahierten und dem zu suchendem wort: Gro�- und Kleinschreibung haben also durchaus Bedeutung. Die Aufgabe des Zerhackens einer Zeile und des Vergleichens mit den Suchw�rtern �bernimmt das rekursiv definierte \lookat-Makro. \lookat ist mit einem Leerzeichen zwischen den beiden �bergabeparametern und den drei Klammeraffen (@) danach so definiert, da� es ein bestimmtes Format von den folgenden Zeichen erwartet. #1 bekommt alle dem \lookat-Makro nachfolgenden Buchstaben bis zum ersten Leerzeichen zugewiesen; #2 erh�lt den Rest der Dateizeile bis zu den drei Klammeraffen, die somit als Zeilenendekennung dienen. In \lookat liegt in der \found-Variable immer ein Wort der Zeile vor. Dieses und auch alle anderen W�rter der Zeile werden St�ck f�r St�ck mit den Suchw�rtern verglichen. Bei erfolgreicher Suche erh�lt jedes gefundene Suchwort einzeln ein Flag zugeordnet. Stehen beide Suchw�rter in einem Adressenblock auf 'true' schaltet auch \foundname auf 'true'. Beim wortweisen Durchsuchen der Zeile enth�lt demnach \rest immer den Restbestandteil der Zeile. Dieser wird analog zur gelesenen Zeile expandiert und wieder an \lookat unter Beachtung des Formats �bergeben. \found erh�lt nun das erste Wort vom \rest-Inhalt �bergeben und der \rest-Inhalt und der Inhalt von \rest wird um dieses Wort verringert. Man erkennt, da� \lookat-Makros ruft sich selbst aufruft. Noch etwas zu der Sonderstellung der Leerzeichen in den Adressenbl�cken: Da immer nur wortweise Vergleich mit den Suchw�rtern erfolgt, erkl�rt sich von selbst, da� diese niemals ein Leerzeichen enthalten d�rfen. Ansonsten w�re die Suche 100%ig erfolglos, da \found immer nur ein Wort enth�lt. Die Rekursion des \lookat-Makros wird entweder abgebrochen, wenn beide Suchw�rter im aktuellen Adressenblock gefunden wurden oder \rest leer ist, da� hei�t, die momentane Zeile ganz durchsucht wurde. Erweitern Wie ich schon erw�hnt habe, w�chst die anwendungsbreite des finder.sty durch Einbezug Eportdateien. Eine derartige Verkn�pfung macht hat aber eine Anpassung der Ausgabevariablen \name, \street und so weiter notwendig. Selbstverst�ndlich lassen sich die vier Makros beliebig umbenennen, gleichwohl mu� bei der Einf�hung weiterer Ausgabevariablen folgendes beachtet werden. Gesetzt den Fall, die Anrede der Person soll noch in die Adressenbl�cke aufgenommen werden. Dazu verdoppelt man zuerst den vierten, \telephone-Block. Danach mu� \linefour beispielsweise in \linefive und demzufolge \linefive in \linesix umbenannt werden. Das die Numerierung dabei stimmt, ist nicht das Wichtige, sondern, da� \line??? nur an einer Stelle im \analysefile-Makro eine Dateizeile �bergeben bekommt. Abschlie�end nennt man noch \telephone etwa in \title um und sorgt daf�r, da� am Ende des Makros sowohl die Ausgabe, als auch gegebenenfalls das L�schen des Makros \title stattfindet. Ich bin sicher, durch finder.sty gestaltet sich das Briefschreiben unter LaTeX um einiges komfortabler. UNd mit etwas Phantasie steht der Einbindung in LaTeX-dokumente aller Art keine (fast) nichts im Wege. [Quelle: c't, magazin f�r computer technik, 3/92, Seite 214ff. Autor : Steffen Steinh�user]