Groff ist die Implementation von troff, was für text runoff steht. Troff ist eine Markupsprache wie z. B. HTML und wurde Ende der 70er Jahre für Fotobelichter entwickelt. Daher ist der Befehlssatz dieser Sprache auch eng an die damals recht limitierte Hardware angelehnt. Ein Vorteil dadurch ist, dass selbst umfangreiche Dokumente auch auf einer längst nicht mehr aktuellen Hardware in übersichtlichen Zeiträumen übersetzt werden können, um z. B. PDF als präzise Vorschaumöglichkeit zu nutzen.
Groff und TeX sind insofern miteinander verwandt, als beide das Ziel verfolgen, qualitativ hochwertigen Textsatz zu ermöglichen. Allerdings sind die Ansätze sehr verschieden, nicht nur in der Syntax, sondern auch in der Handhabung der Programmpakete und Schriftarten.
Der Begriff troff wird in diesem Artikel als Bezeichnung für das Eingabeformat als auch für das eigentliche Übersetzungsprogramm verwendet. Groff ist das komplette Programmpaket. Sowohl troff als auch groff werden normalerweise klein geschrieben, in Anlehnung an den englischen Ursprung.
Vor troff entwickelte sich nroff (die heutzutage beide eigentlich das gleiche Programm sind), welches Ausgaben für zeichenorientierte Geräte wie Zeilendrucker, Typenraddrucker, Computerterminals usw. formatierte. Es konnte alles, was troff konnte, und ignorierte die Kommandos, die nicht anwendbar waren (wie Schriftartänderungen).
In der groff-Implementation ist nroff dasselbe wie troff, d. h., es wird das gleiche Zwischenformat ausgegeben, jedoch ein spezieller Treiber (grotty) für die Textausgabe benutzt.
Inhaltsverzeichnis |
In Anlehnung an troff und die Documenter’s Workbench wurde innerhalb des GNU-Projektes troff von James Clark neu geschrieben, sodass keine Copyrightprobleme mit dem alten, proprietären Code zu erwarten sind. Groff wird kontinuierlich weiterentwickelt.
Das Ditroff-Zwischenformat wurde beibehalten, allerdings mit einigen Erweiterungen. Es stehen unter Anderem Treiber für PostScript, PCL und DVI zu Verfügung; ebenso kann man direkt HTML erzeugen als auch formatierte Textdateien.
Da die meisten troff-Befehle ähnlich wie bei TeX äußerst primitiv sind, liegen groff einige sogenannte Makropakete bei, die dem Benutzer Alltagsaufgaben erleichtern sollen. So gibt es z. B. die Pakete Mom, Me, Mm und Ms für Dokumente, Doc und Man für Manpages. Diese werden beim Aufruf von groff auf der Kommandozeile entsprechend mitgeladen und ermöglichen so dem Benutzer, mit nur einer vergleichsweise kurzen Lernphase typografisch gut gestaltete Dokumente zu schreiben.
Für jedes Ausgabegerät von Groff gibt es (üblicherweise) ein Verzeichnis in /usr/share/groff/<version>/font, benannt nach dem Muster devgerät (z. B. devps, devlj4, …). Anders als bei TeX werden bei Groff keine Schriftarten für das jeweilige Ausgabegerät optimiert in Pixeldaten umgewandelt.
Im folgenden Beispiel devps liegen Beschreibungsdateien mit dem Kurznamen der Schriftarten, in welchen die Metriken der referenzierten Schriftart (Zeichenbreiten, Kerningpaare, Ligaturen, Zeichenzuordnungen) usw. aufgeführt werden. Üblicherweise liegen hier ausschließlich Standardschriftarten vor, die jedes PostScript fähige Ausgabegerät schon im Festwertspeicher eingebaut hat. So bleiben die PostScript Daten klein und das Ausgabegerät kann auf seine internen Schriften zum Ausdruck zurückgreifen. Es besteht aber die Möglichkeit, eigene PostScript Type1-Font Schriftarten einzubinden:
Jetzt kann der Font mit den üblichen Befehlen geladen und referenziert werden.
Heute ist Groff Bestandteil eines Großteils der Linuxdistributionen und sorgt im Hintergrund für das Anzeigen von Manpages.
Im Laufe der Zeit ist Groff – vielleicht auch in Anbetracht der gewöhnungsbedürftigen Syntax – in Vergessenheit geraten. Wenn man aber mal den sauber formatierten Output einer in PostScript übersetzten Manpage sieht, könnte das vielleicht doch ein Ansporn sein, sich ein wenig mit Groff zu beschäftigen.
Ein Beispiel: Mit dem Aufruf
man -t rmdir > rmdir.ps
erzeugt man eine PostScript-Version der Manpage für den Befehl rmdir, die man direkt auf einem PostScript-Drucker ausgeben oder mit einem grafischen PostScript-Betrachter wie gv ansehen kann. Da groff standardmäßig nur sogenannte Level 2-Befehle von PostScript benutzt, können alle gängigen Drucker angesteuert werden. Mit einer Kommandozeilenoption gibt groff nur Level 1-Befehle aus, was die Ansteuerung von Druckern mit Herstelldatum auch vor Anfang der 1990er Jahre ermöglichen kann.
Mit dem Aufruf
man -t 7 regex | ps2pdf - regex.7.pdf
kann unter Zuhilfenahme von ps2pdf aus dem GhostScript-Paket direkt die PDF-Datei einer Manpage erzeugt werden (hier: die Manpage der POSIX Regular Expressions).
Hier eine typische Groff-Datei für das Me-Makropaket, die eine kurze und knappe Befehlsübersicht für den Editor vim darstellt. Zeilen, die nur aus einem Punkt in der ersten Spalte bestehen, werden ignoriert. Leere Zeilen dagegen fügen normalerweise auch in der Ausgabe eine Leerzeile ein.
.\" 9 Punkt Textgröße (Register pp) .nr pp 9 .\" 130% der Textgröße als Zeilenabstand .nr $v 130 .\" 10 Punkt Überschriftengröße (Register sp) .nr sp 10 .\" 16cm lange Zeilen, linker Rand ist default 1" (2.54cm) .ll 16c . .\" Fonts vorbereiten .fp 1 PR \" Palatino Regular .fp 2 PI \" Palatino Italic .fp 3 PB \" Palatino Bold .fp 4 PBI \" Palatino Bold Italic .fp 5 C \" Courier .fp 6 CI \" Courier Italic .fp 7 CB \" Courier Bold .fp 8 CBI \" Courier Bold Italic . .\" Kapitelüberschriften .nr sf 3 \" verwende Font 3 . .\" Kopf- und Fußleiste .nr tf 2 \" verwende Font 2 .nr tp \n(pp \" verwende Schriftgröße aus Register pp .fo ||%|| \" Fußleiste enthält zentriert die Seitenzahl . .\" Worttrennung schön gestalten .hy 14 . . . .\" Kapitel 1 .sh 1 "Vi" .lp \" Absatz . \f2vi\f1 besitzt zwei Modi, einen Kommando- und einen Editmodus. Es gibt mehrere Möglichkeiten, vom Kommando- in den Editmodus zu gelangen, aber nur ein beherzter (mehrfachen) Druck auf die \f2esc\f1-Taste bringt einen wieder zurück in den Kommandomodus. .br \" Zeilenumbruch Wenn man überhaupt nicht mehr weiter weiß, kann \f2vi\f1 durch die Tastenkombination \f7:q!\f1 verlassen werden (ohne abzuspeichern). Manchmal ist das der sicherste Weg, bevor irgendwas strubbelig wird. .lp . .sz -1 \" reduziere Schriftgröße .nf \" schalte Formatierung ab .ta 1.75c \" setze Tabulator .\" Achtung: Es müssen echte Tabs zum Trennen der Felder benutzt werden! \f5dd\f1 Zeile löschen \f5cw\f1 Wort ändern \f5dw\f1 Wort löschen \f5x\f1 Zeichen löschen \f5\&.\f1 Letzten Befehl wiederholen \f5d$\f1 Bis Zeilenende löschen \f5c$\f1 Bis Zeilenende überschreiben \f5u\f1 Undo \f5^r\f1 Redo \f5yy\f1 Ganze Zeile kopieren \f5gg\f1 An den Dateianfang springen \f5G\f1 Zum Dateiende springen . .sp 0.5 \" Füge vertikalen Zwischenraum ein \f5o\f1 Neue Zeile unter Cursor und Insertmode \f5O\f1 Neue Zeile über Cursor und Insertmode \f5r\f1 Replacemode \f5esc\f1 Insertmode verlassen \f5:w\f1 Schreiben \f5:q!\f1 Ohne Sichern beenden \f5:x\f1 Mit Sichern beenden \f5:wq\f1 Mit Sichern beenden \f5:n\f1 Zur nächsten angegebenen Datei springen\** .(f \" starte Fußnote \** Wenn \f2vi\f1 mit mehreren Dateinamen aufgerufen wurde. .)f \" beende Fußnote \f5:N\f1 Zur vorherigen angegebenen Datei springen\** .(f \** Dieser und der vorherige Befehl können analog zu \f2q\f1 mit \f2w\f1 und \f2!\f1 kombiniert werden, damit die veränderte Datei z.\ B. vor dem Wechsel geschrieben wird. .)f \f5:%s///\f1 Regulären Ausdruck wie bei sed über ganze Datei anwenden (%) \f5:%!cmd\f1 Markierung an Shell übergeben \f5:help\f1 Hilfe einblenden \f5:hardcopy\f1 Als PostScript an \f5$PRINTER\f1 schicken . .sp 0.5 \f5v\f1 Wahlfrei zeilenweise markieren \f5V\f1 Ganze Zeile markieren \f5^v\f1 Blockweise markieren \f5y\f1 Markierung kopieren \f5x\f1 Markierung ausschneiden \f5gq\f1 Markierung neu umbrechen (falls Textbreite > 0) \f5p\f1 Einfügen (auch letzte dd-Zeile) .fi \" schalte Formatierung wieder ein .sz \" schalte zurück zur vorigen Schriftgröße .lp . Den meisten Befehlen kann eine Nummer vorangestellt werden, um anzugeben, \f2wie oft\f1 der Befehl wiederholt werden soll. Die Zahl wird beim Tippen nicht angezeigt! .br Eine Zeile am oberen Ende einer Datei, die mit einem beliebigen (Kommentar) Zeichen beginnt, danach den String \(Fcvi:\(Fo und dann Parameter, wird von \f2vi\f1 entsprechend beim Öffnen der Datei interpretiert: .(l \" starte Liste \f5# vi: textwidth=78\f1 .)l \" beende Liste setzt die Textbreite für den automatischen Umbruch auf 78 Zeichen. . .\" Ende
Diesen Text sollte man sich via Zwischenablage auf die lokale Festplatte laden und – bei installiertem Groff und GhostScript – in eine PDF-Datei übersetzen:
groff -me -ma4 vi.me | ps2pdf - vi.pdf
Zu beachten ist, dass groff standardmäßig Eingabe in der Latin-1-Kodierung erwartet. Wird obiger Kode z. B. in UTF-8 abgespeichert, muss man ihn vor dem Aufruff von groff entsprechend mit iconv oder einem ähnlichen Programm konvertieren:
iconv -f utf8 -t latin1 < Eingabedatei > Ausgabedatei
Wenn man sich parallel PDF-Datei und den Quellcode anschaut, bekommt man schnell einen ersten Eindruck von troff und der Benutzung der Me-Makros.
Beispiel: 773 KBytes Fließtext von groff mit dem Makropaket Me nach PDF auf typischer Hardware.
| System | Zeitbedarf |
|---|---|
| PIV/3GHz | 5s |
| Dual PIII/800 | 10s |
| PI/200 | 62s |
| 486DX33 | 570s |
Kürzere Texte sind natürlich dementsprechend schneller übersetzt; das Beispiel ist absichtlich recht umfangreich, um einen aussagekräftigen Vergleich zu erhalten.
groff(1) – Linux-Manpage (englisch)