Update 2019-05-26: While having some familarity with roff is useful, since the time of originally have discovered Pandoc which can convert between many document formats, such as from markdown to roff. Writing documentation in markdown is just hard to beat.

As the first text formatting program built for UNIX in 1970 running on a PDP-7, roff was a port of the BCPL program RUNOFF.

Over the years roff has evolved into troff and the excellent GNU version groff. Similar to other formatting systems, such as LaTeX, groff features a macro system, targetted at authoring certain types of text documents. In spite of its old age, roff is still in wide spread use today, for producing text such as UNIX manual pages, software books, system documentation and standards documents.

Compared to other text formatting systems, such as TeX, groff has a much smaller footprint (a complete LaTeX install can require several GB’s), and my favourite feature is that plain-text output is treated as a first class citizen (such as a man pages). Also just like TeX, groff can do looseless output formats such as postscript and PDF.

  • ms macros (man groff_ms) are suited to creating reports, letters and books.
  • man macros (man groff_man) will craft man pages.
  • tmac
  • mdoc
  • me
  • mm
  • mmse
  • mom
  • www

Installation

Depending on your distro, there’s a good chance a working groff system is already setup. On this Ubuntu 18 box I needed a:

sudo apt install groff groff-base

A tidy looking document (the ms macro set)

To get started, will take the ms macro set for a spin. Create a new text file test.ms:

.TL
My first groff document
.AU
Ben Simmonds
.AI
University of NSW
.AB \"abstract start
This is an abstract.
.AE \"abstract end
.NH
Introduction
.PP
This is a paragraph.
.PP
And another paragraph.
.NH
Background
.NH 2
The why
.PP
Some more text, this is 
.B "bold"
ta da, and this
.I "italic"
boom.

The document has a title (TL), author (AU), institution (AI) and paragraph (PP).

Time to compile it:

$ groff -ms test.ms

By default groff will dump postscript to stdout:

%!PS-Adobe-3.0
%%Creator: groff version 1.22.3
%%CreationDate: Fri Mar 15 02:39:20 2019
%%DocumentNeededResources: font Times-Bold
%%+ font Times-Italic
%%+ font Times-Roman
...

This could be redirected into a ps file, or alternatively groff can just produce a PDF with the -T option:

$ groff -ms groff.ms -T pdf > groff.pdf

Sample document in a PDF viewer:

groff pdf output

A humble man page (the man macro set)

While there is some similarity to using the ms macro as in the document example above, the man macro set does introduce some specific character sequences. Check man groff_man to get an awesome cheat sheet.

Here’s an old example (from 1995), source https://www.linuxjournal.com/article/1158:

.TH COFFEE 1 "23 March 94"
.SH NAME
coffee \- Control remote coffee machine
.SH SYNOPSIS
\fBcoffee\fP [ -h | -b ] [ -t \fItype\fP ]
\fIamount\fP
.SH DESCRIPTION
\fBcoffee\fP queues a request to the remote
coffee machine at the device \fB/dev/cf0\fR.
The required \fIamount\fP argument specifies
the number of cups, generally between 0 and
12 on ISO standard coffee machines.
.SS Options
.TP
\fB-h\fP
Brew hot coffee. Cold is the default.
.TP
\fB-b\fP
Burn coffee. Especially useful when executing
\fBcoffee\fP on behalf of your boss.
.TP
\fB-t \fItype\fR
Specify the type of coffee to brew, where
\fItype\fP is one of \fBcolumbian\fP,
\fBregular\fP, or \fBdecaf\fP.
.SH FILES
.TP
/fC/dev/cf0\fR
The remote coffee machine device
.SH "SEE ALSO"
milk(5), sugar(5)
.SH BUGS
May require human intervention if coffee
supply is exhausted.

The groff_man man page is the best resource, but a quick breakdown:

  • .TH sets the main title of the man page
  • .SH defines a level 1 section header. A convention for man pages is to provide the sections NAME, SYNOPSIS, DESCRIPTION, FILES, SEE ALSO, NOTES, AUTHOR, and BUGS, with extra sections as needed.
  • .SS defines a subsection
  • .TP is used to define a tagged list, and is used to enumerate the available command line options. The line immediately after .TP is the tag.
  • \fB, \fI and \fR set bold, italic and roman type.
  • \fP returns the font to its previous mode

To compile, run groff with the ascii type and set the man macro set like so:

$ groff -Tascii -man coffee.man | less

You should see a neatly formatted man page (the following does not include the bold and italic font settings):

COFFEE(1)                   General Commands Manual                  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 specifies 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 coffee on behalf
              of your boss.

       -t type
              Specify the type of  coffee  to  brew,  where  type  is  one  of
              columbian, regular, or decaf.

FILES
       /fC/dev/cf0
              The remote coffee machine device

SEE ALSO
       milk(5), sugar(5)

BUGS
       May require human intervention if coffee supply is exhausted.



                              23 March 94                        COFFEE(1)

Next, to install the freshly baked manual into the system man page store.

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

Rebuild the man pages index:

$ sudo mandb

The man page can now be viewed as one would expect:

$ man coffee

Also, the new coffee man page should be searchable by tools like apropos:

$ apropos coff
coffee (1)           - Control remote coffee machine