Simple Command

Consider a simple UNIX command hi that prints hello, world and exits. Let's create a manual page hi.1 documenting this command. In this example, I'll begin with the full manual. In later examples, we'll build up the manual piece by piece.

.Dd May 30, 2011
.Dt HI 1
.Os
.Sh NAME
.Nm hi
.Nd print \(dqhello, world\(dq
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
Print
.Qq hello, world
and exit.

How to display this manual page depends on the system you're using.

Traditionally, the command for formatting UNIX manuals for a terminal is nroff. For now, let's stick with that.

To display output, you must invoke nroff as nroff -mandoc file. The mandoc flag indicates that input is in mdoc. Hereafter, I'll refer to nroff simply as the formatter to avoid confusion, as there are many available mdoc formatters.

NAME

hiprint "hello, world"

SYNOPSIS

hi

DESCRIPTION

Print “hello, world” and exit.

Let's start by studying the input and output. We can see most of the text translated into output, for instance, the capitalised NAME input is left-justified and in bold text. Same with SYNOPSIS and DESCRIPTION, although the .Sh text before this terms is missing. We can even see the output sentence Print "hello, world" and exit spread over lines 10–12:

Print
.Qq hello, world
and exit.

Let's take a closer look at this fragment.

The .Qq is part of mdoc's instruction syntax. Input lines beginning with a dot are instructions to the formatter called mdoc macros, or just macros for short. The macro name is a terse two or three-character word following the dot, for example, Qq. The name of a macro tersely hints at its function. The words following the Qq to the end of line are arguments in the scope of the macro.

Scope, a technical term in the field of programming languages, refers to the body of input within the context of an instruction or variable. In mdoc, a macro's scope is the block of text and instructions in the formatting context of that macro. Looking at the input and output, we can infer the scope of Qq by seeing what's surrounded by quotes (the formatting, in this case).

.Qq hello, world
Print “hello, world” and exit.

As we explore more and more macros in this book, we'll see that each macro follows one of a handful of scope rules. It's already clear that Qq is limited in scope to its invocation line. But notice that the formatter recognised the content between Sh macros as requiring indentation. So it's clear that mdoc also has a concept of multi-line scope. In fact, Sh has both line arguments, for the name of the section; and multi-line arguments, for section content.

.Sh SECTION 1
Section text.
.Sh SECTION 2
New section text.

Furthermore, the existence of Qq within the Sh scope means that scopes may be nested. In the next section we'll see how multiple macros may even be specified on a single line.

.Sh SECTION 1
Section text.
.Sh SECTION 2
.Qq Section text nested in a quote.

We can visualise this scoping as follows, with an outer scope and inner scope:

.Sh SECTION 2
.Qq Section text nested in a quote.

Now let's return to hi.1 with this new knowledge of macros and scopes.

We see seven macros in total, Dd, Dt, Os, Sh, Nm, Nd, and Qq. We know now that Qq encloses its arguments in double-quotes, Sh begins a named section with indented multi-line arguments.

Of the remaining macros, Dd accepts the last modification date of the manual in month day, year format. Dt refers to the manual's title, HI, and its category, 1. Numbered manual categories are UNIX conventions, but applicable to any operating system. We'll explore more standard categories throughout this book. Note that HI is uppercase: by convention, Dt should always accept a capitalised document title. We'll talk more about titles and sections in later chapters of this book. For now, let's assume that a category number identifies the topic of the manual, where 1 refers to utilities.

Next, Os indicates the operating system of the system running the formatter. If left unspecified, the formatter will return the current operating system (e.g., OpenBSD 4.9, Linux 2.6.32-5, or Microsoft Windows XP).

.Dd May 30, 2011
.Dt HI 1
.Os \" Current operating system.

Note that text following the \" marker is an mdoc comment, which has the following syntax:

Text. \" Comment to end of the line.
.\" Extending across the full line.

Comments are line-scoped, like Qq:

.\" .Sh NAME

Moving along, Nm accepts the manual's name. This differs from the title, Dt, in that a single manual may document multiple components. We'll see examples of this in later chapters. Finally, Nd accepts a brief, one-line description of the command.

.Sh NAME
.Nm hi
.Nd print \(dqhello, world\(dq

You can see that we re-invoke Nm in the SYNOPSIS, only without arguments. The formatter is smart enough to fill in its argument with the last supplied argument, in this case being hi.

Since our simple command has no command-line arguments, its invocation is simply the command name.

.Sh SYNOPSIS
.Nm

Piecing this all together, we now have the following.

.Dd May 30, 2011
.Dt HI 1
.Os
.Sh NAME
.Nm hi
.Nd print \(dqhello, world\(dq
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
Print
.Qq hello, world
and exit.

In this example, you've noticed that \(dqhello, world\(dq has the same behaviour of the Qq invocation. In mdoc, quotation marks signify literal strings. Thus, we used an escape character \(dq to render ".

You may ask why not just use Qq, such as

.Nd print
.Qq hello, world

For the time being, assume that Nd must have its scope on the invocation line. Strictly-speaking, we could have written

.Nd print "hello, world"

but this encourages dangerous behaviour in assuming that quoted arguments may not affect output. This isn't always the case! We'll see later how quoted terms on macro lines change the grouping of arguments — at times non-intuitively.

Before moving on to the next section, let's look quickly over our checklist for a well-formed manual.

Did I describe the calling syntax of the command?
Yes. It was only the name of the macro (no arguments or flags).
Did I describe each flag and argument of the command?
There were none, so yes.
Did I describe the command's operation?
Yes, it prints hello, world and exits.
Did I describe the command's exit status?
No, we only mentioned that it exits.
Did I describe referenced files and environment variables?
This is not applicable.

To the effect of the exit status, let's modify the DESCRIPTION slightly for clarity.

.Sh DESCRIPTION
Print
.Qq hello, world
and exit 0.

Of course, our command must actually do so! For simplicity's sake, let's assume that this is the case.

With our simple, well-documented example in mind, let's move on to a more realistic UNIX command.

Last edited by $Author: kristaps $ on $Date: 2011/11/04 22:24:07 $. Copyright © 2011, Kristaps Dzonsons. CC BY-SA.