Est. 1973 Advanced

troff

troff is the classic Unix typesetting language, created at Bell Labs in the 1970s to drive phototypesetters and still used today — via GNU groff — to format Unix manual pages.

Created by Joe Ossanna (Bell Labs); later rewritten for device independence by Brian Kernighan

Paradigm Markup; procedural macro-based text formatting
Typing Untyped
First Appeared 1973
Latest Version No language standard; the dominant implementation is GNU troff (groff) 1.23.0 (2023)

troff — short for “typesetter roff” — is the classic Unix typesetting language, a member of the roff family of text formatters that reaches back to the earliest days of time-sharing computing. Rather than describing a document with a graphical interface, an author writes plain text interspersed with terse formatting requests (each beginning with a period, such as .br for a line break or .ce to center a line) and lets troff render it for a specific output device. Created at Bell Labs in the 1970s to drive a phototypesetter, troff went on to typeset a generation of Unix documentation and — through its modern GNU reimplementation, groff — still formats the manual pages you read every time you run man on a Unix or Linux system.

History & Origins

The roff lineage begins in the mid-1960s with RUNOFF, written by Jerome H. Saltzer for MIT’s CTSS. The idea traveled to Bell Labs, where Doug McIlroy produced a version called roff. When the Bell Labs patent department wanted to justify buying a PDP-11, Joe Ossanna reimplemented and extended roff for that machine around 1971 — text processing was one of Unix’s first “killer applications.”

The decisive step came when the lab acquired a Graphic Systems CAT phototypesetter. Ossanna extended the roff line to exploit the typesetter’s multiple fonts and proportional spacing, and the result — able to produce professional-quality typeset output — was named troff, for “typesetter roff.” A companion program, nroff (“newer roff”), rendered the same input language for fixed-width devices such as terminals and line printers. Originally written in PDP-11 assembly language, troff was rewritten in C around 1975, greatly improving its portability.

Ossanna died late in 1977, and Brian Kernighan took over the code. His most important contribution was device-independent troff (“ditroff”) in 1979: instead of emitting codes for one specific typesetter, troff now produced an abstract intermediate representation that separate post-processor programs translated for particular devices. This architecture — a formatter that speaks a device-neutral language, plus drivers per device — is essentially the design that survives today.

Design Philosophy

troff embodies a philosophy characteristic of early Unix: small, composable tools joined by a simple text interface. Several ideas define it:

  • Plain text with embedded requests. A document is an ordinary text file. Formatting is expressed with control lines (starting with .) and inline escape sequences (starting with \), so documents are portable, diff-able, and editable with any text editor.
  • A low-level engine plus macros. Raw troff requests are primitive and verbose. Real documents are written against macro packages that define higher-level commands; the engine itself is meant to be programmed, not typed by hand.
  • Preprocessors instead of a monolith. Rather than build equations, tables, and diagrams into the core, the troff world uses a pipeline of preprocessors — each reads the document, expands its own specialized notation into troff requests, and passes the rest through untouched.
  • Device independence. Since the ditroff era, one document can be rendered to a terminal, PostScript, PDF, or a phototypesetter simply by choosing a different output driver.

Key Language Features

troff is a genuine, if idiosyncratic, programming language for text. Its notable capabilities include:

  • Requests — built-in commands on their own lines, e.g. .ce (center), .sp (vertical space), .ft (font), .ps (point size), .in (indent).
  • Number registers — named numeric variables (via .nr) used for counters, arithmetic, and conditional layout.
  • Strings and macros — user-defined text (.ds) and reusable command sequences (.de..) that make troff programmable and extensible.
  • Conditionals and loops.if/.ie/.el conditionals and .while loops give the language real control flow.
  • Diversions and traps — text can be captured into a “diversion” and re-emitted elsewhere (the basis for footnotes, tables, and floating figures), and traps trigger macros at specific page positions.
  • Escape sequences — inline codes like \fB (bold), \fI (italic), \fR (roman), \(bu (bullet), and \*[...] (string interpolation).

A tiny raw-troff example that defines a macro and centers a heading:

.\" set 12-point type on 14-point leading
.ps 12
.vs 14
.\" define a macro named HD for a centered, bold heading
.de HD
.sp
.ce
\fB\\$1\fR
.sp
..
.HD "Hello, troff"
This is a paragraph of ordinary text.  troff fills and
adjusts the lines to the current measure automatically.

Preprocessors

Much of troff’s power comes from its preprocessor pipeline, each program handling one specialized notation:

PreprocessorPurposeOrigin
eqnMathematical equationsKernighan & Lorinda Cherry, 1974
tblTablesBell Labs (Mike Lesk)
picLine diagrams and picturesBrian Kernighan
referBibliographic referencesBell Labs
grapStatistical chartsJon Bentley & Brian Kernighan

A typical invocation chains them before troff: pic | tbl | eqn | troff.

Macro Packages

Authors rarely write raw troff; they use a macro package that supplies document-level commands:

  • ms — one of the original AT&T packages, for papers, reports, and books.
  • mm — the “memorandum macros,” aimed at business memos and formal documents.
  • me — a Berkeley package favored for research papers.
  • man and mdoc — the packages used to write Unix manual pages; mdoc is semantic (you mark what something is), while man is more presentational.

Evolution

For its first two decades troff was proprietary AT&T software. The turning point for its longevity was groffGNU troff — written from scratch by James Clark and first released in June 1990. groff faithfully reimplemented the ditroff-era system, added its own extensions (including full macro packages, additional preprocessors, and a -T option for many output devices such as PostScript, PDF, HTML, and UTF-8), and released it as free software. On Linux and the BSDs, “troff” today almost always means groff.

groff has been steadily maintained ever since, with version 1.23.0 released in 2023 as the current stable release under maintainer G. Branden Robinson. Alternative modern implementations also exist, including Heirloom troff (derived from the original AT&T source) and neatroff, while mandoc provides a compact, independent formatter specifically for the man and mdoc manual-page languages.

Current Relevance

troff is no longer how most people typeset books or papers — TeX/LaTeX, word processors, and web-based tooling long ago took over that role. Yet troff is far from dead:

  • Manual pages. Effectively every Unix and Linux man page is a troff document. Each time you run man, a troff formatter (usually groff or mandoc) renders it. This alone keeps troff in daily, ubiquitous use.
  • Lightweight, scriptable typesetting. Because documents are plain text and the toolchain is a Unix pipeline, troff remains attractive for automated, reproducible document generation.
  • A living heritage system. Active maintenance of groff, plus Heirloom troff and neatroff, means the language continues to be developed and studied rather than merely archived.

Why It Matters

troff matters because it is woven into the fabric of Unix itself. It was one of the applications that justified building Unix in the first place, it typeset the documentation and books that taught the world about Unix and C, and its preprocessor pipeline — eqn, tbl, pic feeding a common formatter — is a textbook demonstration of the Unix philosophy of small tools composed through text streams. Decades later, its influence is quietly everywhere: the man page you consult to remember a command’s flags is, at that moment, a troff program being run just for you.

Timeline

1964
Jerome H. Saltzer creates RUNOFF at MIT for the CTSS time-sharing system. This early text formatter is the distant ancestor of the entire roff family, establishing the idea of embedding formatting requests in a plain-text document.
1971
At Bell Labs, Joe Ossanna writes roff for the PDP-11 — a reimplementation and extension of Doug McIlroy's earlier roff — as part of the effort to justify the machine's purchase for the patent department's text-processing work.
1973
After Bell Labs acquires a Graphic Systems CAT phototypesetter, Ossanna extends the roff line to support multiple fonts and proportional spacing, producing troff ("typesetter roff"). Its companion nroff targets fixed-width terminals and line printers with the same input language.
1974
Brian Kernighan and Lorinda Cherry release eqn, a preprocessor that lets authors describe mathematical equations in a readable notation that troff then typesets — the first of the influential troff preprocessors.
1975
troff, originally written in PDP-11 assembly language, is rewritten in C, making it far more portable and maintainable as Unix itself spread to new hardware.
1977
Joe Ossanna dies late in the year. Brian Kernighan takes over maintenance and further development of troff.
1979
Kernighan produces device-independent troff ("ditroff"), which emits an abstract intermediate output format consumed by device-specific post-processors — freeing troff from any single typesetter and adding basic drawing primitives.
1990
James Clark releases the first version of GNU troff (groff) in June. This free, from-scratch reimplementation of the ditroff-era system becomes the standard troff on Linux and other free Unix-like systems.
2023
groff 1.23.0 is released, the current stable version, continuing decades of maintenance now led by G. Branden Robinson and keeping troff the default formatter for Unix manual pages.

Notable Uses & Legacy

Unix and Linux manual pages

Nearly every Unix and Linux man page is written in troff's man or mdoc macro language and rendered on demand by groff. Running man(1) is, under the hood, running a troff formatter.

Early Bell Labs and Unix documentation

The Unix Programmer's Manual and much of Bell Labs' technical output — including books by Kernighan and Ritchie — were typeset with troff and its preprocessors, defining the visual style of early Unix literature.

Plan 9 from Bell Labs

Plan 9 carried the troff toolchain forward as its native documentation system, keeping the language central to Bell Labs research operating systems long after the original Unix era.

Academic and technical publishing

Combined with the eqn (equations), tbl (tables), and pic (diagrams) preprocessors, troff was widely used to typeset scientific papers, memoranda, and books before TeX and word processors became dominant.

Language Influence

Influenced By

RUNOFF roff

Influenced

groff mandoc

Running Today

Run examples using the official Docker image:

docker pull debian:stable-slim

Example usage:

docker run --rm -v $(pwd):/work -w /work debian:stable-slim sh -c 'apt-get update && apt-get install -y groff && groff -T ascii -ms doc.ms'
Last updated: