What's GNU

This month's column discusses groff, the GNU version of troff.

This month's column discusses groff, the GNU version of troff. Explaining troff in full detail can (and has!) taken more than one book. For now, we'll provide a little bit of history and an overview of what groff is, what the input tends to look like, and how you would use it.

by Arnold Robbins

What is troff?

While there are many WYSIWYG word processing programs out there, some of which are quite powerful, and others which are usable and freely available, many long time “power users” still prefer text formatters like troff and TeX for the control they give you. Another advantage that these programs have is that you can edit the input using any text editor, even ed or vi over a 2400 baud modem connection, or on a laptop system that can't support X windows.

nroff and troff are the Unix text formatters. They are essentially twins; each accepts the same input “language”. The difference is in the output they produce. nroff was designed to produce output for devices with fixed-width and fixed-size characters, such as terminals and line printers. troff was designed for photo-typesetters. nroff simply ignores requests that it cannot honor. From now on, we will follow the time-honored convention of referring to both programs as troff, to make things simpler.

troff was written at Bell Laboratories by the late Joseph Osanna. It was modeled after the text formatters of the time, notably one named runoff. (runoff was written by Jerry Saltzer for the CTSS system at MIT, running on a modified IBM 7094, in the middle 1960's time frame.) Interestingly enough, nroff was written first; the name stood for “new runoff”. Later, when the research group acquired a photo-typesetter, nroff was enhanced to deal with the newly acquired capabilities, and thus troff was born. In the early 1980's, after the death of Mr. Osanna, Brian Kernighan took over troff, cleaned it up and enhanced it. The troff language is now frozen. It will not evolve further.

troff's Capabilities

Input to troff is a mixture of text and formatting commands. You might think of this as “what you want to say” and “how you want to say it.” Typically, commands are on separate lines by themselves. troff is able to distinguish commands from text, since command lines begin with a dot, or period. Special tricks have to be used to get troff to treat a line that begins with a dot as real text.

There are a large number of commands in troff. Some of the more important commands are for the following tasks:

  • Filling. This means putting as many words of input text on one output line as possible.

  • Adjusting. This means padding lines with blanks so that the margins on both sides are even. Book and magazine text is typically both filled and adjusted.

  • Font changes. Printed text is often in multiple fonts. Italics are often used for emphasis. Bold text is used for strong emphasis and for headings. troff supports at least four fonts normally, with the ability to easily add others.

  • Size changes. Photo-typesetters give you the ability to print characters at different sizes. Most text is set in 10-point type, where one point is 1/72 of an inch. Text can be made smaller or larger as needed. For example, footnotes are often set in a smaller point size than normal text.

  • Margin control. troff gives you separate commands to control the size of all four margins on the piece of paper. This is typically done using a combination of the

    • - line length, how many characters or inches of text that can be in a line

    • - the page offset, how far to the right to shift the entire line, and

    • - the indentation, how far left or right from the beginning of the line to actually place text. E.g., in a book, the first line of a paragraph is often indented 1/2 an inch.

  • Centering. Any number of input lines can be centered in the output text.

  • Line drawing. troff can draw horizontal, and vertical lines, as well as arbitrary curves.

  • Horizontal and Vertical Motions. You can move text up or down an arbitrary amount. Consider subscripts and superscripts in mathematical formulae, or footnotes indicators, which are often one half a line up and in a smaller point size.

You can add comments to your troff source. They begin with \" and continue to the end of the line. We will be using comments in our examples, to help explain what is going on.

Many of the facilities can be done both as standalone commands, and with in-line escape sequences. For example, to change to a bold font, one might have text like this:

        Here is some regular text.
        .ft B  \" now switch to bold
        This is bold.
        .ft    \" switch back to earlier font
        This will be regular again.

You can do the same thing with in-line escape sequences. For font changes, you use \f and either a single letter font name, or a ( and a two letter font name. A similar example would be:

        Here is some regular text. \fBThis is bold.\fP This will
        be regular again.

The letter P is special. It means to use the previous font.

troff provides two nice features, strings and number registers. A string is a shorthand for some text. For example, if you don't want to type the Linux Operating System over and over again, you could define a string LX, and then use the string in your text. This feature can save a lot of typing.

        .ds LX the Linux Operating System \" ds means define string
        If you are new to \*(LX, then you should subscribe to
        \fILinux Journal\fP. It covers \*(LX in great detail,
        month after month.

Number registers are like variables in programming languages. They can contain numeric values. They can also be used in an “auto-increment” and “auto-decrement” fashion. This means that with each use, the value goes up by one or down by one. Why would you need such a thing? Think about automatically numbering chapters, sections, and subsections, as well as figures and footnotes. You would have a register for the chapter number, another for the section number, and so on. With each new chapter, the section register is reset to one. With each new section, the subsection register is also reset to one, and so on.