ROFF(7) | Miscellaneous Information Manual | ROFF(7) |
roff
— roff
language reference for mandoc
The roff
language is a general purpose
text formatting language. Since traditional implementations of the
mdoc(7) and
man(7) manual formatting languages are
based on it, many real-world manuals use small numbers of
roff
requests and escape sequences intermixed with
their mdoc(7) or
man(7) code. To properly format such
manuals, the mandoc(1) utility supports
a subset of roff
requests and escapes. Even though
this manual page lists all roff
requests and escape
sequences, it only contains partial information about requests not supported
by mandoc(1) and about language
features that do not matter for manual pages. For complete
roff
manuals, consult the
SEE ALSO section.
Input lines beginning with the control character ‘.’
are parsed for requests and macros. Such lines are called “request
lines” or “macro lines”, respectively. Requests change
the processing state and manipulate the formatting; some macros also define
the document structure and produce formatted output. The single quote
("'") is accepted as an alternative control character, treated by
mandoc(1) just like
‘.
’
Lines not beginning with control characters are called “text lines”. They provide free-form text to be printed; the formatting of the text depends on the respective processing context.
roff
documents may contain only graphable
7-bit ASCII characters, the space character, and, in certain circumstances,
the tab character. The backslash character ‘\’ indicates the
start of an escape sequence, used for example for
Comments and
Special Characters. For a
complete listing of escape sequences, consult the
ESCAPE SEQUENCE
REFERENCE below.
Text following an escaped double-quote ‘\"’, whether in a request, macro, or text line, is ignored to the end of the line. A request line beginning with a control character and comment escape ‘.\"’ is also ignored. Furthermore, request lines with only a control character and optional trailing whitespace are stripped from input.
Examples:
.\" This is a comment line. .\" The next line is ignored: . .Sh EXAMPLES \" This is a comment, too. example text \" And so is this.
Special characters are used to encode special glyphs and are rendered differently across output media. They may occur in request, macro, and text lines. Sequences begin with the escape character ‘\’ followed by either an open-parenthesis ‘(’ for two-character sequences; an open-bracket ‘[’ for n-character sequences (terminated at a close-bracket ‘]’); or a single one character sequence.
Examples:
See mandoc_char(7) for a complete list.
In mdoc(7) and
man(7) documents, fonts are usually
selected with macros. The \f
escape sequence and the
ft
request can be used to manually change the font,
but this is not recommended in mdoc(7)
documents. Such manual font changes are overridden by many subsequent
macros.
The following fonts are supported:
B
BI
CB
B
in terminal
output.CI
I
in terminal
output.CR
R
in terminal
output.CW
CR
.I
P
\f
eascape sequence or
ft
request, this returns to the font before the
last font change in the macro rather than to the font before the last
manual font change.R
1
R
.2
I
.3
B
.4
BI
.Examples:
\fBbold\fR
\fIitalic\fP
\f(BIbold
italic\fP
Whitespace consists of the space character. In text lines, whitespace is preserved within a line. In request and macro lines, whitespace delimits arguments and is discarded.
Unescaped trailing spaces are stripped from text line input unless in a literal context. In general, trailing whitespace on any input line is discouraged for reasons of portability. In the rare case that a space character is needed at the end of an input line, it may be forced by ‘\ \&’.
Literal space characters can be produced in the output using escape sequences. In macro lines, they can also be included in arguments using quotation; see MACRO SYNTAX for details.
Blank text lines, which may include whitespace, are only permitted within literal contexts. If the first character of a text line is a space, that line is printed with a leading newline.
Many requests and macros support scaled widths for their
arguments. The syntax for a scaled width is
‘[+-]?[0-9]*.[0-9]*[:unit:]
’, where a
decimal must be preceded or followed by at least one digit.
The following scaling units are accepted:
Using anything other than ‘m’, ‘n’, or ‘v’ is necessarily non-portable across output media. See COMPATIBILITY.
If a scaling unit is not provided, the numerical value is interpreted under the default rules of ‘v’ for vertical spaces and ‘u’ for horizontal ones.
Examples:
.Bl -tag -width
2i
.HP
2i
.sp
2v
Each sentence should terminate at the end of an input line. By doing this, a formatter will be able to apply the proper amount of spacing after the end of sentence (unescaped) period, exclamation mark, or question mark followed by zero or more non-sentence closing delimiters (‘)’, ‘]’, ‘'’, ‘"’).
The proper spacing is also intelligently preserved if a sentence ends at the boundary of a macro line.
If an input line happens to end with a period, exclamation or question mark that isn't the end of a sentence, append a zero-width space (‘\&’).
Examples:
Do not end sentences mid-line like this. Instead, end a sentence like this. A macro would end like this: .Xr mandoc 1 . An abbreviation at the end of an input line needs escaping, e.g.\& like this.
A request or macro line consists of:
Thus, the following request lines are all equivalent:
.ig end .ig end . ig end
Macros are provided by the
mdoc(7) and
man(7) languages and can be defined by the
de
request. When called, they follow the same syntax
as requests, except that macro arguments may optionally be quoted by
enclosing them in double quote characters (‘"’). Quoted
text, even if it contains whitespace or would cause a macro invocation when
unquoted, is always considered literal text. Inside quoted text, pairs of
double quote characters (‘""’) resolve to single
double quote characters.
To be recognised as the beginning of a quoted argument, the opening quote character must be preceded by a space character. A quoted argument extends to the next double quote character that is not part of a pair, or to the end of the input line, whichever comes earlier. Leaving out the terminating double quote character at the end of the line is discouraged. For clarity, if more arguments follow on the same input line, it is recommended to follow the terminating double quote character by a space character; in case the next character after the terminating double quote character is anything else, it is regarded as the beginning of the next, unquoted argument.
Both in quoted and unquoted arguments, pairs of backslashes (‘\\’) resolve to single backslashes. In unquoted arguments, space characters can alternatively be included by preceding them with a backslash (‘\ ’), but quoting is usually better for clarity.
Examples:
.Fn strlen
"const char *s"
.Op "Fl
a"
The mandoc(1)
roff
parser recognises the following requests. For
requests marked as "ignored" or "unsupported", any
arguments are ignored, and the number of arguments is not checked.
ab
[message]ad
[b
| c
|
l
| n
|
r
]af
registername formataln
newname oldnameals
newname oldnameam
macroname [endmacro]de
.am1
macroname [endmacro]de1
. Since
mandoc(1) does not implement
roff
compatibility mode at all, it handles this
request as an alias for am
.ami
macrostring [endstring]dei
.ami1
macrostring [endstring]dei1
. Since
mandoc(1) does not implement
roff
compatibility mode at all, it handles this
request as an alias for ami
.as
stringname [string]ds
. If a user-defined string with the
specified name does not yet exist, it is set to the empty string before
appending.as1
stringname [string]ds1
. Since
mandoc(1) does not implement
roff
compatibility mode at all, it handles this
request as an alias for as
.asciify
divnamebacktrace
bd
font [curfont]
[offset]bleedat
left top width heightblm
macronamebox
divnameboxa
divnamebp
[+
|-
]pagenumberBP
source height width position offset flags labelbr
break
while
loop.breakchar
char ...brnl
Nbrp
br
.brpnl
Nc2
[char]cc
[char]ce
[N]cf
filenamecflags
flags char ...ch
macroname [dist]char
glyph [string]tr
.chop
stringnameclass
classname char ...close
streamnameCL
color textcolor
[1
| 0
]composite
from tocontinue
while
loop. Currently unsupported.cp
[1
| 0
]roff
compatibility mode on or off.
Currently ignored.cropat
left top width heightcs
font [width
[emsize]]cu
[N]da
divnamedch
macroname [dist]de
macroname [endmacro]roff
macro. Its syntax can be either
.de
macroname
definition
..
or
.de
macroname endmacro
definition
.endmacro
Both forms define or redefine the macro
macroname to represent the
definition, which may consist of one or more input
lines, including the newline characters terminating each line,
optionally containing calls to roff
requests,
roff
macros or high-level macros like
man(7) or
mdoc(7) macros, whichever applies to
the document in question.
Specifying a custom endmacro works in
the same way as for ig
; namely, the call to
‘.endmacro’ first ends the
definition, and after that, it is also evaluated
as a roff
request or
roff
macro, but not as a high-level macro.
The macro can be invoked later using the syntax
Regarding argument parsing, see MACRO SYNTAX above.
The line invoking the macro will be replaced in the input stream by the definition, replacing all occurrences of \\$N, where N is a digit, by the Nth argument. For example,
.de ZN \fI\^\\$1\^\fP\\$2 .. .ZN XtFree .
produces
in the input stream, and thus in the output: XtFree. Each occurrence of \\$* is replaced with all the arguments, joined together with single space characters. The variant \\$@ is similar, except that each argument is individually quoted.
Since macros and user-defined strings share a common string
table, defining a macro macroname clobbers the
user-defined string macroname, and the
definition can also be printed using the
‘\*’ string interpolation syntax described below
ds
, but this is rarely useful because every
macro definition contains at least one explicit newline character.
In order to prevent endless recursion, both groff and mandoc(1) limit the stack depth for expanding macros and strings to a large, but finite number, and mandoc(1) also limits the length of the expanded input line. Do not rely on the exact values of these limits.
de1
macroname [endmacro]roff
macro that will be executed with
roff
compatibility mode switched off during macro
execution. This is a groff extension. Since
mandoc(1) does not implement
roff
compatibility mode at all, it handles this
request as an alias for de
.defcolor
newname scheme component ...dei
macrostring [endstring]roff
macro, specifying the macro name
indirectly (groff extension). The syntax of this request is the same as
that of de
. The effect is the same as:
de
\*[macrostring]
[\*[endstring]]dei1
macrostring [endstring]roff
macro that will be executed with
roff
compatibility mode switched off during macro
execution, specifying the macro name indirectly (groff extension). Since
mandoc(1) does not implement
roff
compatibility mode at all, it handles this
request as an alias for dei
.device
string ...devicem
stringnamedi
divnamedo
command [argument ...]roff
request or macro line with
compatibility mode disabled. Currently unsupported.ds
stringname [["]string]The string can be interpolated into subsequent text by using \*[stringname] for a stringname of arbitrary length, or \*(NN or \*N if the length of stringname is two or one characters, respectively. Interpolation can be prevented by escaping the leading backslash; that is, an asterisk preceded by an even number of backslashes does not trigger string interpolation.
Since user-defined strings and macros share a common string
table, defining a string stringname clobbers the
macro stringname, and the
stringname used for defining a string can also be
invoked as a macro, in which case the following input line will be
appended to the string, forming a new input line
passed to the roff
parser. For example,
.ds badidea .S .badidea H SYNOPSIS
invokes the SH
macro when used in a
man(7) document. Such abuse is of
course strongly discouraged.
ds1
stringname [["]string]roff
compatibility mode switched off during string
expansion. This is a groff extension. Since
mandoc(1) does not implement
roff
compatibility mode at all, it handles this
request as an alias for ds
.dwh
dist macronamedt
[dist macroname]ec
[char]ecr
ecs
el
bodyie
and uses it as its conditional. If no stack entries are present (e.g., due
to no prior ie
calls) then false is assumed. The
syntax of this request is similar to if
except
that the conditional is missing.em
macronameEN
EQ
.eo
EP
BP
. This is a Heirloom
extension and currently unsupported.EQ
errprint
messageev
[envname]evc
[envname]ex
fallback
curfont font ...fam
[familyname]fc
[delimchar [padchar]]fchar
glyphname [string]fcolor
colornamefdeferlig
font string ...feature
+
|-
namefi
nf
request. In fill
mode, input from subsequent input lines is added to the same output line
until the next word no longer fits, at which point the output line is
broken. This request is implied by the
mdoc(7) Sh
macro and by the man(7)
SH
, SS
, and
EE
macros.fkern
font minkernfl
flig
font string char ...fp
position font [filename]fps
mapname ...fschar
font glyphname [string]fspacewidth
font [afmunits]fspecial
curfont [font ...]ft
[font]P
.ftr
newname [oldname]fzoom
font [permille]gcolor
[colorname]hc
[char]hcode
char code ...hidechar
font char ...hla
languagehlm
[number]hpf
filenamehpfa
filenamehpfcode
code code ...hw
word ...hy
[mode]hylang
languagehylen
ncharhym
[length]hypp
penalty ...hys
[length]ie
condition bodyel
, which may be separated by any intervening
input (or not exist at all). Its syntax is equivalent to
if
.if
condition body.if
condition \{body
body ...\}
.if
condition \{\
body ...
.\}
The condition is a boolean expression. Currently, mandoc(1) supports the following subset of roff conditionals:
If a conditional is false, its children are not processed, but are syntactically interpreted to preserve the integrity of the input document. Thus,
will discard the ‘.ig’, which may lead to interesting results, but
will continue to syntactically interpret to the block close of the final conditional. Sub-conditionals, in this case, obviously inherit the truth value of the parent.
If the body section is begun by an escaped brace ‘\{’, scope continues until the end of the input line containing the matching closing-brace escape sequence ‘\}’. If the body is not enclosed in braces, scope continues until the end of the line. If the condition is followed by a body on the same line, whether after a brace or not, then requests and macros must begin with a control character. It is generally more intuitive, in this case, to write
.if
condition \{\
.request
.\}
than having the request or macro follow as
if
condition \{.requestThe scope of a conditional is always parsed, but only executed if the conditional evaluates to true.
Note that the ‘\}’ is converted into a zero-width escape sequence if not passed as a standalone macro ‘.\}’. For example,
will result in ‘\}’ being considered an argument of the ‘Fl’ macro.
ig
[endmacro].ig
ignored text
..
or
.ig
endmacro
ignored text
.endmacro
In the first case, input is ignored until a ‘..’ request is encountered on its own line. In the second case, input is ignored until the specified ‘.endmacro’ is encountered. Do not use the escape character ‘\’ anywhere in the definition of endmacro; it would cause very strange behaviour.
When the endmacro is a roff request or a roff macro, like in
the subsequent invocation of if
will
first terminate the ignored text, then be invoked
as usual. Otherwise, it only terminates the ignored
text, and arguments following it or the ‘..’ request
are discarded.
in
[[+
|-
]width]index
register stringname substringit
expression macroitc
expression macroIX
class keystringkern
[1
| 0
]kernafter
font char ... afmunits ...kernbefore
font char ... afmunits ...kernpair
font char ... font char ... afmunitslc
[glyph]lc_ctype
localenameLC_CTYPE
locale. This is a Heirloom
extension and currently unsupported.lds
macroname stringlength
register stringletadj
lspmin lshmin letss lspmax lshmaxlf
lineno [filename]lg
[1
| 0
]lhang
font char ... afmunitslinetabs
[1
| 0
]ll
[[+
|-
]width]-O
width
command line option.lnr
register
[+
|-
]value
[increment]lnrf
register
[+
|-
]value
[increment]lpfx
stringls
[factor]lsm
macronamelt
[[+
|-
]width]mc
glyph [dist]mediasize
mediaminss
widthmk
[register]mso
filenamena
ne
[height]nf
Bd
-unfilled
and
Bd
-literal
macros and by
the man(7) EX
macro. The fi
request switches back to the default
fill mode.nh
nhychar
char ...nm
[start [inc
[space [indent]]]]nn
[number]nop
bodynop
request and any space characters
immediately following it. This is mostly used to indent text lines inside
macro definitions.nr
register
[+
|-
]expression
[stepsize]The stepsize is used by the
\n+
auto-increment feature. It remains unchanged
when omitted while changing an existing register, and it defaults to 0
when defining a new register.
The following register is handled specially:
nS
Sh
macro will reset this register.nrf
register
[+
|-
]expression
[increment]nroff
ns
nx
[filename]open
stream fileopena
stream fileos
output
stringpadj
[1
| 0
]papersize
mediapc
[char]pev
pi
commandPI
BP
. This is a Heirloom
extension and currently unsupported.pl
[[+
|-
]height]pm
pn
[+
|-
]numberpnr
po
[[+
|-
]offset]m
.ps
[[+
|-
]size]psbb
filenamepshape
indent length ...pso
commandptr
pvs
[[+
|-
]height]rchar
glyph ...rd
[prompt [argument ...]]recursionlimit
maxrec maxtailreturn
[twice]rfschar
font glyph ...rhang
font char ... afmunitsrj
[N]rm
macronamern
oldname newnameroff
requests is not supported, and diversions are
not implemented at all.rnn
oldname newnamerr
registerrs
rt
[dist]schar
glyph [string]sentchar
char ...shc
[glyph]shift
[number]sizes
size ...so
filenameso
request line. To avoid
inadvertent inclusion of unrelated files,
mandoc(1) only accepts relative paths
not containing the strings "../" and "/..".
This request requires man(1) to change to the right directory before calling mandoc(1), per convention to the root of the manual tree. Typical usage looks like:
.so man3/Xcursor.3
As the whole concept is rather fragile, the use of
so
is discouraged. Use
ln(1) instead.
sp
[height]1v
).spacewidth
[1
| 0
]special
[font ...]spreadwarn
[width]ss
wordspace [sentencespace]sty
position stylesubstring
stringname startpos
[endpos]sv
[height]sy
commandT&
TS
.ta
[width ... [T
width ...]]T
marker are used repeatedly
as often as needed; for each reuse, they are taken relative to the last
previously established tab stop. When ta
is called
without arguments, all tab stops are cleared.tc
[glyph]TE
TS
.ti
[+
|-
]widthm
.tkf
font minps width1 maxps width2tl
'left'center'right'tm
stringtm1
stringtmc
stringtr
glyph glyph ...tr \(xx\(yy
replaces all invocations of \(xx with \(yy.
track
font minps width1 maxps width2transchar
char ...trf
filenametrimat
left top width heighttrin
glyph glyph ...asciify
.
Currently unsupported.trnt
glyph glyph ...troff
TS
uf
fontul
[N]unformat
divnameunwatch
macronameunwatchn
registervpt
[1
| 0
]vs
[[+
|-
]height]warn
flagswarnscale
siwatch
macronamewatchlength
maxlengthwatchn
registerwh
dist [macroname]while
condition bodyif
. Currently implemented with
two restrictions: cannot nest, and each loop must start and end in the
same scope.write
["]stringwritec
["]stringwritem
macronamexflag
levelThe nr
, if
, and
ie
requests accept integer numerical expressions as
arguments. These are always evaluated using the C int
type; integer overflow works the same way as in the C language. Numbers
consist of an arbitrary number of digits ‘0’ to
‘9’ prefixed by an optional sign ‘+’ or
‘-’. Each number may be followed by one optional scaling unit
described below Scaling Widths. The
following equations hold:
1i = 6v = 6P = 10m = 10n = 72p = 1000M = 240u = 240 254c = 100i = 24000u = 24000 1f = 65536u = 65536
The following binary operators are implemented. Unless otherwise stated, they behave as in the C language:
+
-
*
/
%
<
>
==
=
==
(this differs from
C)<=
>=
<>
!=
; this one is of
limited portability, it is supported by Heirloom roff, but not by
groff)&
&&
):
||
)<?
>?
There is no concept of precedence; evaluation proceeds from left to right, except when subexpressions are enclosed in parentheses. Inside parentheses, whitespace is ignored.
The mandoc(1)
roff
parser recognises the following escape
sequences. In mdoc(7) and
man(7) documents, using escape sequences
is discouraged except for those described in the
LANGUAGE SYNTAX section above.
A backslash followed by any character not listed here simply prints that character itself.
\<newline>
\<space>
\!
\"
\#
\$
argde
.\%
\&
\'
\(aa
instead.\(
cc\)
\*[
name]
\*
c and
\*(
cc.
One string is predefined on the roff
language level: \*(.T
expands to the name of the
output device, for example ascii, utf8, ps, pdf, html, or markdown.
Macro sets traditionally predefine additional strings which are not portable and differ across implementations. Those supported by mandoc(1) are listed in mandoc_char(7).
Strings can be defined, changed, and deleted with the
ds
, as
, and
rm
requests.
\,
\-
\/
\:
\?
\?
into the current
diversion without interpreting requests, macros, and escapes. This is a
groff extension and currently unsupported.\[
name]
\^
\_
\(ul
instead.\`
\(ga
instead.\{
if
.\|
\}
if
.\~
\0
\A'
string'
\a
\B'
string'
\b'
string'
\C'
name'
\c
\D'
string'
\d
\E
\
itself.\e
\F[
name]
\F
c and
\F(
cc.\f[
name]
\f
c and
\f(
cc. An empty name
\f[]
defaults to \fP
.\g[
name]
\g
c and
\g(
cc.\H'
[+|-]number'
\h'
[|
]width'
m
.\k[
name]
\k
c and
\k(
cc.\L'
number[c]'
\l'
width[c]'
\M[
name]
\M
c and
\M(
cc.\m[
name]
\m
c and
\m(
cc.\N'
number'
\n
[+|-][
name]
\n
c and
\n(
cc. If the optional sign
is specified, the register is first incremented or decremented by the
stepsize that was specified in the relevant
nr
request, and the changed value is
interpolated.\O
digit,
\O[5
arguments]
1
, 2
,
3
, or 4
, it is
ignored.\o'
string'
\p
\R'
name
[+|-]number'
\r
\S'
number'
\s'
[+|-]number'
\s
[+|-]n,
\s
[+|-]'
number'
,
\s[
[+|-]number]
,
and
\s
[+|-][
number]
are also parsed and ignored.\t
\u
\V[
name]
\V
c and
\V(
cc.\v'
number'
\w'
string'
\X'
string'
\x'
number'
\Y[
name]
\Y
c and
\Y(
cc.\Z'
string'
\z
The mandoc(1) implementation
of the roff
language is incomplete. Major
unimplemented features include:
so
requests with safe relative paths.The special semantics of the nS
number
register is an idiosyncrasy of OpenBSD manuals and
not supported by other mdoc(7)
implementations.
mandoc(1), eqn(7), man(7), mandoc_char(7), mdoc(7), tbl(7)
Joseph F. Ossanna and Brian W. Kernighan, Troff User's Manual, AT&T Bell Laboratories, Computing Science Technical Report, 54, http://www.kohala.com/start/troff/cstr54.ps, Murray Hill, New Jersey, 1976 and 1992.
Joseph F. Ossanna, Brian W. Kernighan, and Gunnar Ritter, Heirloom Documentation Tools Nroff/Troff User's Manual, http://heirloom.sourceforge.net/doctools/troff.pdf, September 17, 2007.
The RUNOFF typesetting system, whose input forms the basis for
roff
, was written in MAD and FAP for the CTSS
operating system by Jerome E. Saltzer in 1964. Doug McIlroy rewrote it in
BCPL in 1969, renaming it roff
. Dennis M. Ritchie
rewrote McIlroy's roff
in PDP-11 assembly for
Version 1 AT&T UNIX, Joseph F. Ossanna
improved roff and renamed it nroff for Version 2
AT&T UNIX, then ported nroff to C as troff, which Brian W.
Kernighan released with Version 7 AT&T
UNIX. In 1989, James Clark re-implemented troff in C++, naming it
groff.
This roff
reference was written by
Kristaps Dzonsons
<kristaps@bsd.lv> and
Ingo Schwarze
<schwarze@openbsd.org>.
September 18, 2021 | macOS 15.2 |