Write Perl Pod That Survives the Formatter
A Pod page that looks fine in your editor can still fall apart the moment podchecker gets hold of it. This guide gets you a page with the expected structure, readable examples, and a passing syntax check. It is a writing and review task, not a command with switches: perldocstyle is the name of a man page supplied by the perl-doc package.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 20 minutes for a short page, plus however long it takes to test the behaviour you are documenting. The examples here use Perl 5.38.2 from Ubuntu's perl-doc package, installed locally as version 5.38.2-3.2ubuntu0.6. The style principles are useful elsewhere, but the installed man page is the authority for this machine.
Before you start
Read the installed guide through
perldoc:perldoc -l perldocstyle perldoc perldocstyle | lessThe first command should print
/usr/share/perl/5.38/pod/perldocstyle.pod. The packaged man page is also available withman perldocstyle. There is no separateperldocstyleexecutable to run.Check that the Pod validator is installed:
command -v podcheckerOn this system it is
/usr/bin/podchecker. If it is missing, install the distribution package that supplies your Perl documentation tools before continuing. That is an administrative change, so use your normal privileged package workflow and review the package name for your distribution.
1. Start with the document skeleton
Create a file named after the subject, such as lib/Inventory/Report.pod or pod/perlwarehouse.pod, and keep the source in version control. For a core-style standalone page, begin with UTF-8 encoding, then a literal NAME heading and one short name-and-purpose paragraph.
=encoding utf8
=head1 NAME
perlwarehouse - read warehouse stock records
=head1 DESCRIPTION
This page explains the file format and the Perl interface used to read
warehouse stock records. It is intended for maintainers who already know
basic Perl syntax.
=head1 SYNOPSIS
use Warehouse::Report;
my $report = Warehouse::Report->new(path => $path);
print $report->total_items, "\n";
=head1 FILE FORMAT
The input is one UTF-8 record per line. The first field is the item code.
=head1 SEE ALSO
L<perlpod>, L<perlpodstyle>
=cut
- DESCRIPTION states scope. Say what the page covers and what it assumes.
- SYNOPSIS stays brief. A reference page can put one before the description, but do not turn it into an exhaustive catalogue: show a few common, best-practice uses, then explain them in the sections that follow.
2. Structure the Pod for skimming
Choose headings for the reader's route through the subject. Use additional top-level headings in capitals when the topic needs them, and put narrower subjects below them. A page about a module might use METHODS, ERROR HANDLING, and SEE ALSO; a page about a language feature might need different names. The guide does not require a fixed list beyond the familiar man-page shape.
- Keep lines short. Fit each source line to 72 characters or fewer. This is a rule for the Pod source, not a promise that every formatter will display exactly 72 columns, but short lines make reviews, terminal output, and later edits less surprising.
- Split long blocks. Break up a long block with meaningful subsections when a reader could reasonably stop and resume later.
- Mark up code and names. Write
C<open>for a function name,C<$path>for a variable, andL<perlpod>for a cross-reference. A link can have separate visible text and a target, for exampleL<Pod syntax|perlpod>. - Link from SEE ALSO. Point to a relevant man page or primary web page; a link does not replace the formatting needed to identify the thing in the sentence.
3. Write examples that explain themselves
Keep a code block as small as possible while still showing the idea. Follow the layout rules of perlstyle, and use names that describe their jobs: $warehouse_report tells the reader more than $foo. Comments are useful when they clarify a non-obvious line, but they should not compensate for an example that is too large.
Give function arguments meaningful names and use the right form for the object being documented. If the page describes a generic scalar, say so; if it expects a file path, call the argument PATH or $path consistently. Put literal angle brackets in Pod markup where required rather than relying on a formatter to guess what code means.
Use straight quotation marks. The source guide permits UTF-8, but typographic quotes still make source maintenance and terminal reading needlessly awkward. In Pod, render an em dash as two hyphens if one is genuinely needed. Prefer a full stop or a new sentence when that is clearer.
4. Check the file before review
Run the syntax checker against the actual file, not a pasted fragment:
podchecker lib/Inventory/Report.pod
A clean file ends with output similar to lib/Inventory/Report.pod pod syntax OK and a zero exit status. Confirm both the rendered view and the status:
perldoc lib/Inventory/Report.pod | less
podchecker lib/Inventory/Report.pod
test $? -eq 0 && echo "Pod check passed"
Tip
podchecker tests Pod syntax, not whether your API claims are true. Exercise the documented program separately, and check that names, defaults, errors, and version notes match the implementation. If an example changes files, use a temporary directory while testing.
Warning
Do not run an unreviewed example as root. Documentation review is not a reason to grant extra privileges.
Common traps to remove during review
- Missing identity. A page without the
NAMEentry is harder for formatters and readers to classify. - Unstated audience. Say whether the reader needs basic Perl, a particular module, or knowledge of an internal format.
- Example overload. Replace a long program with one focused example and explain the important part nearby.
- Vague names. Replace throwaway variables with names that show relationships and purpose.
- Stale history. Document current behaviour first, and mention older behaviour only when a maintainer is likely to meet it.
- Hidden cross-references. Finish with useful
SEE ALSOlinks and make their visible text describe the destination.
For a standalone core page, extra copyright or licence sections are normally unnecessary because the source repository supplies those terms. An AUTHOR or CONTRIBUTORS section is optional when credit helps. Module documentation follows its own packaging and authorship conventions, so check perlpodstyle as well as this guide before treating the skeleton as universal.
Done means
- Skeleton in place. The file begins with
=encoding utf8and a clearNAMEentry. - Audience stated. The audience, purpose, common usage, and relevant caveats are explicit.
- Style followed. Headings, links, inline markup, examples, and line wrapping follow the Pod guidance.
- Checks pass.
podchecker FILEreports success, andperldoc FILEis readable. - Behaviour verified. The documented behaviour has been tested independently of the markup check.