next | next | up | down | Inhalt | Uebungen | Complete | Kommentar

all, section 8.10.

8.10.  Von troff ins Web

Einleitung

Es gibt Werkzeuge mit denen troff -Dokumente für's Web aufbereitet werden können. Natürlich sollen die generierten Web-Seiten untereinander und mit der Welt verbunden sein, sowie Graphik, Tabellen und Mathematiksatz etc. enthalten können. Der zusätzliche Aufwand sollte minimal sein: zwei zusätzliche Makros sollten genügen. Wie dies geht, erfahren Sie in diesem Artikel.

Einleitung

Einige wenige Unverbesserliche, zu denen auch ich und einige meiner besten Freunde gehören, setzen ihre Texte immer noch mit den Mitgliedern der troff-Familie. Auch wir möchten unsere Texte, zumindest was die Optik anbelangt, in guter -- um nicht zu sagen in bester -- Qualität im Web publizieren. Die Anforderungen an die zu verwendenden Techniken sind hoch gelegt: Der Ausdruck und die Web-Seite sollen aus denselben Quellen erzeugt werden; die Web-Seiten sollen Querverweise und Graphik enthalten; jede Seite soll mit dem gleichen Rahmen versehen sein, damit die Navigation vereinheitlicht wird; eine Aufsplittung des Dokuments in kleine Einzelseiten soll an inhaltlich definierten Punkten automatisch erfolgen; ein Inhaltsverzeichnis und ähnlich nützliche Dinge sollten automatisch erzeugt werden; und ehrlich gesagt, möchte ich mich nicht so sehr mit HTML [1] beschäftigen.

Resultat

Bevor ich zum ``wie'' komme, möchte ich Ihnen das Resultat zeigen. Eine Publikation im Web stelle ich mir wie folgt vor:

--   das Layout muß, soweit als möglich, einheitlich sein
--   die einzelnen Seiten sollten relativ kurz
     sein und das Dokument sollte
     nach inhaltlichen Gesichtspunkten
     aufgeteilt sein. So sollte sich z.B. jedes Kapitel
     und Unterkapitel auf einer eigenen Seite befinden.

Wird der vorliegende Artikel anstatt nach PostScript so nach HTML übersetzt, wie der Artikel beschreibt, erhält man als erste Web-Seite die in Abbildung 1 dargestellte Seite. Ein Klick auf bischof aktiviert ein mail-Tool; die Web-Seite unseres Fachbereichs, bzw. unserer Universität, erhält man durch ein Klicken auf die entsprechende Zeile.

Mit den vier Pfeilen links oben bzw. unten kann man sich durchs Dokument navigieren. Das I-Symbol, rechts von den Navigations-Pfeilen, führt zum Inhaltsverzeichnis. Mit einem Klick auf das Brief-Icon läßt man dem Autor eine Nachricht zukommen. Klickt man auf den Pfeil, welcher nach rechts zeigt, kommt man zur inhaltlich nächsten Seite. In unserem Fall ist das Abbildung 2. Das Inhaltsverzeichnis ist in Abbildung 3 dargestellt; es keine inhaltlich nächste oder vorherige Seite. Deshalb ist kein Navigations-Pfeil aktiv.

Der troff-Input für die erste Seite ist in Abbildung 4 dargestellt.

.NH 1
Von troff ins Web
.LP
.ce 9
.Hr -url mailto:bischof@informatik.uni-osnabrueck.de          \
    "Hans-Peter Bischof"
.Hr -url http://www.mathematik.Uni-Osnabrueck.DE/home_ge.html \
    "Fachbereich Mathematik-Informatik"
.Hr -url http://www.informatik.uni-osnabrueck.de              \
    "Universit\*at Osnabr\*uck" .
.ce 0
.LP
.SH
Abstract
.LP
Einige wenige Unverbesserliche,

Abbildung 4: troff/unroff Input

Mit diesen Zeilen haben Sie alle zusätzlich Makros gesehen, die neben ein paar Programmen benötigt werden, um aus troff-Dokumenten Web-Seiten zu machen. Einfach, oder?

Nutzung

Lassen Sie mich, bevor wir in den nächsten Abschnitten zu den technischen Details kommen, erst die Randbedingungen, Ausgangssituation und Vorgehensweise beschreiben.

Ich schreibe meine Texte unter Unix und erzeuge PostSkript-Dateien mit den Werkzeugen der groff -Familie (groff(1), geqn(1), gtbl(1), gpic(1)) und lokal entwickelten Präprozessoren wie nsd [2]. In aller Regel wird bei der Übersetzung ein selbst entwickeltes Makropaket zusätzlich verwendet; Programmteile werden extrahiert und entsprechend aufbereitet -- Zeilennummern werden vorangestellt, \ durch \e ersetzt, etc -- und eingebunden. Gesteuert wird der Übersetzungsprozeß durch make(1). Mögliche Ziele sind hierbei:

1, 2, ...   die einzelnen Kapitel
all         das komplette Manuskript
spell       Buchstabierkontrolle
backup      Anlegen einer Sicherungskopie
clean       Löschen von Zwischenresultaten
nuke        Löschen von allen generierten Dateien
...
Es ist offensichtlich, daß die Pflege des makefiles aufwendig werden kann: Neue Projekte werden begonnen, Quellen innerhalb von existenten Projekten kommen hinzu, weitere Kapitel werden geschrieben, neue Quellen werden augelegt, etc. Weil die Nachführung bzw. der Neuaufbau von makefiles aon Hand nicht angenehm, sondern zeitraubend und langweilig ist, entwickelte ich ein makefile-Generierungsprogramm mk_gen, welches ein aktuelles makefile generiert.

Um dieses Skript möglichst ohne großen Aufwand erstellen und problemlos immer wieder verwenden zu können, war es hilfreich, eine gewissen Einheitlichkeit der Dokumente zu verlangen.

1.
Die Kapitel müssen fortlaufend benannt werden (c.01, c.02 ...)
2.
Alle verwendeten Quellen bzw. Quellfragmente müssen in die Quelle via ".so Src_t/path" eingebunden werden. Die zugehörigen Quellen müssen sich im Katalog "Src/path" befinden.

mk_gen funktioniert so gut, daß ich für die Produktion von PostSkript-Seiten in der Zwischenzeit keine makefiles mehr ``von Hand'' schreibe, sondern ausschließlich generieren lasse. Aus diesem Grunde sollte mk_gen so adaptiert werden, daß aus den troff-Quellen optional Web-Seiten generiert werden können.

Die Produktion von HTML-Seiten, Erstellen von Inhaltsverzeichnissen, Verbinden der Seiten, etc. zerfallen nach genauerer Analyse in zwei getrennte Problemkreise:

1.
Erzeugen der einzelnen Web-Seiten
2.
Verpacken der Web-Seiten in einheitliche Rahmen und Verbinden der Seiten

Das erste Problem kann man mit Werkzeugen lösen, welche sich im Netz finden. Grundsätzlich sind zwei verschiedene Wege gegangen worden:

1a.
Mit einem perl(1) oder awk(1)-Skript wird ein Konverter von einem Makropaket Richtung HTML implementiert. Normalerweise können eqn-, tbl-, pic-Quellen in Gif-Dateien umgewandelt und dann mit eingebunden werden. troff2html von Jim Briggs setzt ein mit dem me-Makropaket geschriebenes Dokument in HTML um.
Falls ein Makropaket, wie zum Beispiel man, eine sehr präzise Struktur produziert, wie dies beim man-Makropaket der Fall ist, besteht auch die Möglichkeit das mit nroff formatierte Dokument in eine Web-Seite umzuwandeln. man2html von Earl Wood setzt vorformatierte Manualseiten nach HTML um.
1b.
Im Kontrast dazu implementierte Oliver Laumann einen troff-Parser, unroff, welcher HTML anstelle einer Druckerbeschreibungssprache erzeugt. Dies ermöglicht unroff die Abarbeitung von benutzerdefinierten Makropaketen.

troff2html

troff2html ist ein perl-Skript, das ein troff-Dokument, falls es mit dem me-Makropaket geschrieben ist, nach HTML konvertieren kann. Folgende Funktionalität ist existent:

--   das me-Makropaket kann verwendet werden
--   die Ausgabe der Präprozessoren kann durch nroff
     weiter übersetzt bzw. via GIF-Bild
     inline eingebunden werden
--   alle ISO-8859-1 Sonderzeichen werden übersetzt
--   Inhaltsverzeichnis kann erzeugt werden
--   Navigationsleiste kann erzeugt werden
--   ein Aufsplitten des Dokuments ist konfigurierbar
--   eigene Makros können nur mit erheblichem Aufwand eingebaut werden

Das Resultat von troff2html ist nur dann befriedigend, wenn man keine in sich bzw. in die ``Welt'' verbundene Seiten generieren möchte. Die sehr komplizierte Adaption eigener Makros, Setzen von Registerwerten etc., schränkt den möglichen Einsatzbereich doch sehr ein. Ich fand troff2html für meine Anforderungen als nicht akzeptabel gefunden.

man2html

man2html ist ein perl-Skript, das Unix-Manual-Seiten nach HTML übersetzt und die Seiten untereinander auch verbindet. man2html akzeptiert als Eingabe mit nroff formatierte Manual-Seiten und generiert daraus eine HTML-Seite. Ein typischer Aufruf ist:

$ man echo | man2html > echo.html

Da man2html die Struktur der formatierten Seiten kennt, ist eine Umsetzung des Texts in HTML nicht weiter schwierig. Der generierte Text für den obigen Aufruf ist in Abbildung 5 dargestellt.

<HTML>
<BODY>
<PRE>
       echo - display a line of text


</PRE>
<H2>SYNOPSIS</H2><PRE>
       <STRONG>echo</STRONG> [<STRONG>-ne</STRONG>] [<EM>string</EM> ...]
       <STRONG>echo</STRONG> {--help,--version}

Abbildung 5: man echo | man2html | sed 10q

Schwieriger stellt sich die Sache dar, wenn die Seiten untereinander verbinden werden sollen. In diesem Fall kann sich man2html nur darauf verlassen, daß sich für Verweise der Art cmd(I), die an beliebiger Stelle im vorformatierten Text auftauchen können, eine Seite im Dateisystem an der Stelle manI/cmd.1 befindet bzw. diese Seite bei Bedarf erzeugt werden kann. Die Perl-Spezifikation des Musters lautet:

/([\+_\.\w-]+)\((\d)(\w?)\)/).

Für die Manual-Pakete einzelner Hersteller kann der Teil des perl-Skripts, der die Crossreferenzen einfügt, problemlos modifiziert werden.

Für man2html gibt es auch eine CGI-Schnittstelle. Diese kann allerdings bei unsachgemäßer Installation und böshafter Nutzung zu sehr viel Ärger führen. Die Anfrage nach ls; rm -rf / wird letztlich das Kommando man ls; rm -rf / ausgeführt.

Als Produzenten für ``rohe Seiten'' zum Beispiel als Begleitmaterial einer Vorlesung, kann man2html problemlos eingesetzt werden.

unroff

Unroff bearbeitet ein Dokument, welches mit troff gesetzt werden kann, und übersetzt dies in ein anderes Format, z.B. SGML oder HTML. Die konkrete Ausprägung der Übersetzung wird durch benutzerdefinierte Regeln und Funktionen spezifiziert. Die Programmierbarkeit wird durch die Nutzung von elk, einer Scheme-basierten Sprache erreicht. Je nach Back-End kann grundsätzlich jede beliebiges Ausgabeformat erreicht werden.

Besonders interessant ist, daß unroff einen vollständigen troff-Interpreter enthält. Dies hat zur Konsequenz, daß auch Dokumente, die ein eigenes Makropaket verwenden, mit unroff umgewandelt werden können.

Die Dokumente können untereinander durch Verweise verbunden sein, ebenso können externe Verweise verwendet werden.

Wie?

Die Produktion der Web-Seiten ist grob in drei Schritte unterteilt.

1.
Mit unroff werden die einzelnen Seiten und das Inhaltsverzeichnis generiert.
2.
Ein Shell-Skript, mk_links, generiert die Rahmen und verbindet die Seiten.
3.
Ein Shell-Skript, mk_toc_frame, generiert den Rahmen um das Inhaltsverzeichnis welches von unroff erzeugt wurde.

Unroff

Werden die Dokumente mit unroff übersetzt, können zusätzlich zwei Makros benutzt werden, um die Hypertext-Verweise zu generieren.

1.
Mit .Hr -url mailto:bischof "hpb" wird ein Anker hinterlegt, der das entsprechende mail-Tool aktiviert, wobei der Empfänger bischof ist. Als Text findet sich in der Web-Seite das letzte Argument des Makros. Wird das Dokument mit troff übersetzt wird dieses Argument kursiv gesetzt. Einen Hypertext-Verweis kann man mit .Hr -url http://www.informatik.uni-osnabrueck.de "Universit\*at Osnabr\*uck" an legen.
2.
Einen lokales Ziel erzeugt man mit .Ha sp Shell-Programmierung. Auf das lokale Ziel verweist man durch .Hr -symbolic sp "erstes Kapitel". In der Web-Seite findet sich der Text ``erstes Kapitel'', der dann zum lokalen Ziel sp zeigt.

Der Aufruf von unroff lautet zum Beispiel:

$ unroff -ms \
  document=all \
  split=2  \
  hyper.scm \
  lib/header c.01

c.01 wird mit dem ms-Makropaket gesetzt, wobei die Angabe von split=2 dafür sorgt, daß aus jedem Kapitel und aus jedem Unterkapitel erster Stufe eine eigene Seite wird, deren Dateiname mit all- beginnt. In hyper.scm sind die Hypertext-Anweisungen implementiert. lib/header enthält ein lokales Makropaket.

Wird c.01 mit troff gesetzt, lautet der Aufruf:

$ groff -tep -ms \
  lib/header c.01

Unroff kann trotz aller Mühen nicht alles in eine Web-Seite verwandeln, was man mit troff und seinen Präprozessoren setzen kann. Tabellen setzt unroff tbl und nroff und setzt sie dann als Text ein. Komplizierte typographische Objekte wie Mathematik-Satz, Liniengraphik etc. werden aus dem Text extrahiert, mit eqn und troff gesetzt, und letztlich in ein gif-Format umgewandelt. Ein Beispiel zeigt Abbildungldung 6.

Will man in Tabellen komplizierte typographische Objekte einbinden stößt man an die Grenzen der Architektur von unroff.

Weiteren Präprozessoren wie grap oder nsp kann können dagegen problemlos verwendet werden. So gesehen fügt sich unroff in die troff-Architektur optimal ein.

Das gesammte Verfahren ist zweistufig, weil unroff keinen Überblick über die produzierten Web-Seiten hat.

mk_links

Ein Setzen des Dokuments mit split=2 und document=all führt zu Dateinamen der Gestalt

all-1
        all-1.1
        all-1....
all-2
        all-2.1
        all-2....

Der Pfeil in den Navigationsleisten nach rechts bzw. links soll immer zur nächsten bzw. zur vorhergehenden Seite verweisen, falls diese existiert; falls nicht soll ein Link auf einen Verweis eingebaut werden, der anzeigt, daß hier die Welt zu Ende ist und der Pfeil ist durchgestrichen. Der Pfeil nach oben bzw. unten soll immer zur nächsten bzw. zur vorhergehenden Hauptkapitel verweisen, falls dieses existiert. Das nachfolgende Teil eines Shellskripts verbindet die Seiten korrekt.

 ...
304     
305     doLink()     # prefix j i
306     {
307         LEFT= `find_prev $1 $2 $3`   # naechste Seite
308         RIGHT=`find_next $1 $2 $3`   # vorhergehende Seite
309         UP=   `find_up   $1 $2`      # vorhergehendes Kapitel
310         DOWN= `find_down $1 $2`      # naechstes Kapitel
311         create_frame $4 $LEFT $RIGHT $UP $DOWN $PREFIX.html
312     }
313     j=1
314     i=0
315     while :                          # ueber alle Kapitel
316     do
317         if [ $i -eq 0 ]
318         then                         # Hauptkapitel
319             FILE=$PREFIX-$j.html
320         else                         # Unterkapitel
321             FILE=$PREFIX-$j.$i.html
322         fi
323     
324         if [ -f $FILE ]              # am Ende der Welt?
325         then
326             doLink $PREFIX $j $i $FILE
327         else
328             j=`expr $j \+ 1`
329             if [ ! -f $PREFIX-$j.html ]
330             then
331                 break
332             fi
333             i=-1
334         fi
335     
336         i=`expr $i \+ 1`
337     
338     done
339     
 ...

Manual

Unter Verwendung der vorgestellten Technik kann man mit unroff auch die Manualseiten in Web-Seiten umwandeln. Es wird ein zum Manual-Baum paralleler Baum aufgebaut, der anstelle von troff-Input HTML-Seiten enhält. Zusätzlich müssen nur zwei weitere Shellskripte eingesetzt werden, um die Navigation zu erleichtern. Eines setzt die Querverweise in HTML-Verweise um, das andere generiert ein Inhaltsverzeichnis für jeden Katalog, in dem sich HTML-Seiten befinden. Siehe Abbildung 7 und 8. Für jedes Problem wurde ein Skript entwickelt, wobei angemerkt werden muß, daß die Querverweise nur dann eingebaut werden konnten, wenn die Verweise in den Manualseiten systematisch verwendet wurden.

So werden in den Manuals zu Sun OS 4.1.3 bzw. Solaris 2.0 alle Verweise mit dem Makro BR gesetzt. Das Skript kann auf jede Systematik angepaßt werden. Werden die Manualseiten unsystematisch geschrieben, ist es nicht möglich, alle Querverweise in die HTML-Seiten aufzunehmen.

Literatur

[1]
Russ Jones & Adrian Nye, "HTML und das World Wide Web: selbst Publizieren imWWW", O'Reilly, 1995.
[2]
Axel T. Schreiner, "Ein DIN 66261 Baukasten --``/usr/bin/nsd''" unix/mail 4/89, Carl Hanser Verlag, 1989.

Http-Adressen:

elk

http://www-rn.informatik.uni-bremen.de/software/elk
man2html

http://medusa.acs.uci.edu/indiv/ehood/man2html/doc/man2html.html
troff2html

http://www.sis.port.ac.uk/~briggsjs/troff2html.html
unroff

http://www-rn.informatik.uni-bremen.de/software/unroff
Quellen

Die Quellen sind über die HTTP -Adresse im Impressum zu beziehen.

back | next | up | down | Inhalt | Uebungen | Complete | Kommentar


Created by unroff & hp-tools. © by Hans-Peter Bischof. All Rights Reserved (1997).

Last modified 03/July/97