|

Linux CLI 50 🐧 groff command

groff > file
Hello Linux
# Ctrl + D to quit
groff -Thtml
groff -Thtml > index.html

groff is the GNU implementation of the classic Unix troff typesetting system. It takes plain text with embedded formatting macros and produces typeset output — plain text, PostScript, PDF, HTML, or UTF-8. Its most important modern job is rendering man pages, but it can also produce nicely formatted documents.

Key point: groff is a formatter, not a word processor. You write plain text interspersed with requests (lines starting with a dot, like .sp or .ce) and macros (higher-level commands from a macro package like man or ms). groff then renders that into the output format of your choice.


a – groff command introduction

groff is used to create simple text documents and troff (TeX-like) formats. It uses macros similar to those used by Unix typesetters. It is mainly used to create man pages — the built-in documentation you see with man ls, man grep, etc.

Syntax:

groff [options] [file...]

Common options:

OptionPurpose
-T devDirect output to device dev
-iRead stdin after all named input files
-m dirSearch dir for macro files
-n numStart numbering at page num
-tProcess with tbl (tables)
-pProcess with pic (diagrams)
-eProcess with eqn (equations)
-sProcess with soelim (include files)

Available output devices:

DeviceOutput
psPostScript
pdfPDF
asciiPlain ASCII text
utf8UTF-8 encoded text
htmlHTML
dviDVI (via TeX)
lj4HP LaserJet 4
latin1ISO Latin-1

Basic usage — writing directly to a file:

$ groff > file
Hello Linux
# Ctrl + D to quit
$ cat file
Hello Linux

When you run groff with no input files, it reads from stdin until you press Ctrl+D. The output goes to stdout, which you redirect to a file.

More examples:

# Send output to HTML
$ groff -Thtml

# Format a file to HTML and save it
$ groff -Thtml > index.html

# Convert a man page to HTML
$ man -P cat cat | groff -Thtml > cat.html

# Format a file to PDF
$ groff -Tpdf document.ms > output.pdf

# Format a file to plain text
$ groff -Tascii document.ms

# Format with UTF-8 output
$ groff -Tutf8 document.ms

# Process tables too
$ groff -t -Tpdf report.ms > report.pdf

# Start page numbering at 5
$ groff -n 5 document.ms

# Read stdin after files
$ groff -i document.ms

# Use a custom macro directory
$ groff -m /usr/share/groff/site-tmac document.ms

Note: By itself, groff does very little — it just renders text. The real power comes from macro packages like man, ms, me, and mm, which provide higher-level commands (headings, paragraphs, lists, fonts). When you use -man, you get the macros used in manual pages. When you use -ms, you get a package designed for technical documents.

Common macro packages:

PackageFlagPurpose
man-manManual pages
mdoc-mdocBSD-style manual pages
ms-msManuscripts, technical papers
me-meGeneral documents
mm-mmMemos, letters, reports
# Render a man page
$ groff -man -Tascii mytool.1

# Render a document with the ms macros
$ groff -ms -Tpdf paper.ms > paper.pdf

# Render with the mm macros
$ groff -mm -Tps letter.mm > letter.ps

b – some groff embedded commands

groff input contains requests — lines that start with a dot and a two-letter command. These control spacing, alignment, indentation, and more. Here are the most common ones.

Spacing:

RequestEffect
.spSpace down one line
.sp 5Space down 5 lines
.sp 2.5cSpace 2.5 centimeters
.brLine break
.bpPage break

Centering and alignment:

RequestEffect
.ce 100Center the next 100 lines
.ce 0Stop centering
.ad lAdjust lines left
.ad rAdjust lines right
.ad cAdjust lines center
.ad bAdjust lines both margins
.naNo adjustment

Indentation:

RequestEffect
.inIndent one level
.in 4Indent 4 lines
.tiTemporary indent (next line only)
.po 10Page offset — 10 characters

Font and size:

RequestEffect
.ps 20Font size 20
.ss 12Space-character size
.ft BSwitch to bold font
.ft ISwitch to italic font
.ft RReturn to roman font

Example — a simple formatted document:

$ cat > hello.tr << 'EOF'
.ce 1
Hello, Linux!
.sp 2
This is a simple groff document.
.sp
It has several lines of text,
with some spacing in between.
.in 4
This line is indented.
.in 0
Back to normal.
.ce 0
.sp 2
The end.
EOF

$ groff -Tascii hello.tr
        Hello, Linux!


This is a simple groff document.

It has several lines of text,
with some spacing in between.
    This line is indented.
Back to normal.

The end.

More details: The full troff request reference is at https://www.troff.org/54.pdf.


c – groff examples

Here are the practical examples you’ll use most often.

1. Format text as HTML interactively:

$ groff -Thtml
Hello, Linux!
This is formatted by groff.
^D
<!-- Creator: groff version 1.22.4 -->
<!-- CreationDate: ... -->
<!-- ... -->
<p>Hello, Linux!
This is formatted by groff.</p>

2. Save formatted HTML to a file:

$ groff -Thtml > index.html
Hello, Linux!
^D
$ ls -l index.html
-rw-r--r-- 1 kronos kronos 1234 Jan 15 10:00 index.html

3. Create a source file and render it:

$ echo "hello, Linux!" > hello.tr
$ cat hello.tr
hello, Linux!

$ groff hello.tr
hello, Linux!

4. Create a PDF from a groff source:

$ groff -Tpdf hello.tr > output.pdf
$ file output.pdf
output.pdf: PDF document, version 1.4

5. Convert a man page to HTML:

$ man -P cat cat | groff -Thtml > cat.html
$ ls -l cat.html
-rw-r--r-- 1 kronos kronos 45678 Jan 15 10:00 cat.html

The man -P cat part tells man to use cat as the pager — so it just dumps the raw roff source to stdout instead of displaying it. That source is then fed to groff -Thtml.

More examples:

# Write a formatted document with macros
$ cat > report.ms << 'EOF'
.TL
My Report
.AU
Kronos
.AB
This is the abstract.
.AE
.NH
Introduction
.PP
This is the first paragraph.
.NH
Methods
.PP
This is the second paragraph.
EOF

$ groff -ms -Tpdf report.ms > report.pdf

# Format a man page to plain text
$ man -P cat ls | groff -man -Tascii | head -20

# Convert a man page to PDF
$ man -P cat ls | groff -man -Tpdf > ls.pdf

# Convert a man page to UTF-8 text
$ man -P cat ls | groff -man -Tutf8

# Strip formatting entirely
$ man -P cat ls | groff -man -Tascii | col -bx

# Interactive session to HTML
$ groff -Thtml > page.html
.ce 1
Welcome
.sp 2
This is a groff-generated page.
^D

Comparing output formats:

# ASCII
$ groff -Tascii hello.tr
hello, Linux!

# UTF-8
$ groff -Tutf8 hello.tr
hello, Linux!

# HTML
$ groff -Thtml hello.tr
<!-- Creator: groff version 1.22.4 -->
<p>hello, Linux!</p>

# PDF (binary)
$ groff -Tpdf hello.tr > hello.pdf
$ file hello.pdf
hello.pdf: PDF document, version 1.4

A full example — a simple man page:

$ cat > mytool.1 << 'EOF'
.TH MYTOOL 1 "January 2024" "mytool 1.0" "User Commands"
.SH NAME
mytool \- a simple example
.SH SYNOPSIS
.B mytool
[\fIOPTION\fR]... [\fIFILE\fR]...
.SH DESCRIPTION
.B mytool
does something useful.
.SH OPTIONS
.TP
.B \-h
Show help.
.TP
.B \-v
Show version.
.SH AUTHOR
Written by Kronos.
EOF

# Render it like man would
$ groff -man -Tascii mytool.1

# Convert to HTML
$ groff -man -Thtml mytool.1 > mytool.html

# Convert to PDF
$ groff -man -Tpdf mytool.1 > mytool.pdf

# Install it
$ sudo cp mytool.1 /usr/share/man/man1/
$ man mytool

Complete Example Session

# ============================================
# PART 1: BASIC GROFF — WRITE TO A FILE
# ============================================

$ groff > file
Hello Linux
# Ctrl + D to quit

$ cat file
Hello Linux

# ============================================
# PART 2: FORMAT AS HTML
# ============================================

$ groff -Thtml
Hello, Linux!
^D
<!-- Creator: groff version 1.22.4 -->
<!-- CreationDate: Mon Jan 15 10:00:00 2024 -->
<p>Hello, Linux!</p>

# ============================================
# PART 3: SAVE HTML TO FILE
# ============================================

$ groff -Thtml > index.html
Hello, Linux!
^D

$ ls -l index.html
-rw-r--r-- 1 kronos kronos 1234 Jan 15 10:00 index.html

$ head index.html
<!-- Creator: groff version 1.22.4 -->
<p>Hello, Linux!</p>

# ============================================
# PART 4: SIMPLE SOURCE FILE
# ============================================

$ echo "hello, Linux!" > hello.tr
$ groff hello.tr
hello, Linux!

# ============================================
# PART 5: CREATE A PDF
# ============================================

$ groff -Tpdf hello.tr > output.pdf
$ file output.pdf
output.pdf: PDF document, version 1.4

# ============================================
# PART 6: MAN PAGE TO HTML
# ============================================

$ man -P cat cat | groff -Thtml > cat.html
$ ls -lh cat.html
-rw-r--r-- 1 kronos kronos 45K Jan 15 10:00 cat.html

# ============================================
# PART 7: FORMATTED DOCUMENT WITH MACROS
# ============================================

$ cat > report.ms << 'EOF'
.TL
My Report
.AU
Kronos
.NH
Introduction
.PP
This is the first paragraph of the report.
.NH
Conclusion
.PP
This is the conclusion.
EOF

$ groff -ms -Tascii report.ms

    My Report

    Kronos

1.  Introduction

    This is the first paragraph of the report.

2.  Conclusion

    This is the conclusion.

# ============================================
# PART 8: EMBEDDED REQUESTS
# ============================================

$ cat > hello.tr << 'EOF'
.ce 1
Hello, Linux!
.sp 2
This is a simple groff document.
.sp
It has several lines of text.
.in 4
This line is indented.
.in 0
Back to normal.
.ce 0
.sp 2
The end.
EOF

$ groff -Tascii hello.tr
        Hello, Linux!


This is a simple groff document.

It has several lines of text.
    This line is indented.
Back to normal.

The end.

# ============================================
# PART 9: MAN PAGE TO PDF
# ============================================

$ man -P cat ls | groff -man -Tpdf > ls.pdf
$ file ls.pdf
ls.pdf: PDF document, version 1.4

# ============================================
# PART 10: MAN PAGE TO UTF-8
# ============================================

$ man -P cat ls | groff -man -Tutf8 | head -20
LS(1)                       User Commands                       LS(1)

NAME
       ls - list directory contents

SYNOPSIS
       ls [OPTION]... [FILE]...

DESCRIPTION
       List  information  about the FILEs (the current directory by
       default).
...

Quick Reference

groff — Options

OptionPurpose
-T devOutput device (ascii, utf8, html, pdf, ps)
-iRead stdin after files
-m dirMacro directory
-n numFirst page number
-tProcess with tbl
-pProcess with pic
-eProcess with eqn
-sProcess with soelim

groff — Output Devices

DeviceOutput
asciiPlain ASCII
utf8UTF-8 text
htmlHTML
pdfPDF
psPostScript
dviDVI
lj4HP LaserJet 4
latin1ISO Latin-1

groff — Macro Packages

FlagPackagePurpose
-manmanManual pages
-mdocmdocBSD man pages
-msmsManuscripts
-memeGeneral documents
-mmmmMemos, letters

groff — Common Requests

RequestEffect
.sp NSpace N lines
.brLine break
.bpPage break
.ce NCenter N lines
.ce 0Stop centering
.in NIndent N
.tiTemporary indent
.po NPage offset
.ps NFont size
.ss NSpace-character size
.ad l|r|c|bAdjust lines
.naNo adjustment
.ft BBold font
.ft IItalic font
.ft RRoman font

man page Macros

MacroPurpose
.THTitle header
.SHSection header
.SSSubsection
.PPParagraph
.TPTagged paragraph
.BBold
.IItalic
.BRBold-roman alternating
.IRItalic-roman alternating

groff vs Other Tools

ToolPurpose
groffTroff typesetting
TeX/LaTeXHigh-quality typesetting
pandocDocument conversion
manView man pages
mandocMan page compiler

Best Practices

Do This:

# Use -man for man pages
groff -man -Tascii mytool.1           # ✅

# Use -Tpdf for PDF output
groff -Tpdf -ms doc.ms > doc.pdf      # ✅

# Use -Thtml for HTML
groff -Thtml -man mytool.1 > mytool.html  # ✅

# Use macro packages for structured documents
groff -ms -Tpdf report.ms > report.pdf   # ✅

# Preview in ASCII first
groff -Tascii doc.ms                  # ✅

# Use .ce 0 to stop centering
.ce 0                                 # ✅

# Pipe man source through groff for conversion
man -P cat ls | groff -man -Thtml > ls.html  # ✅

Don’t Do This:

# Don't forget the macro package
groff -Tpdf doc.ms                    # ❌ no macros — plain text

# Don't mix -T devices
groff -Tpdf -Thtml doc.ms             # ❌ only last wins

# Don't use groff for simple text output
groff -Tascii file.txt                # ⚠️  just cat it

# Don't forget .ce 0 after centering
.ce 100                               # ❌ centers forever

# Don't assume all devices are installed
groff -Tpdf doc.ms                    # ❌ may need ghostscript

# Don't use groff for modern documentation
# Consider Markdown + pandoc instead     # ✅

Common Pitfalls

PitfallProblemSolution
No output deviceConfusing errorUse -T
No macro packagePlain text onlyAdd -man or -ms
Missing requestsLayout brokenCheck dot-prefix
PDF needs GhostscriptErrorInstall ghostscript
HTML missing CSSUgly outputPost-process
.ce never stoppedCentered foreverAdd .ce 0
Requests must start at col 1Not processedNo leading spaces
Trailing spacesUnexpected outputClean input

Real-World Examples

1. Write Text and Save as Plain File

$ groff > note.txt
Hello, this is a note.
^D

$ cat note.txt
Hello, this is a note.

2. Format as HTML

$ groff -Thtml > page.html
Hello, Linux!
^D

3. Save HTML to a File

$ groff -Thtml > index.html
Hello, Linux!
^D

$ ls -l index.html
-rw-r--r-- 1 kronos kronos 1234 Jan 15 10:00 index.html

4. Create a Simple Source File

$ echo "hello, Linux!" > hello.tr
$ groff hello.tr
hello, Linux!

5. Create a PDF

$ groff -Tpdf hello.tr > output.pdf
$ file output.pdf
output.pdf: PDF document, version 1.4

6. Man Page to HTML

$ man -P cat cat | groff -Thtml > cat.html
$ ls -lh cat.html
-rw-r--r-- 1 kronos kronos 45K Jan 15 10:00 cat.html

7. Man Page to PDF

$ man -P cat ls | groff -man -Tpdf > ls.pdf
$ ls -lh ls.pdf
-rw-r--r-- 1 kronos kronos 78K Jan 15 10:00 ls.pdf

8. Formatted Document with ms Macros

$ cat > report.ms << 'EOF'
.TL
My Report
.AU
Kronos
.NH
Introduction
.PP
This is the first paragraph.
.NH
Conclusion
.PP
This is the conclusion.
EOF

$ groff -ms -Tpdf report.ms > report.pdf

9. Centered Title

$ cat > title.tr << 'EOF'
.ce 1
My Document
.sp 2
.ce 0
This is the body of the document.
EOF

$ groff -Tascii title.tr
   My Document

This is the body of the document.

10. Indented Paragraphs

$ cat > indent.tr << 'EOF'
Normal line.
.in 4
Indented line.
.in 8
More indented line.
.in 0
Back to normal.
EOF

$ groff -Tascii indent.tr
Normal line.
    Indented line.
        More indented line.
Back to normal.

11. Write a Complete Man Page

$ cat > mytool.1 << 'EOF'
.TH MYTOOL 1 "January 2024" "mytool 1.0" "User Commands"
.SH NAME
mytool \- a simple example tool
.SH SYNOPSIS
.B mytool
[\fIOPTION\fR]... [\fIFILE\fR]...
.SH DESCRIPTION
.B mytool
does something useful with the given files.
.SH OPTIONS
.TP
.B \-h
Show help and exit.
.TP
.B \-v
Show version and exit.
.SH AUTHOR
Written by Kronos.
EOF

$ groff -man -Tascii mytool.1

12. Convert All Man Pages to HTML

$ mkdir -p html-man
$ for m in $(man -k . | awk '{print $1}' | sort -u | head -20); do
    man -P cat "$m" 2>/dev/null | groff -man -Thtml > "html-man/$m.html"
  done
$ ls html-man/

13. Strip Formatting from a Man Page

$ man -P cat ls | groff -man -Tascii | col -bx

14. Process Tables with tbl

$ cat > table.ms << 'EOF'
.TS
allbox;
c c c
l l l.
Name	Dept	Score
Alice	Eng	95
Bob	Math	87
.TE
EOF

$ groff -t -ms -Tascii table.ms

15. Use a Different Macro Package

# Manuscript macros
$ groff -ms -Tpdf paper.ms > paper.pdf

# Memo macros
$ groff -mm -Tps letter.mm > letter.ps

# General document macros
$ groff -me -Tascii doc.me

16. Pipe a Man Page Through a Pager

$ man -P cat ls | groff -man -Tutf8 | less

17. Generate a PDF Report

$ cat > report.ms << 'EOF'
.TL
Monthly Report
.AU
Kronos
.AB
Summary of January activity.
.AE
.NH
Highlights
.PP
We accomplished several key goals.
.NH
Next Steps
.PP
Continue working on the roadmap.
EOF

$ groff -ms -Tpdf report.ms > report.pdf
$ xdg-open report.pdf

18. Preview Before Converting

# Always preview in ASCII first
$ groff -Tascii document.ms
# Then convert to your target format
$ groff -Tpdf document.ms > document.pdf

Visual: How groff Works

┌──────────────────────────────────────────────┐
│           groff pipeline                     │
│                                              │
│  Source (.ms, .man, .tr)                     │
│  ┌────────────────────────────────────────┐  │
│  │ .TL                                    │  │
│  │ My Report                              │  │
│  │ .AU                                    │  │
│  │ Kronos                                 │  │
│  │ .PP                                    │  │
│  │ Body text here.                        │  │
│  └────────────────────────────────────────┘  │
│                                              │
│              │                               │
│              ▼                               │
│                                              │
│  groff -ms -Tpdf                             │
│  (reads macros, applies formatting)          │
│                                              │
│              │                               │
│              ▼                               │
│                                              │
│  Output (PDF, HTML, ASCII, ...)              │
│  ┌────────────────────────────────────────┐  │
│  │  ┌──────────────────┐                  │  │
│  │  │   My Report      │                  │  │
│  │  │                  │                  │  │
│  │  │   Kronos         │                  │  │
│  │  │                  │                  │  │
│  │  │   Body text here.│                  │  │
│  │  └──────────────────┘                  │  │
│  └────────────────────────────────────────┘  │
│                                              │
└──────────────────────────────────────────────┘

Summary

CommandPurposeExample
groff > fileWrite to filegroff > out.txt
groff -TasciiPlain text outputgroff -Tascii doc.ms
groff -Tutf8UTF-8 outputgroff -Tutf8 doc.ms
groff -ThtmlHTML outputgroff -Thtml doc.ms
groff -TpdfPDF outputgroff -Tpdf doc.ms > doc.pdf
groff -TpsPostScriptgroff -Tps doc.ms > doc.ps
groff -manMan page macrosgroff -man -Tascii mytool.1
groff -msManuscript macrosgroff -ms -Tpdf report.ms
groff -mmMemo macrosgroff -mm -Tps letter.mm
groff -tProcess tablesgroff -t -ms -Tpdf report.ms
groff -n NStart page at Ngroff -n 5 doc.ms
.sp NSpace N lines.sp 2
.ce NCenter N lines.ce 1
.in NIndent N.in 4
.ps NFont size.ps 12
.bpPage break.bp
.brLine break.br

Key takeaways:

  • groff is the GNU troff typesetting system — a formatter, not a word processor
  • It’s mainly used for man pages, but can produce PDF, HTML, PS, and plain text
  • Use -T dev to choose the output device (ascii, utf8, html, pdf, ps)
  • Use macro packages like -man (man pages) and -ms (manuscripts) for structured documents
  • Requests start with a dot (.sp, .ce, .in, .ps, .bp, .br) and control layout
  • Run groff with no file to read from stdin; Ctrl+D to finish
  • Convert a man page with man -P cat NAME | groff -man -Thtml > NAME.html
  • Create a PDF with groff -ms -Tpdf doc.ms > doc.pdf
  • Preview in ASCII first (-Tascii) before converting to PDF or HTML
  • You can also just use man to view pages — groff is for generating or converting them

Remember: groff is powerful but quirky. Its syntax is terse and its history is long. For modern documentation, Markdown + pandoc is usually a better choice. But for man pages and for converting existing troff sources, groff is the right tool. Learn -man and -ms, the basic requests (.sp, .ce, .in), and the man -P cat | groff idiom for converting man pages. It’s a niche skill, but one that still pays off when you need to produce properly typeset Unix documentation.


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!