# Writing Documentation - Part 1: POD

#### By Christoph Spiel

The title, Writing Documentation, sounds somewhat formal. However, in this article I refer to documentation a broad sense, not only to documentation accompanying a particular piece of software, but to any related textual pieces of information. This textual information could be as short as a few lines and, for example, describe how to to start a program with all of its command line options and environment variables set correctly. On the other hand, the text could be several tens of thousands lines long, elaborating all the tricks a group of users has learned over the years while using a large software system.

## Introduction

With today's GNU/Linux distributions, the aspiring documentation writer immediately finds herself in fat city: there are several systems to chose from! Three documentation systems will be introduced in this article series. Here, I start with POD. Next month I'll address LaTeX in conjunction with latex2html, and in part 3 DocBook.

The systems cater different documentation needs and all have their highs and lows. But before assessing the pros and cons of the different systems, let me put up some requirements, which I want to impose on the documentation systems.

The sources of the documentation should be:

Portable
As of December 2001, writing a "portable" file almost implies using 7-bit ASCII to encode characters. Today, 7-bit ASCII is the only encoding that works on a huge number of computers. In the future, hopefully, it will mean Unicode. Unicode can represent many more characters than ASCII does and will be as portable.

Requiring portability ensures that the texts' sources can be read and modified on a wide variety of computer systems, thereby making the documentation accessible to other programmers, which is what Open Source Software is all about.

Searchable
Data on a computer is only as good as the access to it. -- Sounds like a commonplace, but we easily forget that documentation ought to be maintained just like source code is. We want to be able to search existing documentation for, say, a particular term or identifier. Therefore, the source of the documentation should at least be amenable to standard searching tools like, for example, the grep family (grep, agrep, rgrep, sgrep) of tools.
Modular
Unless we write a short note, it is desirable that the document sources can be split into logical parts, for example sections, and the collection of all the source files is still processed as a whole by the documentation system.
For documentation to be open'' (as in Open Source''), the source should be easy to read, and the system to generate the final output should be simple to learn. A documentation system will be better accepted if the writer -- and later possibly the maintainer -- can concentrate on contents rather than syntactic quirks or obscure tool chains.

Just as I require certain features in the documentation's source format, so I do with the output.

Multiple Output Formats
The documentation system must be capable of producing different output formats -- the more formats the better. At least HTML and PostScript (some users prefer PDF) must be supported, one for on-screen reading, the other for print outs.

HTML support in turn requires hyperlinks'', this is, references between documents or parts thereof that can be followed in a convenient way. References also help to implement the Modular Requirement in my list of source format features.

Automatic Reference Generation
All references should be resolved automatically as far as this is possible. For example, the system should resolve cross references within in the document and should allow for footnotes or sidenotes to be placed and numbered without the help of the writer. The index and bibliography also should be generated automatically.

Let us now look at a particularly easy to use format: Perl's Plain Old Documentation.

## Perl's Plain Old Documentation (POD)

The Plain Old Documentation'' system that ships with every Perl distribution is simplest documentation system in my selection. It is simple to learn, simple to use, but -- and I hesitate to write therefore -- also the most limited of the three. Anyhow, the article you are currently reading (yes this one!) has been prepared with POD. If it is good for the goose, it can't be bad for the gander...

The big advantages of POD are

• It comes with Perl. So you probably already have it on your Linux box. Try
    pod2man --help


to see if it is installed.

• It offers a small and well-though-out set of document structuring and markup instructions.
• The POD translation tools render at least four different output formats: HTML, UN*X manual pages, LaTeX (which serves as base for a further translation into PostScript), and plain ASCII text.

### Syntax

The POD format defines three different kinds of paragraphs. Paragraphs are separated from each other by one or more completely (!) empty lines.

Ordinary Paragraph.
Any line that does not start with at least four spaces or an equal sign is considered ordinary text. Paragraphs are separated by one or more empty lines. This means, the documenter simply writes one paragraph after the other with at least one blank line between each pair.

Ordinary paragraphs will be filled and justified (if the output format allows for justification) when output.

Verbatim Paragraph.
Lines indented by four or more spaces are considered verbatim text. They are output exactly as typed. All formatting instructions that we will see later, are disabled in verbatim paragraphs.
Command Paragraph.
Command paragraphs start with an equal sign ='' in column zero, immediately followed by an identifier. Usually, command paragraphs consist of single lines. Yet they are syntactically paragraphs, because they are separated by blank lines before and after them.

#### Sectioning

Text is sectioned by =headN commands, like

=head1 primary_heading

=head2 secondary_heading

=head3 tertiary_heading

which also define the section headings primary_heading, etc.. How many heading levels (this is largest N permitted) actually are accepted, depends on the POD-to-something converter. For example, pod2man allows only two levels, pod2html allows up to six levels.

I have added line and column numbers to the source of the examples. The line numbers do not appear in the real source. They are included here to point out the empty lines that must separate the command paragraphs, this is, those starting with an equal sign in column 0. Additionally, I have added a column-number ruler at the beginning of the next example to clarify where column 0 starts.

Example:

                    1         2         3         4          5
0123456789012345678901234567890123456789001234567890
2
3    The physical parts of your computer are called "hardware".
4
6
7    The CPU is the most important part of your computer.
8
10
11    Mass storage devices store data permanently.
12
14
16
18
20
22
23    This is where the trouble starts ...


#### Lists

Itemized, enumerated or description lists are produced with

=over N

=item label

=item label

...

=back

where =over N starts a list that is indented at least N spaces, and extends until =back. Depending on the first label the POD-to-something translators generate an itemized list (label = *), a numbered list (label = 1) or a description list (label starts with a letter).

Example: itemized list

Again, I have added line numbers to alert the reader of the (many) empty lines used for separating the command paragraphs.

Source

     1    =over 4
2
3    =item *
4
5    Fruit, particularly non-imported fruit like ...
6
7    =item *
8
9    Though not tasty, vegetables should make up a large part of your
10    daily diet.
11
12    =item *
13
14    Fish is much easier digestible than meat.  Therefore, ...
15
16    =back


Result

• Fruit, particularly non-imported fruit like ...
• Though not tasty, vegetables should make up a large part of your daily diet.
• Fish is much easier digestible than meat. Therefore, ...

Example: enumerated list

Source

     1    =over 4
2
3    =item 1.
4
5    Ensure that the power switch is in position "OFF".
6
7    =item 2.
8
9    Plug in the power cord.
10
11    =item 3.
12
13    Switch the power switch in position "ON".
14
15    =back


Result

1. Ensure that the power switch is in position OFF''.
2. Plug in the power cord.
3. Switch the power switch in position ON''.

Example: description list

Source

     1    =over 8
2
3    =item Robert
4
6
7    =item Jimmy
8
10
11    =item John-Paul
12
13    Bass guitar
14
15    =item John
16
17    Drums and percussion
18
19    =back


Result

Robert
Jimmy
John-Paul
Base guitar
John
Drums and percussion

#### Inline Markup Commands

Within Ordinary Text, several markup commands are recognized. All markup commands start with a single capital letter and enclose their argument within angle brackets: LETTER<argument>. The argument can consist of multiple words, which can span more than one line.

I<argument>
Render argument in italics. I corresponds to the HTML tags em and var, thus it is primarily used for emphasizing words or marking up variables.

Examples:

• Do not remove your Linux kernel!

is produced by

    Do I<not> remove your Linux kernel!

• Use cd directory to change your working directory to directory.

is generated with

    Use B<cd> I<directory> to change your
working directory to I<directory>.

B<argument>
Render argument bold. B corresponds to the HTML tag b. It is used to emphasize in text and to mark up program names or switches.

Examples:

• Always shut down your machine before switching it off.

comes from

    B<Always> shut down your machine before switching it off.

• podchecker accepts the options -warnings and -nowarnings.

is the result of

    B<podchecker> accepts the options B<-warnings>
and B<-nowarnings>.

C<argument>
C marks up code or anything else which is to be taken literally. The corresponding HTML tags is are code,  samp, and tt.

Examples:

• Every C-program must have a function called main.

is generated by

    Every C-program must have a function
called C<main>.

• Boolean false is represented by [1 1 0], and boolean true by [1 1 1].

is produced by

    Boolean false is represented by C<[1 1 0]>,
and boolean true by C<[1 1 1]>.

L<reference> or L<description|reference>
Link to an existing reference. If description is omitted, the link's text is reference, otherwise it is description. Using L is a bit tricky. Therefore, I have devoted the next section to it.

#### Cross References

The L-command is distantly related to HTML's <a href = "reference">description</a>, however, in POD, reference is not a general unified resource locator (URL).

reference can only refer to (automatically by the POD-to-something translator) generated labels. These labels are inserted for every  =head and =item. The label associated with  =head heading is heading downcased, but otherwise unchanged, e.g.

    =head1 A Multi-Word Heading (MWH)


automatically gets assigned the label

    a multi-word heading (mwh)


The labels of =items are prefixed by item_, spaces are replaced by underscores, and non-alphanumeric characters are replaced by their hexadecimal ASCII code prefixed by a percent sign. Anybody expected an easy rule? So, one of the items in this article,

    =item Automatic Reference Generation.


has the label

    item_Automatic_Reference_Generation%2E


because the ASCII number of the period is 46 in decimal or 2e in hexadecimal.

Example:

Source

    =head1 Introduction

    Section L<"concepts"> introduces the basics of the field.

    =head1 Concepts

    ...

    =head1 Synchronization

    =over 4

    =item Deadlocks

    =item Race Conditions

    =item Recovering from Deadlocks

    =back

    How to cope with deadlocks was already discussed in


Result

# Introduction

Section concepts introduces the basics of the field.

...

# Synchronization

Race Conditions

The L-command is very limited in its use, for the writer cannot insert places to refer to with an L-command; HTML-like anchors'' are missing.

A second limiting factor are some POD translators trying to be smart and decorate link with additional text. For example, pod2latex mangles both references to items in the above example:

How to cope with deadlocks was discussed in the \textsf{Deadlocks$|$"item\_Deadlocks"} entry elsewhere in this document, and the \textsf{Recovering from Deadlocks$|$"item\_Recovering\_from\_Deadlocks"} entry elsewhere in this document.

where I have underlined the words added by pod2latex. Clearly, we want a better mechanism. The mechanism exists in format-specific paragraphs.

## Format-Specific Paragraphs

We have just seen that the L-command is somewhat difficult to control. Why can't we simply use a HTML-reference? The terse answer, because POD is not HTML'', leads to the solution. If we had a way to say this text is for HTML, this line is for LaTeX, and this paragraph is for ''SnaFoo, we could use the specific markup provided by these formats.

The special command

=for format paragraph_of_text

tells a translator to look at format before processing paragraph_of_text. If the translator feels responsible for handling format, it transforms paragraph_of_text according to its own rules, otherwise it completely ignores the paragraph. The second part of the translator's name usually specifies which format it takes care of. For example, pod2man transforms =for man paragraphs, pod2html processes =for html paragraphs, and so on.

As all command paragraphs, a =for format paragraph ends at the first completly empty line that follows the introducing =for.

A consistent document structure will show forks'' whenever specific formats are used, because a =for format clause ought to appear for each desired output format, otherwise we punch a logical holes into the document.

    This is an ordinary paragraph, which is processed by all
translators.

    =for html <p>This paragraph only appears if the file is processed
with <b>pod2html</b>.</p>

    =for latex This very paragraph is only treated by {\bf pod2latex}.

    =for text I am a paragraph for the *pod2text* formatter.

    We now continue with the ordinary text for all formatters.


The translators ignore unknown formats, which means we can invent special paragraphs for our own purposes! For example, to comment out'' a paragraph, write

    =for comment Can someone clarify the next section?


Another popular use is the emacs format :-) To switch emacs into text-mode when preparing a POD-file, start the file with

    =for emacs -*- text -*-


or end it with

    =for emacs
Local Variables:
mode: text
End:


The emacs-users who are using the hyperbole add-on can convert their "dumb" POD-files into hyper-linked collections (well -- hyperbole can do a lot more than that, but hyperlinks are a beginning) of files with

    =for hyperbole <(std-reference)>


where <(std-reference)> is a hyperbole button taking you to another file which holds the reference documentation of std when you click the button in emacs.

### Programs That Work With POD

• pod2html, pod2man, pod2latex, pod2text

Translators from POD to HTML, UN*X manual pages, LaTeX and plain text respectively.

• podchecker

Simple syntax checker for POD files.

### Pros And Cons of POD

Pro
• Simplicity
• Conversion speed
Cons
• Lack of tables
• No program to generate an index supplied by default