ROFF(7)

名称
roff - roff の清書のコンセプトと歴史

解説
roff とは清書プログラム群の一般名称です。 troff, nroff, ditroff, groff などの名前で知られています。 roff 清書システムは、拡張可能なフォーマット用言語と、 印刷および他のテキスト書式への変換のための一連のプログラムからなります。 伝統的には、これが Unix の主たるテキスト処理システムでした。 すべての Unix 的なオペレーティングシステムは、 いまだに roff システムをコアパッケージとして配布しています。

今日、最も一般的な roff システムはフリーソフトウェアでの 実装である GNU roff, groff(1) です。 groff です。 groff より前の実装は 古典 (1973 年まで遡ります) と呼ぶことにします。 groff は、古典である先祖の見た目や使用感および機能を実装していますが、 多くの拡張を持ちます。 groff ほとんどすべての計算機システムで利用できるため、今日では事実上の roff 標準となっています。

古い Unix システムでは、 Multics オペレーティングシステムのもっと古い runoff を実装した、 roff と呼ばれるバイナリを持つものがありました。 歴史 節を参照してください。 このプログラムの機能は、古代の troff と比べてさえ限定されたものでした。 これはもうサポートされていません。 この結果、この文書では、 roff という術語は常に roff システム 一般を指し、古代の roff バイナリを指しません。

その古さにもかかわらず、roff は今日でも広く使用されています。 例えば、UNIX システムのマニュアルページ (manページ) や多くのソフトウェア書籍、システム文書、標準、企業の文書は roff で書かれています。 テキストデバイスに対する roff 出力は、いまだに並ぶもののないほど優れて います。グラフィカルな出力も他のフリーの清書プログラムと同等の品質を 持っていますし、ものによっては商用システムのものよりも優れているときも あります。

roff のもっとも有名なアプリケーションは マニュアルページ または単に man ページ と呼ばれるものです。 これは、多くのオペレーティングシステムにおいて、 標準の文書化システムです。

この文書は、 roff システム の開発にまつわる歴史的な事実、 すべての roff バージョンに共通な使用側面や通常は groff(1) のようなフロントエンドに隠されてしまうような roff パイプラインの詳細、 このフォーマット言語の一般概要、roff ファイル編集のこつ、 さらなる参考資料へのポインタを記述します。

歴史
roff テキスト処理システムは、非常に長い歴史を持ち、1960 年代まで遡ります。 roff システム自身 Unix オペレーティングシステムと密に繋っていますが、 その根源はより昔のオペレーティングシステムである CTSS および Multics です。

  runoff の先祖

roff の進化はオペレーティングシステムの歴史に密にかかわっています。 その先祖である runoff は、 Jerry Saltzer によって CTSS (Compatible Time Sharing System) オペレーティングシステム上で書かれました。 1961 年という早い時期です。 1963 年から CTSS が更に開発され、 Unix の有名な先祖であるオペレーティングシステム になるとき、 runoff は文書テキスト処理の主たる書式になりました。 両オペレーティングシステムは当時非常に高価な計算機上でのみ動作したので、 それらは研究分野や政府や軍事の目的で主に使用されていました。

現代の roff に比べ、 runoff 言語の可能性は非常に限られていました。 1960 年代には、テキスト出力のみが可能でした。 これは、長さ 2 のリクエストの集合により実装可能でした。 その多くは、roff でも同じく使用されています。 この言語は、計算機世代以前の清書習慣に従ってモデル化されたものでした。 原稿中のドットで開始する行は、 後で手動で清書を行う人に対する清書の指示を表していたのです。

runoff プログラムは、最初に PL/1 言語で記述され、後に C プログラム言語の祖母である BCPL で記述されました。 Multics オペレーティングシステムでは、 ヘルプシステムが runoff で扱われていました。 これは、roff が Unix マニュアルページを扱う仕事と似ています。 runoff 言語で書かれた文書は、現存します。 例えば Saltzer のホームページを見てください。 関連項目 の節を参照してください。

  古典的な nroff/troff システム
1970 年代には、Multics の子 Unix の人気がどんどんでてきました。 これは、購入可能なマシン上で動作することと、 当時大学ではより簡単に入手可能であったためです。 MIT (the Massachusetts Institute of Technology) では、 Unix を実行する PDP-11 計算機からのグラフィックス出力デバイスである、 Wang Graphic Systems CAT 清書機を動かす必要がありました。 runoff の機能はこの目的には足りなかったので、 Josef F. Osanna の手により更に強力なテキストフォーマットシステムへと開発されました。 彼は、Multics オペレーティングシステムの主たる開発者であり、 いくつかの runoff ポートのプログラマでもあります。

runoff という名前は roff に縮められました。 Osanna のコンセプトである非常に拡大された言語は、既に完全な roff システム のすべての要素を含んでいました。 すべての現代的な roff システムは、 このシステムとの互換性を実装しようとしています。 そのため、Joe Osanna は roff システムの父とも呼べるのです。

この最初の roff システム は 3 個のフォーマットプログラムを持っていました。

troff
    (植字機 roff) は、唯一のデバイスとして CAT 植字機用のグラフィカル出力を生成しました。

nroff
    は、端末および行プリンタに適したテキスト出力を生成しました。

roff
    は、以前の runoff プログラムの再実装でしたが、機能は限定されていました。 このプログラムは後のバージョンで捨てられました。 今日では、 roff という名前は、troff/nroff システム全体を指すために使用されます。

Osanna の最初のバージョンは PDP-11 アセンブリ言語で記述され、 1973 年にリリースされました。 Brian Kernighan が、これを C プログラミング言語で書き直すことで、 roff 開発に加わりました。 C バージョンは 1975 年にリリースされました。

フォーマット言語 nroff/troff プログラムは、著名な Troff User's Manual [CSTR #54] に記述されています。 これは、1976 年に最初に出版され、 1992 年まで Brian Kernighan によって改訂され続けました。 この文書は 古典 troff の仕様書です。 後のすべての roff システムは、この仕様との互換性を確立しようと試みました。

1977 年に約 50 歳にて Osanna が心臓発作で死去した後は、 Kernighan が troff の開発を続けました。 次のマイルストーンは、 より多くのデバイスと中間出力言語と後処理システムのサポートのために、 一般的なインタフェースを troff に備えることでした。 これは今日でも使用されていますので、これにより、 roff システム の構造が完成しました。 ROFF の使い方 の節を参照してください。 1979 年には、これらの斬新なシステムが論文 [CSTR #97] に記述されました。 この新しい troff バージョンは、 groff を含む既存するすべてのより新しい troff システムの基礎となりました。 システムによっては、この デバイス独立 troff だけで、 ditroff(7) と呼ばれるバイナリを持つものもあります。 すべての現代的な troff プログラムは、既に、完全な ditroff 機能を自動的に提供します。

  商用化
簡単に入手可能な Unix 7 オペレーティングシステムが商用化されたときに、 大きな退化が発生しました。 分岐したオペレーティングシステムが大量発生し、 互いに非互換な拡張をめぐって争いました。 幸運なことに、これらの非互換性は、元の troff とは争いませんでした。 すべての商用 roff システムは、 Osanna/Kernighan のオープンソースコードと文書を多用しましたが、 それらに些細な追加をしただけで “彼等” のシステムとして販売しました。

古代 Unix と古典 troff のソースコードは、20 年もの間利用不可能でした。 幸運なことに、2001 年に Caldera が SCO UNIX を購入しました。 そして Caldera は、古代のソースコードに対する、 非商用目的でのオンラインアクセスを可能にしました。 関連項目 を参照してください。

  フリーの roff
商用 roff システムのいずれも、 一般的な roff 開発の後継者の地位を獲得できませんでした。 誰もが各々の物にだけ興味があったのです。 これは 1980 年代に、 一度は素晴しかった Unix オペレーティングシステムの急降下に繋がります。

急速に突き進む商用化への対抗策として、 AT&T Bell Labs は、彼等の Plan 9 オペレーティングシステムで救援プロジェクトを立ち上げようとしました。 これは非商用にはソースコードですら自由に利用可能でしたが、 プロプラエタリなライセンスがあって、自由な開発を阻害していたのです。 このコンセプトは時代遅れであったので、 メインストリームの開発をまとめるプラットフォームとしては Plan 9 は受け入れられませんでした。

唯一の救済は、立ち上がりつつあったフリーのオペレーティングシステム (386BSD, GNU/Linux 等) やソフトウェアプロジェクトによるもので、 それは 1980 年代および 1990 年代のことです。 これらは古代 Unix の機能と多くの拡張を実装していましたので、 古い経験は失われなかったのです。 21 世紀には、Unix 的なシステムは、再度、 計算機産業におけるメジャーな要因になりました — フリーソフトウェアのおかげで。

最重要なフリー roff プロジェクトは troff の GNU ポートです。 James Clark によって作成され、 にされました。 これは groff (GNU roff) と呼ばれます。 概要は groff(1) を参照してください。

groff システムは、依然として活発に開発されています。 これは古典 troff と互換ですが、多くの拡張が追加されています。 ほとんどすべての計算機システムで利用できる、 はじめての roff システムです — しかもフリーです。 このため、今日では groff が事実上の roff 標準となっています。

ROFF の使い方
ほとんどの人々は、実際に roff を使っていることにさえ気付かないでしょう。 システムマニュアルページ (man ページ) を読むときには、 roff がバックグラウンドで動作しているのです。 roff 文書は、生粋のビューアである xditview(1x) で閲覧可能です。 これは、X ウィンドウ配布物の標準プログラムです。 X(7x) を参照してください。 明示的に roff を使うのもまた難しくはありません。

roff の実装によっては、ラッパプログラムがあり、 シェルのコマンドラインから roff システムを簡単に使えるようにしています。 例えば、GNU roff 実装では、次のようになっています。 古典 troff の長いコマンドパイプを避けるためのコマンドラインオプションを 与えるために、 groff(1) が提供されています。 grog(1) プログラムは、文書をもとに、groff を起動するための引数を推測します。 コマンドラインオプションを指定したくない方は、 groffer(1) プログラムを試すと良いでしょう。 こちらは、groff ファイルと man ページをグラフィカルに表示するためのものです。

  roff パイプ
各 roff システムは、プリプロセッサ、roff フォーマットプログラム、 一組のデバイスポストプロセッサ群からなります。 このコンセプトは、 パイプライン 機構を多用します。 それはすなわち、一連のプログラムが次々と呼ばれ、そこでは、 行列上の各プログラムの出力が次のプログラムの入力となるというものです。

プリプロセッサは roff コードを生成し、これは roff フォーマッタ (例えば troff) に与えられます。 次に、roff フォーマッタが、 中間出力 を生成し、これがデバイスポストプロセッサプログラムに与えられて 印刷や最終出力に使用されます。

これらの部分すべてが、各自のプログラム言語を使用します。 各言語は、他の部分とは完全に独立です。 更に、特殊用途向けの roff マクロパッケージも含めることが可能です。

ほとんどの roff 文書は、なにがしかのパッケージのマクロを使用し、 それらをプリプロセッサのコードと混ぜて使い、 それらに素の roff 言語の要素で味付けします。 roff フォーマット言語の完全な力は、ユーザはほとんどの場合必要としません。 マクロパッケージのプログラマだけが、そのすさまじい詳細を知る必要があるのです。

  プリプロセッサ
roff プリプロセッサは、 roff フォーマット言語に構文的に従う出力を生成する、任意のプログラムです。 各プリプロセッサは、 このプリプロセッサを通すと、roff コードに変換されるような、 自分自身の言語を定義します。 このような言語で記述された部分は、roff 文書に埋め込めます。 このような部分は、特殊な roff リクエストやマクロで識別されます。 プリプロセッサコードで拡張された文書は、 対応するすべてのプリプロセッサを通してから、 実際の roff フォーマットプログラムに通す必要があります。 これにより、フォーマッタが、外部コードを単に無視できるようになります。 プリプロセッサプログラムは、文書のうち、 自分自身のものと判断した部分のみを抽出して変換します。

フリーおよび商用の roff プリプロセッサが多数あります。 すべてのシステムで利用できるわけではないものものありますが、 プリプロセッサのほんの小さな集合は、 roff システムの一部とみなされます。 古典的なプリプロセッサは次の通りです。

    tbl 表のためのものです。 eqn 数式のためのものです。 pic 図の描画のためのものです。 refer 参考文献の参照用です。 soelim 標準の場所からマクロファイルをインクルードするためのものです。

すべてのシステムで使用可能ではありませんが、 他の有名なプリプロセッサは次の通りです。

    chem 化学式の描画のためのものです。 grap グラフィカル要素を構築するためのものです。 grn gremlin(1) 図を埋め込むためのものです。

  フォーマットプログラム
roff フォーマッタ は、roff フォーマット言語で記述された文書 または roff マクロパッケージを使用する文書を、構文解析します。 生成される 中間出力 は、フォーマットプログラムのコマンドラインオプションで指定されている、 単一のデバイスポストプロセッサに与えられることを意図しています。 文書は、必要なすべてのプリプロセッサに事前に通されていることが必要です。

roff フォーマッタが生成する出力は、もうひとつの言語、すなわち 中間出力書式 や troff 出力 と呼ばれるもので表現されます。 この言語は、最初に [CSTR #97] で仕様が記述されました。 この GNU 拡張が groff_out5 に記述されています。 中間出力言語は、高位の roff 言語に対する、アセンブリ言語のようなものです。 生成された中間出力はある特殊デバイス用に最適化されたものですが、 言語はすべてのデバイスに共通です。

roff 生成器は、roff システムの心臓です。 典型的な roff は、2 個の生成器、すなわちテキストデバイス用の nroff と、グラフィカルデバイス用の troff を持っています。

しばしば、 troff という名前が、両方の生成器を指す一般術語として使用されます。

  デバイスとポストプロセッサ
デバイスとは、プリンタやテキスト端末やグラフィカル端末といった ハードウェアインタフェースや、別のテキスト形式やグラフィカル形式への 変換のソフトウェアインタフェースです。

roff ポストプロセッサは、troff 出力を、 特殊デバイスに適した形式に変換するプログラムです。 roff ポストプロセッサは、出力対象に対するデバイスドライバのようなものです。

各デバイスに対し、 そのデバイスに最適化されたポストプロセッサプログラムがあります。 ポストプロセッサは、生成された中間出力を構文解析し、 デバイスに直接送られるデバイス固有コードを生成します。

デバイスおよびポストプロセッサの名前は固定ではありません。 なぜなら、これらは一般的に、実際の計算機のソフトウェアおよびハードウェアの 能力に依存するからです。 例えば、 [CSTR #54] で述べられている古典的なデバイスは、 古典的な時代から大部変わってしまいました。 古いハードウェアはもはや存在しませんし、 古いグラフィカル変換器は、現在使えるものと比較すると、非常に不正確です。

例えば、古典的な troff における Postscript デバイス post は解像度 720 でしたが、groff の ps デバイスは 72000 であり、100 倍の改善がなされています。

今日では、プリンタのようなほとんどのデバイスに対しては オペレーティングシステムがデバイスドライバを提供しますので、 それぞれのプリンタに対して特殊なハードウェアポストプロセッサを記述する 必要はありません。

ROFF プログラム
roff を使用した文書は、普通のテキストファイルを roff のフォーマット用 要素で修飾したものです。 roff フォーマット言語は非常に強力です。 ほぼ完全なプログラミング言語であり、言語を拡張する要素を提供します。 これらを使用することで、特殊な応用に適したマクロパッケージを開発する ことが可能です。 このようなマクロパッケージは、素の roff よりも簡単に扱えます。 ほとんどの人々はマクロパッケージを選択することで、 roff 言語の内部について気にしなくても良くなっています。

  マクロパッケージ
マクロパッケージは、ある特殊な種類の文書を簡便な方法で フォーマットするのに適したマクロの集合です。 マクロパッケージによって、roff の使い勝手が格段に良くなります。 パッケージのマクロ定義は、 name.tmac (または tmac.name ) と呼ばれるファイルに保管されています。 すべての tmac ファイルは、 1 つまたはそれ以上のディレクトリ中の標準の場所に保管されています。 マクロパッケージの命名およびその置き場所についての一般的な詳細は groff_tmac(5) にあります。

文書が使用するマクロパッケージは、 troff(1) にあるようにフォーマッタのコマンドラインオプション で宣言することもできますし、 groff(7) にあるように文書中で roff 言語のファイルインクルードリクエストで 指定可能です。

有名な古典的マクロパッケージとしては、典型的なマニュアルページ用の man や、BSD スタイルのマニュアルページ用の mdoc や、書籍・記事・手紙用の me (おそらく、作成者 Eric Allman のファーストネームから来ています) や、 ms (Manuscript Macros から来ています) や mm (Memorandum Macros から来ています) があります。

  roff フォーマット言語
古典的な roff フォーマト言語は Troff User's Manual [CSTR #54] に記述されています。 roff 言語はリクエスト、マクロ定義、エスケープシーケンス、 文字列変数、数値レジスタまたはサイズレジスタ、そして 制御構造を提供する完全なプログラミング言語です。

リクエスト は、シェルプロンプトにおけるコマンドのような、 定義された基本的なフォーマット用コマンドです。 ユーザは、定義済の roff 要素を使用して、 リクエストのような要素を定義可能です。 これらは、 マクロ と呼ばれます。 文書の著者は、リクエストとマクロを使う際の違いに 気づくことはないでしょう。どちらもドット 始まりの単独行で記述されます。

エスケープシーケンス は、roff の要素であり、バックスラッシュ で始まります。 どこにでも挿入することができ、 それは行のテキストのまんなかであっても構いません。 これらはさまざまな機能を実装するのに 使われます。 それには、 を用いた非 ASCII 文字の挿入、 を用いたフォントの変更、 を用いた文中のコメント、 のような特殊な制御文字のエスケープ、 その他多くの機能が含まれます

文字列 は文字列を格納可能な変数です。 文字列は、 .ds リクエストで格納可能です。 格納された文字列は、後で \* エスケープシーケンスを使用することで取り出せます。

レジスタ は数値やサイズを格納します。 レジスタは、 .nr リクエストで設定可能であり、その値は \n エスケープシーケンスで取り出せます。

ファイル名の拡張子
マニュアルページ (man ページ) はファイル名の拡張子として セクション番号をとります。例えば、この文書のファイル名は roff.7 です。つまり、この文書はマニュアルページの セクション 7

古典的なマクロパッケージは、パッケージ名を拡張子にとります。 me マクロパッケージを使った文書は file.me となり、 mm マクロパッケージに対しては file.mm 、 ms マクロパッケージに対しては file.ms 、 pic ファイルに対しては file.pic といった具合です。

roff 文書の一般的な命名方式はありませんが、時々 troff ファイル 用に file.tr が使われているのが見受けられます。 roff ファイル用に標準のファイル名拡張子が必要なのかもしれません。

ファイル名拡張子は、 less(1) ページャと組み合わせると、非常に便利なことがあります。 これにより、シェル環境変数で指定されるコマンドラインパイプ LESSOPEN へすべての入力を与えることが可能となります。 この処理はうまく書けませんので、例を書いておきます: ここで lesspipe は、システムが提供するコマンドやあなたが書いたシェルスクリプトです。

ROFF の編集
roff 文書を編集するための最良のプログラムは Emacs (または Xemacs) です。 emacs(1) を参照してください。 これは、あらゆる roff 方言に適した nroff モードを提供します。 このモードは、次の方法で有効にできます。

Emacs でファイルを編集しているときには、 `M-x nroff-mode' とタイプすることでモードを変えられます。 ここで、 M-x は Meta キー (または Alt) を押したままで同時に x キーを押すことを意味します。

ファイルをエディタにロードしたときに自動的にモードを選択するようにする ことも可能です。 もっとも一般的な方法は、次の 3 個のコメント行を、ファイルの最後に 含めることです。
.\" Local Variables:
.\" mode: nroff
.\" End:
例えば man ページのような、あるファイル名拡張子の集合は、 nroff モードを自動的に有効にします。 理論上は、ファイルの最初の行として .\" -*- nroff -*- を書いておくことで、ロード時に nroff モードを開始可能です。 不幸なことに、これで混乱してしまう man プログラムのようなアプリケーションがありますので、 この方法は価値が低下しています。

すべての roff 整形器は、自動化された改行と水平および垂直の間隔調整を 提供します。 これを邪魔しないようにするには、次のこつが役立つでしょう。 roff 文書に、空の行や空行を入れないでください。 構造的な要素が必要な場合には、代りに、 空のリクエスト (ドットのみからなる行) や、行コメント .\" を使ってください。 予期せぬ動作になるので、行を空白で開始しないでください。 インデントされた段落は、roff リクエストで制御された方法で構築可能です。 各文をそれ自身の独立した行で開始することによって、 ドットが略語を終端するのか文を終端するのかによって、 ドットの後の空間を調整します。 両者を区別するために、各文の後で、改行してください。 更に、Emacs でオートフィルモードを使用するには、各文の後に、 空の roff リクエスト (ドットのみの行) を入れるのが最良です。

次の例は、最適な roff 編集がどのように見えるかを示しています。

    This is an example for a roff document.
    This is the next sentence in the same paragraph.
    This is a longer sentence stretching over several
    lines; abbreviations like `cf.' are easily
    identified because the dot is not followed by a
    line break.
    In the output, this will still go to the same
    paragraph.

Emacs 以外にも、nroff スタイルファイルを提供するものがあります。 例えば、 vi(1) の拡張である vim(1) がそうです。

バグ
UNIX® は、Open Group の登録商標です。 Caldera が SCO UNIX を 2001 年に買収して以来、事態はずいぶん良く なりました。

関連項目
roff 関連の文書は沢山あります。 古典的な troff に関するオリジナルの論文は、まだ入手可能であり、 groff のすべての側面について非常に細かいことまで記述されています。

  インターネットサイト

troff.org
    には、roff のすべての歴史的な側面に関する概要とポインタがあります。

Multics
    には、MIT プロジェクト、CTSS や Multics や初期の Unix や runoff の多くの情報があります。 用語解説や古代文書への多くのリンクが、特に有用でしょう。

Unix Archive
    には、Caldera が 2001 年以来パブリックにした古代 Unix のソースコードや バイナリ (troff のソースコードとその文書を含む) があります。 例えば、著名な Unix version 7 for PDP-11 は にあります。

Developers at AT&T Bell Labs
    には、初期の開発者の情報を追跡するための、検索機能があります。

AT&T Bell Labs による Plan 9
    です。

runoff
    には、古代の runoff 整形言語を使用した文書があります。

CSTR の論文
    には、オリジナルの troff マニュアル (CSTR #54, #97, #114, #116, #122) と有名な歴史的なプログラミング文書があります。

GNU roff
    には、実際の標準 roff である、フリー roff 実装の groff があります。

  歴史的な roff 文書
多くの古典的な 文書が、まだオンラインで入手可能です。 troff 言語の主要な 2 冊のマニュアルは次の通りです。

[CSTR #54]
    J. F. Osanna, Bell Labs, 1976; revised by Brian Kernighan, 1992.

[CSTR #97]
    Brian Kernighan, Bell Labs, 1981, revised March 1982.

「小言語」の roff 論文は次の通りです。

[CSTR #114]
    Jon L. Bentley and Brian W. Kernighan, Bell Labs, August 1984.

[CSTR #116]
    Brian W. Kernighan, Bell Labs, December 1984.

[CSTR #122]
    J. L. Bentley, L. W. Jelinski, and B. W. Kernighan, Bell Labs, April 1986.

  マニュアルページ
構造が複雑であるため、完全な roff システムには、複数の man ページが 含まれ、それぞれが roff のあるひとつの側面を記述しています。 不幸なことに、異なった roff 実装間でも一般的となる、 文書の命名方法はありません。

groff では、man ページ groff1 に、groff で利用可能なすべての文書の概観が含まれます。

他のシステムでは、おまかせしますが、 troff(1) から始めると良いかもしれません。

作者
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.

この文書は FDL (GNU Free Documentation License) バージョン 1.1 以降の条項のもとに配布されています。 FDL のコピーをシステム上に持っているはずです。 また、これはオンライン でも入手可能です。

このドキュメントは groff すなわち GNU roff 配布物の一部です。 が書き、 が管理しています。