MAN(7)
๐ MAN โ the legacy manual-page formatting language, bestie ๐
(that's MAN(7) from the Miscellaneous Information Manual, if we're being official about it โจ)
๐ธ NAME ๐ธ
man โ the legacy formatting language for manual pages ๐ซถ
๐ฆ DESCRIPTION ๐ฆ
okay so storytime ๐: the man language was THE standard formatting language for AT&T UNIX manual pages from 1979 to 1989. iconic run, honestly. butโ
๐จ DO NOT use it to write new manual pages. ๐จ
fr fr. it's a purely presentational language and it lacks support for semantic markup ๐ญ. use the mdoc(7) language instead. periodt. ๐
so in a man document, any line that starts with the control character '.' is called a โmacro lineโ โจ. the first word is the macro name, and it usually consists of two capital letters. for a list of portable macros, go peek at โMACRO OVERVIEWโ below ๐. the words that come after the macro name are the arguments to the macro.
lines that don't start with the control character are called โtext linesโ ๐. they give you free-form text to be printed, and ngl the formatting of that text depends on the respective processing context:
.SH Macro lines change control state.
Text lines are interpreted within the current state.
many aspects of the basic syntax of the man language are based on the roff(7) language ๐ง. see the LANGUAGE SYNTAX and MACRO SYNTAX sections in the roff(7) manual for the deets, in particular regarding comments, escape sequences, whitespace, and quoting.
every single man document starts with the TH macro, which specifies the document's name and section, followed by the โNAMEโ section formatted like this:
.TH PROGNAME 1 1979-01-10
.SH NAME
\fBprogname\fR \(en one line about what it does
๐ MACRO OVERVIEW ๐
this overview is sorted so that macros of similar purpose are listed together ๐ซถ. deprecated and non-portable macros are not included in the overview, but you can find them in the alphabetical reference below โฌ๏ธ.
๐ Page header and footer meta-data ๐
THโ set the title:name section date [source [volume]]ATโ display AT&T UNIX version in the page footer (<= 1 argument)UCโ display BSD version in the page footer (<= 1 argument)
๐ Sections and paragraphs ๐
SHโ section header (one line)SSโ subsection header (one line)PPโ start an undecorated paragraph (no arguments)RS,REโ reset the left margin:[width]IPโ indented paragraph:[head [width]]TPโ tagged paragraph:[width]PDโ set vertical paragraph distance:[height]inโ additional indent:[width]
๐ Physical markup ๐
Bโ boldface fontIโ italic fontSBโ small boldface fontSMโ small roman fontBIโ alternate between boldface and italic fontsBRโ alternate between boldface and roman fontsIBโ alternate between italic and boldface fontsIRโ alternate between italic and roman fontsRBโ alternate between roman and boldface fontsRIโ alternate between roman and italic fonts
๐ MACRO REFERENCE ๐
ok bestie, this is the canonical list โ every single macro, alphabetized, nothing skipped, no cap. ๐ซถ Wanna know how the scoping of each macro works (like who's in charge until when)? That's over in MACRO SYNTAX, go peek there. โจ
AT ๐ผ
Sets the volume for the footer, for compatibility with man pages from AT&T UNIX releases. The optional arguments tell it which release it's from. This macro is an extension that first showed up in 4.3BSD. ๐
B ๐
ฑ๏ธ
Text is rendered in bold face. periodt.
BI ๐
Text is rendered alternately in bold and italic. So like, .BI this word and that makes this and and go bold, while word and that go italic. Any whitespace between arguments gets dropped in the output. ๐ซฅ
Example:
.BI bold italic bold italic
BR ๐ธ
Text is rendered alternately in bold face and roman (that's the default font, girly). Whitespace between arguments is omitted in output. Also see BI. ๐
DT ๐
Restore the default tabulator positions โ they sit at intervals of 0.5 inches. This does literally nothing unless the tabulator positions got changed with the roff(7) ta request. ๐
EE ๐
This is a non-standard Version 9 AT&T UNIX extension that GNU later adopted. In mandoc(1), it does the exact same thing as the roff(7) fi request โ switch to fill mode. โจ
EX ๐ซ
Also a non-standard Version 9 AT&T UNIX extension, later adopted by GNU. In mandoc(1), it does the same as the roff(7) nf request โ switch to no-fill mode. ๐
HP ๐
Begins a paragraph whose first output line is left-justified, but every line after that is indented. Syntax goes like this:
.HP [width]
The width argument is a roff(7) scaling width. If you specify it, it gets saved for later paragraph left margins; if you don't, the saved-or-default width is used. ๐ซถ
This macro is portable, but it's deprecated, because it has no good representation in HTML output โ it usually ends up indistinguishable from PP. ๐ญ
I โ๏ธ
Text is rendered in italics.
IB ๐
Text is rendered alternately in italics and bold face. Whitespace between arguments is omitted in output. Also see BI. ๐
IP ๐
Begins an indented paragraph, syntax:
.IP [head [width]]
The width argument is a roff(7) scaling width that defines the left margin. It's saved for later paragraph left-margins; if unspecified, the saved-or-default width gets used. ๐
The head argument is used as a leading term, flushed to the left margin. Super handy for bulleted paragraphs and stuff like that. ๐
IR ๐ฆ
Text is rendered alternately in italics and roman (the default font). Whitespace between arguments is omitted in output. Also see BI. ๐
LP ๐ช
Just a synonym for PP. that's it, that's the whole macro.
ME ๐ง
Ends a mailto block that was started with MT. This is a non-standard GNU extension. ๐ซถ
MT ๐
Begins a mailto block. Also a non-standard GNU extension. Syntax:
.MT address
link description to be shown
.ME
OP ๐ฉ
Optional command-line argument. This one is a non-standard DWB extension. Syntax:
.OP key [value]
The key is usually a command-line flag, and value is its argument. ๐
P ๐ช
This synonym for PP is an AT&T System III UNIX extension that 4.3BSD later adopted. โจ
PD ๐
Specify the vertical space to be inserted before each new paragraph. Syntax:
.PD [height]
The height argument is a roff(7) scaling width. It defaults to 1v. If you leave the unit off, v is assumed. ๐
This macro affects the spacing before any subsequent instances of HP, IP, LP, P, PP, SH, SS, SY, and TP. so like, it's a whole vibe-shifter for spacing.
PP ๐
Begins an undecorated paragraph. A paragraph's scope gets closed by a subsequent paragraph, sub-section, section, or end of file. The saved paragraph left-margin width gets reset to the default. ๐ธ
RB ๐
Text is rendered alternately in roman (the default font) and bold face. Whitespace between arguments is omitted in output. Also see BI. ๐
RE โฉ๏ธ
Explicitly closes out the scope of a prior RS. The default left margin gets restored to whatever it was before that RS invocation. ๐
Syntax:
.RE [level]
With no argument, the most recent RS block is closed out. If level is 1, all open RS blocks are closed out. Otherwise, level โ 1 nested RS blocks stay open. ๐ซถ
RI ๐ญ
Text is rendered alternately in roman (the default font) and italics. Whitespace between arguments is omitted in output. Also see BI. ๐
RS ๐
Temporarily resets the default left margin. Syntax:
.RS [width]
The width argument is a roff(7) scaling width. If it's not specified, the saved-or-default width is used. โจ
Also see RE. ๐
SB ๐
Text is rendered in small size (one point smaller than the default font) bold face. This macro is an extension that probably first appeared in SunOS 4.0, and was later adopted by GNU and by 4.4BSD. ๐
SH ๐๏ธ
Begins a section. A section's scope is only closed by another section or the end of file. The paragraph left-margin width gets reset to the default. ๐
SM ๐ค
Text is rendered in small size โ one point smaller than the default font.
SS ๐ช
Begins a sub-section. A sub-section's scope is closed by a subsequent sub-section, section, or end of file. The paragraph left-margin width gets reset to the default. โจ
SY ๐ป
Begins a synopsis block, syntax:
.SY command
arguments
.YS
This is a non-standard GNU extension and it's very rarely used, even in GNU manual pages. Formatting works similar to IP. ๐
TH ๐
Sets the name of the manual page, for use in the page header and footer. Syntax:
.TH name section date [source [volume]]
Conventionally, the document name is given in all caps. The section is usually a single digit, and in a few cases it's followed by a letter. ๐
The recommended date format is YYYY-MM-DD, exactly as specified in the ISO-8601 standard; if the argument doesn't conform, it gets printed verbatim. If the date is empty or not specified, the current date is used. ๐๏ธ
The optional source string specifies the organisation providing the utility. When it's unspecified, mandoc(1) uses its -Ios argument. The volume string replaces the default volume title of the section. ๐
Examples:
.TH CVS 5 1992-02-12 GNU
TP ๐
Begins a paragraph where the head โ if it goes past the indentation width โ is followed by a newline; if it doesn't, the body follows on the same line, after advancing to the indentation width. Subsequent output lines are indented. ๐ธ
Syntax:
.TP [width]
head \" one line
body
The width argument is a roff(7) scaling width. If you specify it, it's saved for later paragraph left-margins; if unspecified, the saved-or-default width is used. ๐ซถ
TQ ๐ถโ๐ซ๏ธ
Like TP, except no vertical spacing is inserted before the paragraph. This is a non-standard GNU extension and it's very rarely used, even in GNU manual pages. ๐
UC ๐ฐ๏ธ
Sets the volume for the footer, for compatibility with man pages from BSD releases. The optional first argument specifies which release it's from. This macro is an extension that first appeared in 3BSD. โจ
UE ๐
Ends a uniform resource identifier block that was started with UR. This is a non-standard GNU extension. ๐ซถ
UR ๐
Begins a uniform resource identifier block. Also a non-standard GNU extension. Syntax:
.UR uri
link description to be shown
.UE
YS โ
Ends a synopsis block that was started with SY. This is a non-standard GNU extension. ๐
in ๐ฅ
Indent relative to the current indentation:
.in [width]
If width is signed, the new offset is relative. Otherwise, it's absolute. This value gets reset upon the next paragraph, section, or sub-section. ๐
โจ Line Macros โจ
Line macros are only scoped to the current line โ that's their whole thing. The body is zero or more arguments. But plot twist: if a macro is scoped to the next line and its line arguments are empty, then the next line (which has to be text, bestie) gets used instead. So like:
.I
foo
is literally the same as .I foo. ๐ซถ
And now the messy part:
- If next-line macros get invoked consecutively, only the last one is used. ๐
- If a next-line macro is followed by a non-next-line macro, an error is raised. ๐
The syntax goes like this:
.YO [body...]
[body...]
And here's the full lineup of line macros, with how many args they eat, where they're scoped, and any receipts:
ATโ arguments:<=1, scope: currentBโ arguments:n, scope: next-lineBIโ arguments:n, scope: currentBRโ arguments:n, scope: currentDTโ arguments:0, scope: currentEEโ arguments:0, scope: current (Version 9 AT&T UNIX)EXโ arguments:0, scope: current (Version 9 AT&T UNIX)Iโ arguments:n, scope: next-lineIBโ arguments:n, scope: currentIRโ arguments:n, scope: currentOPโ arguments:>=1, scope: current (DWB)PDโ arguments:1, scope: currentRBโ arguments:n, scope: currentRIโ arguments:n, scope: currentSBโ arguments:n, scope: next-lineSMโ arguments:n, scope: next-lineTHโ arguments:>1, <6, scope: currentUCโ arguments:<=1, scope: currentinโ arguments:1, scope: current (roff(7))
๐งฑ Block Macros ๐งฑ
Block macros are built different: they've got a head and a body. Just like the in-line ones, the head is scoped to the current line and โ in exactly one situation โ the next line (yes, the same next-line stipulations from "Line Macros" apply here too, no cap).
The syntax:
.YO [head...]
[head...]
[body...]
So when does the body scope actually close? Depends:
- section โ closed by
SH - sub-section โ closed by a section or
SS - paragraph โ closed by a section, sub-section,
HP,IP,LP,P,PP,RE,SY, orTP
And ngl: no closure refers to an explicit block closing macro. That's just how it is.
Also, as a rule, block macros may not be nested. So calling a block macro while another block macro scope is still open โ and that open scope isn't implicitly closed โ is syntactically incorrect. ๐ซ
Here's the whole roster:
HPโ arguments:<2, head scope: current, body scope: paragraphIPโ arguments:<3, head scope: current, body scope: paragraphLPโ arguments:0, head scope: current, body scope: paragraphMEโ arguments:0, head scope: none, body scope: none (GNU)MTโ arguments:1, head scope: current, body scope: toME(GNU)Pโ arguments:0, head scope: current, body scope: paragraphPPโ arguments:0, head scope: current, body scope: paragraphREโ arguments:<=1, head scope: current, body scope: noneRSโ arguments:1, head scope: current, body scope: toRESHโ arguments:>0, head scope: next-line, body scope: sectionSSโ arguments:>0, head scope: next-line, body scope: sub-sectionSYโ arguments:1, head scope: current, body scope: toYS(GNU)TPโ arguments:n, head scope: next-line, body scope: paragraphTQโ arguments:n, head scope: next-line, body scope: paragraph (GNU)UEโ arguments:0, head scope: current, body scope: none (GNU)URโ arguments:1, head scope: current, body scope: part (GNU)YSโ arguments:0, head scope: none, body scope: none (GNU)
One more lil rule: if a block macro is next-line scoped, it may only be followed by in-line macros for decorating text. That's it, that's the boundary. ๐
๐จ Font handling ๐จ
In man documents you've got two ways to pick a font: the "Physical markup" macros, or roff(7)'s \f font escape sequences. Both valid, bestie. โจ
Here's the tea on how long each one sticks around:
- In text lines, the effect of manual font selection by escape sequences only lasts until the next macro invocation.
- In macro lines, it only lasts until the end of the macro scope.
And heads up: macros like BR open and close a font scope for each argument. So it's giving very much per-argument energy. ๐
๐ SEE ALSO ๐
man(1), mandoc(1), eqn(7), mandoc_char(7), mdoc(7), roff(7), tbl(7)
๐ HISTORY ๐
The man language first showed up as a macro package for the roff typesetting system in Version 7 AT&T UNIX. Iconic origin story honestly. ๐๏ธ
The stand-alone implementation that's part of the mandoc(1) utility? That first appeared in OpenBSD 4.6. ๐ธ
๐ AUTHORS ๐
- Douglas McIlroy
<m.douglas.mcilroy@dartmouth.edu>โ designed and implemented the original version of these macros, wrote the original version of this manual page, and was the first to use them when he edited volume 1 of the Version 7 AT&T UNIX manual pages. main character energy fr. ๐ - James Clark โ later rewrote the macros for
groff. - Eric S. Raymond
<esr@thyrsus.com>and Werner Lemberg<wl@gnu.org>โ added the extended man macros togroffin 2007. - Kristaps Dzonsons
<kristaps@bsd.lv>โ wrote themandoc(1)program and this man reference. ๐ซถ
and that's the whole page bestie!! ๐ This one ships from Debian, dated August 5, 2021, and it's page MAN(7) โ go forth and write some gorgeous man pages, you absolute legend ๐ โจ๐ฆ
๐ฆ where this page comes from
- alpine 3.22: mandoc-doc 1.14.6-r13 ยท ISC
- alpine 3.23: mandoc-doc 1.14.6-r14 ยท ISC
- alpine 3.24: mandoc-doc 1.14.6-r15 ยท ISC
- nixos 26.05: mandoc 1.14.6
- nixpkgs unstable: mandoc 1.14.6
- opensuse-leap 16.0: mandoc 1.14.6-160000.2.2 ยท ISC
- opensuse-leap 16.0: mandoc 1.14.6-160000.2.2 ยท ISC
- opensuse-leap 16.0: mandoc 1.14.6-160000.2.2 ยท ISC
- opensuse-leap 16.0: mandoc 1.14.6-160000.2.2 ยท ISC
- Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
- Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2017 Anthony Bentley <bentley@openbsd.org>
- Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms