How to create your own man pages

-- PART II

In this second and final part we will be talking a look at the syntax of a man page, which will hopefully be the final thing you need to create your own man pages with the help of the example code that was given above.

General Macros

."

The comment macro
Any text following a comment macro is not interpreted by groff.

Example:

.\" manpage for ppenv
.\" Contact [email protected] to correct errors or typos

.TH

The Title Header
Every man page should start with this macro that sets the header and footer information of a man page, and it has the following format:

.TH [name of program] [section number] [center footer] [left footer] [center header]

The options are self explanatory. But it is important to notice that despite being optional, they are a standard of a good man page and you should use them all, as exemplified below.

Example:

.TH ppenv 1 "01 August 2016" "version 1.3.1" "ppenv manpage"

.SH

The Section Header
Man pages contents are divided into section headers as it was described on the General Layout in the first part of this tutorial. These section headers (not to be confused with man section numbers) are defined with the .SH macro. And it has the following format:

.SH [section name]

Example:

.SH NAME
.SH SYNOPSIS

groff will always convert [section name] to bold and any text written below .SH macro will be indented to the right.

Two of these section headers deserve a special mention, and I will talk about them now...

.SH NAME

This section header is of special interest because it is used by commands like whatis and apropos to output information about the man page. .SH NAME should always respect the following format:

.SH NAME
<program_name> - <oneline_description>

Example:

.SH NAME
ppenv - print the current python environment

If respected, this format will allow the whatis, apropos and man -k commands to output summary information about the manual page, which is usually very helpful in order for this man page to be included in documentation search queries.

$ whatis ppenv
ppenv (1)            - print the current python environment
$ apropos environment
ppenv (1)            - print the current python environment
baudrate (3ncurses)  - curses environment query routines
check-language-support (1) - returns the list of missing packages in order to provide a complete language environment
clearenv (3)         - clear the environment
dbus-update-activation-environment (1) - update environment used for D-Bus session services
Dpkg::BuildEnv (3)   - track build environment
env (1)              - run a program in a modified environment
environ (7)          - user environment
[...]

.SH SYNOPSIS

Man pages tend to all follow a more or less strict set of conventions regarding the way a command syntax should be represented. You can see many examples for existing man pages. But keep the following conventions in mind.

  • Optional arguments should be placed between square brackets: ppenv [OPTION]
  • If more than one argument is allowed, you can place an ellipsis after the specification: ppenv [OPTION]...
  • You don't need to name arguments. Just the string 'OPTION' is enough and is the usual convention.
  • Parameters are different in that they don't start with an hyphen or double hyphen. They are called positional parameters and usually come last in the command syntax specification. Parameters must be named: ppenv [OPTION]... [DIR]
  • Naming parameters is not an art. If it is a filepath, call it PATH, if it is a directory call it DIR, if it is the name of a file, call it FILE, etc...

When in doubt try to consult other man pages and study what the author did.

Font Attributes

Fonts are controlled by the .B, .I and .R macros representing bold, italics and roman, respectively. Roman is the standard (default) format. In addition, every two of these formats can be combined to produce an output that alternates between each format on every parameter.

.R   Roman format
.B   Bold format
.I   Italics (underline on most terminals)
.RB  Alternate between Roman and Bold
.RI  Alternate between Roman and Italics
.BR  Alternate between Bold and Roman
.BI  Alternate between Bold and Italics
.IR  Alternate between Italics and Roman
.IB  Alternate between Italics and Bold

.R This is some text -> This is some text
.B This is some text -> This is some text
.I This is some text -> This is some text
.RB "This " "is " "some text" -> This is some text
.RI "This " "is " "some text" -> This is some text
.BR "This " "is " "some text" -> This is some text
.BI "This " "is " "some text" -> This is some text
.IR "This " "is " "some text" -> This is some text
.IB This is some text -> Thisissometext

Spaces are important since they are argument separators to a macro. This is why the last line above displays without any spaces; they were interpreted by groff as the .IB arguments separator and not included in the output. For spaces to be considered, arguments must be enclosed in double quotes along with any necessary spaces.

Keep in mind that in many common terminals (and this is also true of the mate-terminal), italic fonts aren't supported. Italic text will instead be rendered as underline.

Paragraphs

Paragraphs include a series of macros that control paragraph format in different ways.

.br

The new line
The .br (lowercase) macro simply inserts a new line, without any paragraph extra space.

Example:

.BR $ " pyenv shell --unset"
.br
.BR $ " cd ~/Projects/Scripts"
.br
.BR $ " ppenv -c"

.PP

The Simple Paragraph macro
Creates a new simple paragraph. Paragraphs are formatted by groff with an extra line of empty space.

Example:

.PP
Copyright (c) 2016 Mario Figueiredo
.PP
This document is part of the ppenv software.

.RS and .RE

Start/End Indent
Indents to the right all lines (or paragraphs) between .RS (start) and .RE (end) to the right.

Example:

The following will show a typical output on a directory with a git repository
with the 'develop' branch checked out.
.PP
.RS
.BR $ " pyenv shell 3.5.2 2.7.11"
.br
.BR $ " ppenv -c"
.br
python: *3.5.2 2.7.11 (shell)    git branch: develop
.RE

groff will format the above as:

The following will show a typical output on a directory with a git repository with the 'develop' branch checked out.

       $ pyenv shell 3.5.2 2.7.11
       $ ppenv -c
       python: *3.5.2 2.7.11 (shell)    git branch: develop

.IP

Indent Paragraph
.IP takes one parameter and prints it in the current location. Anything on the next line will start printing in the same line, but indented as a block to the right. This macro (and its cousin below) is usually used on the OPTIONS and FILES section header of a man page.

Example:

.SH OPTIONS
.IP -v
print more verbose information
.IP -r
enable recursion
.IP "-f FILE"
Specify the output FILE

The above will produce the following output:

OPTIONS
      -v     print more verbose information

      -r     enable recursion

      -f FILE
             Specify the output FILE

.TP

The Tag Paragraph
Similar to .IP, but allows you to format its parameter (.IP parameters are always printed in Roman).

Example:

.SH OPTIONS
.TP
.B -v
print more verbose information
.TP
.B -r
enable recursion
.TP
.BI -f " FILE"
Specify the output FILE

The above will produce the a similar output to the .IP example. However the options will be formated as bold, and the -f option will be formated as: -f FILE (bold followed by italic)

Sourcing man pages

Manual pages can be sourced from other manual pages with the .so (lowercase) macro. Similar to a link, sourcing will instead embed the target man page into the current page and interrupt the rest of the original page processing.

This can be useful if one wishes, for instance, to properly document a program or feature that can be called by different names (grep, egrep, printf, fprintf, etc).

Example:

.TH appenv 1 "01 August 2016" "version 1.3.1" "appenv manpage"
.so man1/ppenv

The above will create a man page that simply points to the ppenv man page every time someone uses the command man appenv. The actual documentation for the appenv alias will be written in the ppenv.1 man page. This is how egrep and fprintf man pages are done, for instance.

It is important to specify the section folder (in this case man1/) in the .so macro parameter.

Converting man pages

groff can also be used to convert man pages to other formats, including html, postscript, plain ascii, or pdf.
However special care must be taken on some formats and the use of the col command may be required to remove certain invisible control characters that are still printed by groff.

# correctly convert a man file to ascii in UTF-8 format
$ groff -K utf8 -mandoc -Tutf8 ppenv.1 | col -bx > ppenv.txt

-- END OF TUTORIAL

4 Likes