Forming a Labelled and Indented Paragraph in troff
- posted:
2025-05-26
A labelled and indented paragraph is a paragraph that begins with a label, followed by text that is indented. As mentioned in the section of Paragraphs in Groff manual, there are typically two common forms:
The label and the paragraph text appear on separated lines. For example:
Note This is the paragraph text that is separated from the label "Note". Here is some dummy text, and then comes some more dummy text.
The label and the paragraph body appear on the same line. For example:
Note This is the paragraph text that is on the same line as the label "Note". Here is some dummy text, and then comes some more dummy text.
The first form is easier to implement in troff, shown as below. It starts with the label "Note", followed by the requests .br and .in 8m to break the line and apply indentation. Then on the next it comes the paragraph text:
$ groff > form1.ps Note .br .in 8m This is the paragraph text that is separated from the label "Note". Here is some dummy text, and then comes some more dummy text.
The second form is more challenging because the label and the paragraph text share the same line, which prevents the use of standard indentation. A common solution is to use the macro ".IP" from the ms macro package:
$ groff -ms > form2-with-ms.ps .IP Note This is the paragraph text that is on the same line as the label "Note". Here is some dummy text, and then comes some more dummy text.
But how to achieve that without using any macro packages? A trick is to place a tab character right after the label "Note", with the tab stop set to match the indentation width:
$ groff > form2.ps .in 8m .ta 8m .ti 0 Note \c This is the paragraph text that is on the same line as the label "Note". Here is some dummy text, and then comes some more dummy text.
Let's break down how this works. First, both the indentation width and the tab stop are set to 8m using the requests .in 8m and .ta 8m. The request .ti 0 is then used to cancel automatic indentation for the next line, which is the first line of output.
The first line of output begins with the label "Note" at the left margin, followed by a tab character. The escape sequence "\c" tells troff to continue the output with the next input line, so the paragraph text follows immediately after the tab. Because the tab stop matches the indentation width, the paragraph text is aligned as if it were indented. The remaining of the paragraph appears on the next output lines, which is automatically indented.
If you look into the source code of the macro ".IP" in the ms macro package, you will see it uses the same method. Below is a simplified version of the macro ".IP":
.de IP .ie \\n(.$>1 .nr I \\$2 .el .nr I 8 .in \\nIm .ta \\nIm .ti 0 \\$1\t\c ..
The first argument is the label, and the second argument (optional) specifies the indentation width. Here are some examples of how to use it:
a normal labelled and indented paragraph:
.IP mylabel Some dummy text. Some more dummy text.
a numbered list (the indentation is set to 4m):
.IP 1. 4 My first point. .IP 2. 4 My second point.
Thanks for reading :)