Text2Html --------- Überblick --------- Das TextTransformer-Projekt "Text2Html" dient zur automatischen Umformung reiner Textdateien in HTML-Dateien. Dabei ist es nicht nötig, spezielle Formatierungsanweisungen einzufügen. M a n s i e h t d e n T e x t e n n i c h t a n, d a s s s i e V o r l a g e n f ü r H T M L - D o k u m e n t e s i n d . Allein, die Leerzeichen in den Texten müssen sorgsam gesetzt sein: Textabschnitte müssen durch Leerzeilen getrennt sein und Tabellen müssen richtig eingerückt sein und - neu - mit Leerzeichen können versteckte Anweisungen codiert werden. Das Projekt ist eine Beispiels-Anwendung für den TextTransformer und erhebt nicht den Anspruch alle möglichen Texte korrekt zu behandeln. Insbesondere kann es sein, dass unvollständige, eingerückte und verschachtelte Strukturen nicht erkannt werden. Für gängige Texte ist das Projekt aber durchaus zu verwenden. So wurden sämtliche Seiten dieser Homepage mit ihm erstellt. Individuelle Anpassungen und Erweiterungen kann jeder mit dem TextTransformer-Programm vornehmen. Um dies zu erleichtern wird das Projekt im folgenden ausführlich erläutert. - Zunächst folgt eine allgemein verständliche Darstellung der Analyse der Text-Dokumente - Dann folgt ein speziellerer Teil, in dem auf die technischen Einzelheiten eingegangen wird. Das Projekt kann hier herunter geladen werden: Text2Html.ttp Die Textvorlage für diese HTML-Seite ist: Text2Html.txt Reiner Text ----------- Reine Textdateien, zumeist im ASCII- oder ANSI-Zeichensatz, sind die wohl nach wie vor verbreiteste Art Texte abzuspeichern. Auf dem Bildschirm angezeigt sehen sie aus wie Texte, die mit einer Schreibmaschine getippt wurden. Das liegt daran, dass diese Dateien in binärer Form nichts weiter als die Buchstaben enthalten, die man auf einer Schreibmaschine tippen kann. Die reinen Textdateien enthalten keinerlei Anweisungen zur Verwendung verschiedener Schriftarten und -größen oder oder zum Zeichnen von Tabellen etc.. Zwar verfügt mittlerweile fast jeder Computerbenutzer über komplexe Textverarbeitungs-Software, die die Text-Daten in ihren jeweiligen eigenen Formaten abspeichern. Gerade die Einfachheit und damit die Unabhängigkeit von der jeweils verwendeten Software sind aber der große Vorzug reiner Textdateien. Auch sind Texte einfacher und damit schneller zu schreiben, wenn man nicht auf die jeweilige Formatierung zu achten hat. HTML-Text --------- HTML ist das Dateiformat in dem Webseiten gespeichert sind. HTML-Seiten sehen schöner aus als reine Texte, da Überschriften fett und in mit einer größeren Schrift dargestellt werden, Listen eingerückt werden und um Tabellen Rahmen gezeichnet werden. Auch HTML-Dateien sind Textdateien. Sie enthalten jedoch neben den reinen Textdaten Anweisungen zur Formatierung des Textes. Umwandlung von reinen Textdateien in HTML-Text ---------------------------------------------- Die Umwandlung eines Textes in ein HTML-Dokument ist relativ einfach, wenn der Text mit einer Textverarbeitungs-Software erstellt wurde: es müssen nur die Formatierungsanweisungen des Originaltextes adäquat übernommen werden. Bei der Umwandlung von reinen Textdateien in HTML-Text steht man jedoch vor dem Problem, dass der Originaltext keinerlei explizite Angaben zu Formatierung enthält. Für dieses Problem gibt es im Prinzip drei Lösungen: 1. Man fügt dem Originaltext spezielle Syntaxelemente hinzu, die das Umwandlungsprogramm instruieren, wie die HTML-Seite auszusehen habe. Dies Vorgehen kann insofern sinnvoll sein, als das dadurch die komplexen Möglichkeiten, die HTML bietet, auf eine vereinfachte Syntax reduziert werden könnten, die für die individuellen Zwecke ausreicht. Die Wikipedia ist ein Beispiel hierfür (siehe Wikipedia.html). Jedoch hätte man dann diese neue Syntax zu lernen, man wäre an sie gebunden und man würde damit das Original-Dokument verunstalten. Das ist nicht Ziel dieses Projekts. (Eine Ausnahme hiervon sind die versteckten Anweisungen s.u.) 2. Man erstellt ein HTML-Dokument als einfaches Abbild des Originaltextes. d.h. ohne Formatierungen. Das ist immerhin schon ein erster Ansatz. Tatsächlich lassen sich Text-Dateien oftmals im Browser direkt anzeigen, ohne dass irgendwelche Manipulationen vorgenommen werden müssten. Wer es besser machen möchte und sich schon einmal den Original-Code einer HTML-Seite angesehen hat, könnte meinen, hierfür müsse lediglich der Original-Text in die (Tag-) Paare: und eingeschlossen werden: .. Original-Text Speichert man den neuen Text dann mit dem Extender ".html" statt ".txt" ab und lädt ihn in einen Browser, so wird man allerdings bemerken, dass hierbei alle Zeilenumbrüche verloren gegangen sind, und dass immer nur das erste einer Reihe von Leerzeichen angezeigt wird. Außerdem ist nicht sicher gestellt, dass Sonderzeichen richtig dargestellt werden und die Zeichen, durch die HTML-Tags definiert werden, bringen die Textanzeige völlig durcheinander. Dennoch bildet diese Möglichkeit das Grundgerüst für den HTML-Konverter unter Punkt 3. 3. Man entwickelt ein Schema, wie aus dem Aufbau und Inhalt des Originaltextes eine Formatierung des Textes abzuleiten ist. Dies ist das Verfahren, dass im Text2Html-Projekt angewandt werden soll. Nur im Fall, dass keine Formatierung ableitbar ist, soll der Text wie unter Punkt 2 skizziert im möglichst originaler Form dargestellt werden. Wie aber soll die Formatierung aus dem Text ableitbar sein? Die Antwort ist unter Punkt 3 schon angedeutet: aus Aufbau und Inhalt. Text-Aufbau ----------- Den Aufbau eines Textes erkennt man am besten, wenn man ihn aus einem Abstand betrachtet, in dem man ihn nicht mehr lesen kann. Die Struktur ergibt sich gerade aus dem, was nicht Text ist: aus seinen Lücken. Lücken entstehen durch Zeilenumbrüche, Leerzeilen, Leerzeichen und Tabulatoren. Das Text2Html-Projekt nimmt zunächst die gleiche Perspektive ein. Ein Text soll derart in ein HTML-Dokument umgewandelt werden, dass die geschilderte Struktur nicht nur erhalten bleibt, sondern verstärkt wird. Eine Kapitelüberschrift soll etwas größer als der übrige Text und in Fettschrift dargestellt werden und das regelmäßige Muster einer Auflistung oder Tabelle soll durch zusätzliche Markierungen oder Linien akzentuiert werden. Text-Inhalt ----------- Ein zweites Kriterium für die Verwendung bestimmter HTML-Elemente ergibt sich aus einer näheren Betrachtung des Textes selbst. Z.B. die Unterstreichung von Links auf einer HTML-Seite und die Möglichkeit, durch Anklicken eines Links auf eine andere Seite zu gelangen, wird in HTML dadurch realisiert, dass der Ausdruck: " Original-Text wenn man ihr nicht die zwei Leerzeichen voranstellen würde: Original-Text Eine Leerzeile mit exakt zwei Leerzeichen hat einen ähnlichen Effekt wie die vorherige Anweisung. Zusätzlich werden alle Leerzeichen der folgenden Zeilen ausgegeben, die Sonderzeichen werden nicht übersetzt und das fett-Attribut wird ignoriert. (Für HTML-Kenner: der folgende Text wird in die Tags
 und 
eingeschlossen.) Vergleichen Sie die Resultate für den gleichen Text. Ein Text mit z w e i vorangestellten Leerzeichen sieht genauso aus, wie auch der Originaltext aussieht E n g l i s h : Hello world G e r m a n : Hallo Welt Mit e i n e m vorangestellten Leerzeichen wird der Text als einfacher Absatz interpretiert und Fettschrift wird erkannt: E n g l i s h : Hello world G e r m a n : Hallo Welt O h n e vorangestellte Leerzeichen wird der Text als Tabelle interpretiert: E n g l i s h : Hello world G e r m a n : Hallo Welt HINWEISE ZUR IMPLEMENTATION A c h t u n g : die folgenden Hinweise sind nur zu verstehen, wenn man schon einige Erfahrung mit der Benutzung des TextTransformers hat. Das "Text2Html" Projekt präsentiert fortgeschrittene Techniken des TextTransformers, die nur für wenig strukturierte Texte erforderlich sind. Der TextTransformer unterstützt die Entwicklung effizienter LL(1)-Parser. Der frei gestaltete Text, der hier analysiert werden soll, genügt den Bedingungen einer LL(1)-Analyse nicht. Die erweiterten Fähigkeiten des TextTransformers, - die Verwendung von Produktionen zur Vorausschau und - die Möglichkeit des Aufrufs von Unterparsern lassen ihn die hier gestellte Aufgabe dennoch bewältigen. Diese Mittel sollten aber möglichst sparsam eingesetzt werden, da durch sie die Ausführungsgeschwindigkeit der Übersetzung herabgesetzt wird. Projekt-Optionen ---------------- Da für die Zerlegung des Textes die Erkennung von Leerzeilen und Einrückungen nötig ist, dürfen Leerzeichen nicht ignoriert werden. Die Projekt-Optionen sind daher die Standard-Einstellungen dahingehend verändert, keine Zeichen auszulassen. Anmerkung: In einer Reihe von Produktionen (s.u.) wird diese Veränderung durch das Setzen von lokalen Einstellungen wieder rückgängig gemacht. Startproduktion --------------- Am Anfang und Ende der Startproduktion "Text2Html" wird mit den Funktionen "HtmlBegin" und "HtmlEnd" der HTML-Rahmen geschrieben, in den die eigentlichen Textelemente eingefügt werden. Der Kern der Produktion besteht in der Zerlegung des Ausgangstextes in die alternierenden Abschnitte aus Leerzeilen und Text. Eine Leerzeile ist definiert als: EMPTY_LINE ::= (\r?\n){2,} \ // linebreaks ( \ [ \t]{3,} \ // drei oder mehr Leerzeichen oder Tabulatoren (\r?\n|\z) \ )* d.h. besteht zumindest aus zwei Zeilenumbrüchen. Einzelne Zeilenumbrüche, können auch innerhalb eines Textabschnitts (PartOfText) vorkommen. Das Ende eines Textabschnitts wird eindeutig durch "EMPTY_LINE" markiert, da dieses Token auf einen längeren Textabschnitt passt als ein einzelner Zeilenumbruch. Nach den Präferenzregen des TextTransformers wird es somit bevorzugt erkannt. Da aber Textabschnitte sowohl durch eine gerade wie durch eine ungerade Anzahl an Zeilenumbrüchen getrennt sein können, muss auf den doppelten Zeilenumbruch "EMPTY_LINE" auch ein einzelner "EOL" folgen können, bevor ein neuer Textabschnitt beginnt. EOL ::= \r?\n PartOfText ---------- Nach den Leerzeilen wird durch entsprechende Vorausschau getestet, welches der HTML-Elemente (Titel, Liste, Tabelle, Text) als nächstes folgt. In der folgenden Tabelle gibt es für jedes der HTML-Element eine Spalte. In der ersten Zeile stehen die Namen der Produktionen, die zur Vorausschau für das entsprechende Element verwendet werden und in der zweiten Zeile stehen die Produktionen, mit denen der Text weiter zerlegt wird, wenn die Vorausschau erfolgreich war. .. Titel Liste Tabelle Text ---------------------------------------------------------------------- Vorausschau isTitle isList isTable -- Produktion Title List Table Paragraph Es wäre möglich, zur Vorausschau dieselbe Produktion zu verwenden, die dann für die Verarbeitung des Textes zuständig ist. Die hier definierten Vorausschau-Produktionen kürzen die Vorausschau auf ein nötiges Mindestmaß ab. Da zwei Textbestandteile von einer einzelnen Leerzeile getrennt sein können, darf PartOfText keinen nachfolgenden Zeilenumbruch konsumieren. Wohl aber dürfen Produktionen, die zur Vorausschau verwendet werden, das Vorhandensein einer nachfolgenden Leerzeile testen. Vorausschau-Produktionen konsumieren keinen Text. Erkennung von Tabellen ---------------------- a) Überblick über den Erkennungsalgorithmus Zunächst wird an Hand einer relative allgemeinen Beschreibung von Tabellen getestet, ob eine Tabelle im Text folgt. Die Produktion "isTable" prüft, ob es mindestens zwei aufeinander folgende Zeilen im Text gibt, die eine tabellen-artige Struktur aufweisen. Ist dies der Fall, wird der gesamte Tabellen-Abschnitt eingelesen und dabei zunächst in Zeilen und diese wiederum in in Text und Nicht-Text-Teile (die Lücken) aufgeschlüsselt. So wird eine Baumstruktur erhalten, in der die Zeilen der Tabelle die Zweige sind. Haben alle Zeilen/Zweige eine gleiche Zusammensetzung aus Text- und Lücken-Bestandteilen ist die Erstellung der Html-Tabelle kein Problem. Mit der Methode "IsPerfectTable" wird geprüft, ob diese der Fall ist. Handelt es sich nicht um eine "perfekte" Tabelle, so muss der Baum genauer analysiert werden, um zu versuchen, die Spaltenzahl und die Spaltenpositionen zu bestimmen. b) Tabulatoren Die Spalten einer Tabelle sind voneinander durch Tabulatoren getrennt. Als Tabulator wird hier nicht nur ein Tabulator-Zeichen angesehen, sondern auch das Zeichen '|' oder eine Folge von Leerzeichen. Genau wird das Token TABULATOR wie folgt definiert: TABULATOR ::= \t+|\|+|[ ]{2,} Leider kann man nicht davon ausgehen, dass Felder nur zusammenhängende Zeichen enthalten können und dass die Felder voneinander korrekt durch Tabulatoren getrennt sind. Praktisch kommt es häufig vor, dass aus Platzgründen zwei Felder durch ein einfaches Leerzeichen getrennt sind. Da einfache Leerzeichen aber auch innerhalb eines Tabellen-Feldes erlaubt sein sollen, ist die Bedeutung des Leerzeichens damit vom jeweiligen Kontext abhängig. Es sei hier nochmals an die oben genannten Mindestanforderungen an Tabellen erinnert. NSpace / NSpaceNPm ------------------ In den Produktionen für die HTML-Elemente wird der Text zunächst nur grob zerlegt: in die Lücken und in die "gefüllten" Stellen. Die Erkennung der Text-Teile, die keine Leerzeichen enthalten erfolgt durch die Produktion "NSpace" (not space). "NSpaceNPm" (not space, not punctuation mark) ist eine Variante von "NSpace", die dem Parsen von Titeln dient, in denen keine Satzzeichen vorkommen dürfen. Der Sinn der Verwendung von "NSpace" soll am Beispiel des Tabellen-Parsers erläutert werden. Tabellen-Parser --------------- Die obige Struktur-Vorgabe für Tabellen erlaubt es nicht einen Parser zu konstruieren, der direkt die einzelnen Felder als solche erkennt. Vielmehr werden die Tabellen-Zeilen als abwechselnde Abschnitte von Tabulatoren bzw. Leerzeichen und Text angesehen, der nicht aus Tabulatoren bzw. Leerzeichen besteht. Wenn es sich nicht um eine "perfekte" (s.o.) Tabelle handelt, so wird in einer anschließenden Analyse eine Zeile herausgesucht, die eine maximale Anzahl an "echten" Tabulatoren enthält. Diese Zeile wird dann als Maßstab für die übrigen Zeilen genommen, für die angenommen wird, dass ihre Felder an den Zeilen-Positionen beginnen, die in der Muster-Zeile unmittelbar hinter den Tabulatoren liegen. PrintNSpace ----------- Vor der Ausgabe der nicht leeren Textteile werden diese erneut durch einen Unter-Parser "PrintNSpace" zerlegt. In "PrintNSpace" wird der Text ausgegeben, jedoch für unterschiedliche Textbestandteile verschieden. So besteht "PrintNSpace" aus einer Reihe von Alternativen, zu denen z.B. "Link" zur Erkennung von Links und BLOCK zur Erkennung von Sperrschrift gehören: erstere Produktion erzeugt HTML-Links und in der Aktion zum BLOCK-Token wird der Text als Blocksatz ausgegeben. In den anderen Alternativen wird entweder der Text unverändert ausgegeben, oder es erfolgt die oben angesprochene Übersetzung der Sonderzeichen (in den Aktionen der Token "HTML_SPECIAL_CHAR" und "HTML_KEY_CHAR"). Sperrschrift ------------ Sperrschrift. d.h. die Einfügung von jeweils einem Leerzeichen zwischen den Buchstaben eines Wortes, wird in Fett-Schrift übersetzt. Ein Problem bilden hierbei Sonderzeichen, wie das Apostroph oder ein Komma, die innerhalb der Sperrschrift auftauchen können (z.B. im englischen "don't"). Sie sind nicht durch ein Leerzeichen vom vorhergehenden Buchstaben getrennt. Außerdem kann ein Satz mit Sperrschrift enden und somit ein Punkt, ein Ausrufezeichen oder ein Fragezeichen unmittelbar auf den letzten gesperrten Buchstaben folgen. Im Englischen gibt es zudem das Wort "a", dass als einzelner Buchstabe immer von Leerzeichen eingeschlossen ist. Übersetzung der Sonderzeichen ----------------------------- Zur Übersetzung der Sonderzeichen könnte man für jedes von ihnen ein eigenes Token definieren, das mit einer Aktion zur Ausgabe seines Namens verbunden ist, ähnlich wie im Atari-Beispiel im Installations-Pakets des TextTransformers. Im Text2Html-Projekt wird ein anderer Weg beschritten: sämtliche Sonderzeichen werden in einer Zeichenmenge zusammengefasst und diese Zeichenmenge dient zur Definition eines Tokens: HTML_SPECIAL_CHAR ::= [-\xa0-¿\"#$&'*+/<=>\\\^_|×÷] Daneben gibt es noch ein Token für die Zeichen, die eine Schlüsselbedeutung in HTML haben: HTML_KEY_CHAR ::= [<>&"] Auf der Interpreterseite ist eine Tabelle als "mstrstr" definiert, die jedes Zeichen mit seinem zugehörigen Namen verbindet. Z.B. m_mSpecialChar[ "ü" ] = "ü"; Wird nun eines der Zeichen aus der Menge der Sonderzeichen erkannt, wird es durch: out << m_mSpecialChar[State.str()]; in seinen Namen übersetzt. Anmerkung: Die Tabelle enthält fast 100 Wertepaare, aber selbstverständlich wurde sie, ebenso wie die Zeichenliste, aus einer vorhandenen Tabelle mittels eines kurzen TextTransformer-Programms hergestellt. Das hat nur 5 min gedauert. Stil und Keywords ----------------- Beim Schreiben des HTML-Grundgerüsts werden die Funktionen "PrintStyle" und "PrintKeyWords" aufgerufen. "PrintStyle" bestimmt die verwendeten Schriftgrößen und -arten und "PrintKeyWords" erzeugt eine (unsichtbare) Liste von Stichworten für Suchmaschinen. Diese beiden Funktionen sollte jeder Benutzer entweder an seine eigenen Bedürfnisse anpassen oder schlicht in folgender Weise ausklammern: //PrintStyle(); //PrintKeyWords(); Schluss ------- Ich wünsche viel Spaß und Erfolg mit dem Text2Html-Umwandler. Sollte jemand etwas an diesem Projekt verbessern, es erweitern oder anders modifizieren, würde ich mich freuen, wenn er es auch anderen Besuchern dieser Homepage zur Verfügung stellen würde. Letztes Update: 22.12.07