Home / Alt manpages / grotty(1)

  • grotty(1)
  • User command
  • linux

Get Working Bold, Italics and Colour Out of grotty

grotty is the reason a man page shows up in your terminal with bold headings and underlined options instead of a wall of stray escape codes. You will use it through groff to produce terminal output with working bold, italics, colour and links, then switch to its older overstrike format when a pager or terminal cannot handle control sequences. The examples match GNU groff 1.23.0, supplied here by groff-base 1.23.0-3build2.

Allow about 10 minutes. You need a shell, groff and grotty. No elevated privileges are needed because every example here reads a document and writes to standard output. Do not send untrusted output containing terminal control sequences straight to a terminal until you know where it came from.

1. Check the installed driver

grotty is the TTY output driver for troff. In normal use, groff selects it for you once you pick a terminal device such as utf8, ascii or latin1. Check both the wrapper and the driver before you start debugging a display problem:

$ command -v groff grotty
/usr/bin/groff
/usr/bin/grotty
$ grotty --version
GNU grotty (groff) version 1.23.0

If the command is missing, install the distribution's groff package through its normal package-management process. That is an administrative change, so check the package name for your distribution before reaching for sudo.

Checkpoint

For a man page, the convenient path is man or groff selecting a terminal device. Piping arbitrary groff output straight into grotty is a common mistake: groff has already run the driver, so the second invocation sees terminal output instead of the intermediate format it expects.

2. Render a small document with the default terminal format

Create a disposable roff file in /tmp. This changes no installed man page and can be left for inspection or removed later with your normal file-clean-up process:

$ demo=$(mktemp /tmp/grotty-demo.XXXXXX.roff)
$ printf '%s\n' \
  '.TH DEMO 1' \
  '.SH NAME' \
  'demo - terminal output test' \
  '.PP' \
  'This is \f[B]bold\f[] and \f[I]italic\f[].' > "$demo"
$ groff -Tutf8 "$demo" | sed -n '1p' | sed -n l
demo ... This is \033[1mbold \033[22mand \033[4mitalic\033[24m.$

The line contains real terminal escape bytes, so the escaped display from sed -n l is your useful evidence. A real terminal interprets those SGR sequences as bold and underlined italic text. With the UTF-8 device, drawing characters and Unicode text are also available wherever the input and font descriptions support them.

3. Keep terminal attributes when using less

A pager must be told to pass SGR sequences through. GNU less uses -R for that, which matters most when you are viewing a saved rendering rather than invoking man, whose own configuration may already pick a suitable pager:

$ groff -Tutf8 "$demo" | less -R

Scroll through the document and quit with q. Literal escape notation on screen means the pager was not configured to pass the sequences through. If colours or links are still missing, check the terminal emulator as well as less: OSC 8 hyperlinks need a pager and terminal that both support them, and are not guaranteed just because grotty emitted them.

4. Select italic or reverse-video rendering

By default, grotty represents oblique text with underlining, because italic terminal support has historically been uneven. Pass driver options through groff with -P; on this installation, -P -i produces genuine SGR italic output:

$ groff -Tutf8 -P -i "$demo" | sed -n '1p' | sed -n l
demo ... \033[3mitalic\033[23m.$

The alternative -P -r asks for reverse video for oblique text, though it is ignored if -i or legacy mode is also selected. Both choices only affect presentation; neither changes the roff source.

5. Use legacy output for limited terminals

-c suppresses SGR and OSC sequences entirely. Instead, bold is represented by printing a character, a backspace, and the character again; italics use an underscore and backspace. This is a callback to old paper-terminal conventions, useful for simple consumers that cannot interpret ANSI control sequences:

$ troff -Tutf8 "$demo" | grotty -c | sed -n '1p' | sed -n l
demo ... This is b\bbo\bol\bld\bd and _\bi_\bt_\ba_\bl_\bi_\bc.$

Use troff here, because it produces the intermediate output that grotty actually consumes. Do not replace this with groff ... | grotty -c: that fails with a message such as the first command must be 'x T'. To make legacy mode the default for a whole process, set GROFF_NO_SGR in its environment, or use -P -c when calling groff directly:

$ GROFF_NO_SGR=1 groff -Tutf8 "$demo" | sed -n '1p' | sed -n l

Legacy output is not a safety filter. It still represents the document's content, and can still contain characters a terminal treats specially. Use it to solve a compatibility problem, not as a general-purpose sanitiser.

6. Disable drawing when line art causes trouble

For UTF-8 output, simple horizontal and vertical \D drawing commands become Unicode box-drawing characters; other devices use characters such as -, | and +. If a document's line art looks wrong or a downstream text consumer needs plain text, pass -d to ignore all drawing commands:

$ groff -Tutf8 -P -d "$demo" > /tmp/demo-plain.txt
$ sed -n '1,4p' /tmp/demo-plain.txt

This only changes the rendering, not the source document. Remove the temporary output once it is no longer useful, and be careful not to overwrite a file you need: redirecting with > truncates an existing destination before the command even runs.

7. Diagnose the usual failure modes

  • Missing formatting: inspect the first line with sed -n l. SGR bytes prove grotty emitted attributes; literal bytes on the terminal point to the pager or emulator instead.
  • Driver rejects input: check whether a previous groff command already ran grotty. Use troff -Tutf8 file | grotty -c for a direct driver test.
  • Italic text shows up underlined: that is the normal default. Use groff -Tutf8 -P -i file if the terminal supports SGR italics.
  • Diagrams look broken: try -P -d. The driver targets simple documents and does not support fractional movement or arbitrary drawing shapes.
  • Unexpected font or device files: inspect GROFF_FONT_PATH and any -F option. A custom directory takes precedence in the search path and can change the selected descriptions.

Done means

  • Single pass confirmed: groff -Tutf8 file renders a terminal document without a second grotty pass.
  • Pager configured: less -R preserves the SGR output when the terminal supports it.
  • Flags chosen for a reason: -P -i, -P -r, -P -c and -P -d are each picked for a stated compatibility need.
  • Direct test available: a legacy test uses troff as the producer and grotty -c as the consumer.