使用 groff 编写 man 手册

作者:Matt Welsh

在 Unix 系统上发现的最初的文本处理系统中有两个是 troff 和 nroff,它们是在贝尔实验室为 Unix 的最初实现而开发的(事实上,Unix 本身的发展部分原因是为了支持这样的文本处理系统)。这个文本处理器的第一个版本被称为 roff(“runoff”的缩写);后来出现了 troff,它为当时使用的一种特定的排字机生成输出。nroff 是后来的版本,它成为了所有 Unix 系统上的标准文本处理器。groff 是 GNU 对 nroff 和 troff 的实现,在 Linux 系统上使用。它包括几个扩展功能和许多打印设备的驱动程序。

groff 能够生成文档、文章和书籍,与其他文本格式化系统(如 TeX)非常相似。然而,groff(以及最初的 nroff)有一个 TeX 及其变体所没有的内在特性:生成纯 ASCII 输出的能力。虽然其他系统非常适合生成要打印的文档,但 groff 能够生成纯 ASCII,以便在线查看(或直接作为纯文本打印在最简单的打印机上)。如果您要生成既在线查看又以打印形式提供的文档,groff 可能是您的最佳选择(尽管还有其他替代方案,例如 Texinfo、Lametex 和其他工具)。

groff 还具有比 TeX 小得多的优点;它需要的支持文件和可执行文件甚至比最小的 TeX 发行版还要少。

groff 的一个特殊应用是格式化 Unix man 手册页。如果您是 Unix 程序员,您最终需要编写和生成某种 man 手册页。在本文中,我们将通过编写一个简短的 man 手册页来介绍 groff 的使用。

与 TeX 一样,groff 使用特定的文本格式化语言来描述如何处理文本。这种语言比 TeX 等系统略显晦涩,但也更简洁。此外,groff 提供了几个宏包,这些宏包在基本格式化程序之上使用;这些宏包是为特定类型的文档量身定制的。例如,mgs 宏是编写文章和论文的理想选择,而 man 宏用于 man 手册页。

编写 man 手册页

使用 groff 编写 man 手册页实际上非常简单。为了使您的 man 手册页看起来像其他的,您需要在源文件中遵循几个约定,这些约定如下所示。在本例中,我们将为一个名为 coffee 的虚构命令编写一个 man 手册页,该命令以各种方式控制您的联网咖啡机。

使用任何文本编辑器,输入清单 1 中的源代码,并将结果另存为 coffee.man。不要输入每行开头的行号;这些行号仅供本文稍后参考使用。

 1:  .TH COFFEE 1 "23 March 94"
 2:  .SH NAME
 3:  coffee /- Control remote coffee machine
 4:  .SH SYNOPSIS
 5:  /fBcoffee/fP [ -h | -b ] [ -t /fItype/fP ]
 6:  /fIamount/fP
 7:  .SH DESCRIPTION
 8:  /fBcoffee/fP queues a request to the remote
 9:  coffee machine at the device /fB/dev/cf0/fR.
10:  The required /fIamount/fP argument specifies
11:  the number of cups, generally between 0 and
12:  12 on ISO standard coffee machines.
13: .SS Options
14: .TP
15: /fB-h/fP
16: Brew hot coffee. Cold is the default.
17: .TP
18: /fB-b/fP
19: Burn coffee. Especially useful when executing
20: /fBcoffee/fP on behalf of your boss.
21: .TP
22: /fB-t /fItype/fR
23: Specify the type of coffee to brew, where
24: /fItype/fP is one of /fBcolumbian/fP,
25: /fBregular/fP, or /fBdecaf/fP.
26: .SH FILES
27: .TP
28: /fC/dev/cf0/fR
29: The remote coffee machine device
30: .SH "SEE ALSO"
31: milk(5), sugar(5)
32: .SH BUGS
33: May require human intervention if coffee
34: supply is exhausted.

清单 1. man 手册页源文件示例

不要让此源文件中的晦涩程度吓到您。了解字符序列 \fB\fI\fR 用于分别将字体更改为粗体、斜体和罗马字体,这会有所帮助。\fP 将字体设置为先前选择的字体。

其他 groff 请求出现在以点 (.) 开头的行上。在第 1 行,我们看到 .TH 请求用于将 man 手册页的标题设置为 COFFEE,man 节设置为 1,以及上次 man 手册页修订的日期。(回想一下,man 节 1 用于用户命令,节 2 用于系统调用,依此类推。man man 命令详细说明了每个节号。)在第 2 行,.SH 请求用于启动一个名为 NAME 的节。请注意,几乎所有 Unix man 手册页都使用节进展 NAMESYNOPSISDESCRIPTIONFILESSEE ALSONOTESAUTHORBUGS,以及根据需要添加的额外可选节。这只是编写 man 手册页时使用的约定,软件根本没有强制执行。

第 3 行给出了命令的名称和一个简短的描述,在破折号 ([mi]) 之后。您应该对 NAME 节使用此格式,以便可以将您的 man 手册页添加到 man -kapropos 命令使用的 whatis 数据库中。

在第 4-6 行中,我们给出了 coffee 命令语法的概要。请注意,斜体 \fI...\fP 用于表示命令行上的参数,可选参数用方括号括起来。

第 7-12 行简要描述了该命令。粗体通常用于表示程序和文件名。在第 13 行,使用 .SS 请求启动一个名为 Options 的小节。接下来在第 14-25 行是选项列表,使用标记列表呈现。标记列表中的每个项目都用 .TP 请求标记;.TP 之后的行是标记,之后是项目文本本身。例如,第 14-16 行的源代码

.TP
\fB-h\P
Brew hot coffee. Cold is the default.

将在输出中显示为以下内容

-h     Brew hot coffee. Cold is the default.

您应该以这种方式记录程序的每个命令行选项。

第 26-29 行构成了 man 手册页的 FILES 节,该节描述了命令可能用于完成其工作的任何文件。.TP 请求的标记列表也用于此。

在第 30-31 行中,给出了 SEE ALSO 节,其中提供了对其他值得注意的 man 手册页的交叉引用。请注意,第 30 行中 .SH 请求后面的字符串 <\#34>SEE ALSO<\#34> 用引号引起来;这是因为 .SH 使用第一个以空格分隔的参数作为节标题。因此,任何超过一个单词的节标题都需要用引号括起来以构成单个参数。最后,在第 32-34 行中,呈现了 BUGS 节。

格式化和安装 man 手册页

为了格式化此 man 手册页并在屏幕上查看它,您可以使用命令

$ groff -Tascii -man coffee.man | more

-Tascii 选项告诉 groff 生成纯 ASCII 输出;-man 告诉 groff 使用 man 手册页宏集。如果一切顺利,man 手册页应如图 1 所示显示。

COFFEE(1)                                               COFFEE(1)
NAME
       coffee - Control remote coffee machine
SYNOPSIS
       coffee [ -h | -b ] [ -t type ] amount
DESCRIPTION
       coffee  queues  a  request to the remote coffee machine at
       the device /dev/cf0. The required amount  argument  speci-
       fies the number of cups, generally between 0 and 12 on ISO
       standard coffee machines.
   Options
       -h     Brew hot coffee. Cold is the default.
       -b     Burn coffee. Especially useful when executing  cof-
              fee on behalf of your boss.
       -t type
              Specify  the  type of coffee to brew, where type is
              one of columbian, regular, or decaf.
FILES
       /dev/cf0
              The remote coffee machine device
SEE ALSO
       milk(5), sugar(5)
BUGS
       May  require  human  intervention  if  coffee  supply   is
       exhausted.

图 1. 格式化的 man 手册页

如前所述,groff 能够生成其他类型的输出。使用 -Tps 选项代替 -Tascii 将生成 PostScript 输出,您可以将其保存到文件、使用 GhostView 查看或在 PostScript 打印机上打印。-Tdvi 将生成设备无关的 .dvi 输出,类似于 TeX 生成的输出。

如果您希望 man 手册页可供系统上的其他人查看,则需要将 groff 源安装在其他用户的 MANPATH 中存在的目录中。标准 man 手册页的位置是 /usr/man。因此,第 1 节 man 手册页的源应放在 /usr/man/man1 中。因此,命令

$ cp coffee.man /usr/man/man1/coffee.1

将把此 man 手册页安装在 /usr/man 中供所有人使用(请注意使用 .1 文件扩展名,而不是 .man)。当随后调用 man coffee 时,man 手册页将自动重新格式化,并且可查看的文本将保存在 /usr/man/cat1/coffee.1.Z 中。

如果您无法直接将 man 手册页源复制到 /usr/man(例如,因为您不是系统管理员),您可以创建自己的 man 手册页目录树并将其添加到您的 MANPATH 中。MANPATH 环境变量的格式与 PATH 相同;例如,要将目录 /home/mdw/man 添加到 MANPATH,只需使用

$ export MANPATH=/home/mdw/man:$MANPATH

groff 和 man 手册页宏还有许多其他选项和格式化命令可用。了解这些命令的最佳方法是查看 /usr/lib/groff 中的文件;tmac 目录包含宏文件本身,这些文件通常包含有关它们提供的命令的一些文档。要将特定的宏集与 groff 一起使用,只需使用 -m 选项。例如,要使用 mgs 宏,请使用

groff -Tascii -mgs files...

groff 的 man 手册页更详细地描述了这个选项。

不幸的是,groff 提供的宏集没有很好的文档记录。其中一些宏集有第 7 节 man 手册页;例如,man 7 groff_mm 将告诉您有关 mm 宏集的信息。但是,此文档通常仅涵盖 groff 实现中的差异和新功能,这假设您可以访问原始 nroff/troff 宏集(称为 DWB—文档编写者工作台)的 man 手册页。最好的信息来源可能是一本关于使用 nroff/troff 的书,其中详细介绍了这些经典宏集。有关编写 man 手册页的更多信息,您可以随时查看 man 手册页源(在 /usr/man 中)并通过比较格式化输出和源代码来确定它们的作用。

本文改编自 Matt Welsh 和 Lar Kaufman 合著的 Running Linux,由 O'Reilly and Associates 出版(ISBN 1-56592-100-3)。除其他外,本书还包括 Linux 下使用的各种文本格式化系统的教程。本期 Linux Journal 以及 Running Linux 中的信息应该为使用该系统的许多文本工具提供良好的开端。

祝您好运,文档编写愉快!

Matt Welsh (mdw@cs.cornell.edu) 是康奈尔大学的学生和系统程序员,在机器人与视觉实验室从事实时机器视觉项目。

加载 Disqus 评论