CleanCode Perl Libraries
Multi-Lingual Library Maintainability
available: Perl not available: Java not available: JavaScript not available: Certified
not available: Testable
not available: Standalone
available: Diagnostic


Pod::HtmlTree - Creates a Perl documentation tree in HTML format.


        use Pod::HtmlTree;
        # '@someArgList' is an unordered list containing options, command files,
        # package dirs, and package files, as described next.


Perl5.005, Pod::Html, Pod::Usage, File::stat, File::Basename, HTML::Template, Getopt::ArgvFile, Getopt::Long, File::Spec, File::Handy, Array::Slice, Data::Handy, HTML::XGenerator

(Needs Pod::Html 1.04 or greater for XHTML support.)


This module creates a set of HTML documentation from template files and from POD input contained in Perl files. You specify elements for which you wish to generate documentation and options to tailor your documentation. The elements and options may be specified either from the command line or a command file; typically the former is handy for one-shots or trials, the latter is easier for production purposes.

The standard pod2html module provides console documentation on a per-module basis, whereas pod2htmlTree adapts the style of javadoc (for creating Java documentation) to Perl, adding a few new features: template customization, standalone tool handling, capability bars, and cross-language support.

Packages, Modules, and Classes

A point of distinction to note: The terms package, module and class are often interchanged in Perl. I prefer the terminology distinctions of Java where, for example, and specify two modules or classes -- and -- contained in the package. The Perl corollary, then, is that Data::Dumper specfies the module contained in the Data package.

One can say then, in Perl, every class is a module, but not every module is a class. (In Java, by contrast, it is a symmetric relationship; every module is a class.)

Every package contains one or more modules or classes which are related. Hence, it makes sense to have some package-level documentation as well as module-level documentation. Most Perl documentation does not provide package-level documentation. In some ways, that makes sense, since the modules within any given package are probably written by different authors at different times with widely different intentions. But I submit that, since they are in the same package, they are related and worth describing. Hence Pod::HtmlTree provides a facility for this.

Documentation Tree Structure

The documentation tree will have the same structure as your Perl tree, (except for one exception noted below). So, for example, if you have a module Stuff::Module stored in Stuff/ in your Perl tree, the resultant documentation file will be Stuff/Module.html in your documentation tree. These will be rooted in sourcePath and targetPath, respectively. sourcePath and targetPath each default to the current directory if not specified. (Note that you should generally specify different roots for these.)

As mentioned above, there is one exception to the tree mirroring discussed. The standard use of Pod::HtmlTree involves documenting library modules, (.pm files) which are always used by including them in your application with a use or require statement. You may specify any number of directories containing library modules. But Pod::HtmlTree also allows you to specify one directory of tools or applications, (e.g. /my/bin). The tools/applications in that directory should be documented with pod per the conventions discussed here for standalone applications. To connect such a tool directory to a Pod::HtmlTree run, use the --tools option. This tool directory will not generally be in your library module tree, but rather elsewhere in your filesystem. For coherence of documentation, however, the created documentation directory is inserted into the documentation tree rooted at targetPath, just like all of your other library modules. The directory name is just the final component of the path name of the tool directory.

Example: Let sourcePath=/perl/lib, targetPath=/my/doc/tree, and tools=/usr/local/bin. Then, a module Stuff::Module, located in /perl/lib/Stuff/ will be documented in /my/doc/tree/Stuff/Module.html. And, a tool application, located in /usr/local/bin/ will be documented in /my/doc/tree/bin/genData.html.

File References

Referencing a file (a graphic, a style sheet, and so forth) is usually done in one of two ways: an absolute path (e.g. /usr/bin/my/cgi/...) or a relative path (e.g. cgi/xyz/...). Pod::HtmlTree provides a third technique (again borrowed from javadoc), a document-root relative path. In the body of any particular module, using either absolute or relative paths will work just fine. But in templates (e.g. perlpkg.thtml) which are re-used at different levels of the generated documentation tree, you need a way to refer to the root of the documentation tree no matter where you are. This is done via the { @docRoot } construct. Referencing a style sheet, for example, could be done like this

<link rel="stylesheet" href="{ @docRoot }/perlwin32.css" type="text/css">

Then, during generation of the documentation tree, { @docRoot } is updated at each level with the appropriate relative path. Note: in practice do not put any spaces between the braces and the @docRoot term. Spaces are used here so I can display the construct rather than interpret it.

Template Files

You may optionally tailor the template files to use in your documentation tree generation as listed below. The .thtml suffix indicates a template-HTML file which is filled in with variable data (courtesy of HTML::Template). All constructs in the file beginning with <TMPL_ are substitution directives. You should take care to leave them intact, though you may add or change formatting around them. For referencing other files, you may use document-root relative paths, as described in "File References".


Top-level template for the package table of contents used in targetPath/index.html.


Top-level template for the summary of packages and description used in targetPath/index.html. This template, when filled out, becomes perlmain.html.


Package-level template for the summary of modules and description used in targetPath/package/index.html.


Top-level template for the global index used in targetPath/index-all.html. This template, when filled out, becomes index-all.html.


Module-level template which provides a hyperlinked list of methods, functions, variables, etc. at the start of each section.


Module-level template which provides a hyperlinked list of methods, functions, variables, etc. in the table of contents at the top of the documentation page.


Module-level template which provides a navigation bar at the top and bottom of each documentation page. Includes buttons for main home, perl home, java home, global index, tools, and downloads.


Module-level template which shows a capabilities chart and checks off those which apply for each module. Capabilities include: whether the module exists in Perl, Java, and/or JavaScript; whether it is certified (i.e. has builtin regression tests), whether it is testable in a standalone mode, and whether it is diagnostic-enabled (see Data::Diagnostic).


Package-level template for the summary of tool applications (as specified via --tools). This template, when filled out, becomes tools.html.

Content Files

Content files, in contrast to template files, are complete HTML files. They do not have any dynamic substitutions, except for document-root relative paths (described in "File References"). The contents of the body element from each content file is inserted in the appropriate template file during documentation generation.


This optional file should contain a top-level description of your system (global to all your packages). It should be a valid HTML file. The contents of the body element in this file is inserted into the perlmain.thtml template when generating targetPath/index.html.


This optional file should contain a description of the collection of modules which comprise an individual package. It should be a valid HTML file. The contents of the body element in this file is inserted into the perlpkg.thtml template when generating targetPath/package/index.html. Example: For CleanCode, I've created CGI::PageValidator, CGI::PageGenerator, and CGI::PageSequencer modules. These are intimately related to each other, yet hardly related to other CGI::* modules. So the package.html file in my local CGI directory describes these three modules, not every existing CGI::* module.

While this file is optional, it is recommended, for this reason: the first sentence is inserted into perlmain.html for the module summary. If there is no first sentence (or no file at all), that package will show no one-line description in the top-level documentation page.

Auxiliary Files and Data

templatePath/*.html, *.gif, *.jpg, *.css

Any additional files which you wish to use in your documentation tree (images, style sheets, or other html files) should be placed directly in the templatePath directory. These will be copied over as-is to the targetPath directory.

Every generated documentation file can have the same header and/or footer by using the --header and --footer options. Since you define your header (or footer) in only one place, changing it later is simple. These --header and --footer options serve as simple templates.

You may interpolate the date and/or the time using two template functions: <TMPL_VAR date> and <TMPL_VAR time>. The current date or time will be inserted in the string where those markers are present.

For referencing other files, you may use document-root relative paths, as described in "File References".

These header/footer strings may contain \n and \t which will be translated into actual newlines and tabs, respectively. Note: In a command file, the standard Perl conventions apply to double-quoted vs. single-quoted strings, but off by one. If you use double quotes and insert just a \n, it will turn into a plain n. You must either use two backslashes, or switch to single quotes.

Generated Files

In addition to generating a .html file from each .pm file, there are numerous other files inserted into your documentation tree:


This top-level file is the entry point to your documentation. A dual-frame document, the left frame lists all your packages and modules (perltoc.html) with hyperlinks to load them in the right frame. The initial right frame contents is perlmain.html, a listing of package names and descriptions, plus whatever top-level description you provide in sourcePath/overview.html. You will also have top and bottom navigation bars which provide ready access to the global index, tool summary, other language modules, and your home page.


Listing of all packages and modules, used as the left-hand navigation pane in index.html.


Top-level summary of packages, plus global description, used as the right-hand content pane in index.html. Each package is summarized in a table containing its name and a one-line description, taken from the first sentence of the package.html file within its source directory.


This package-level corollary to perlmain.html, contains a listing of modules names and descriptions as directed by the perlpkg.thtml template, plus whatever description you provide in sourcePath/package/package.html. Each module is summarized in a table containing its name and a one-line description, taken from the first sentence of the source code file within its source directory. This page is loaded through a link in perlmain.html or a link in perltoc.html, both mentioned above.


This top-level file contains your global index of classes, modules, constructors, methods, functions, and variables which you have documented. It is generated from a template file of the same name. A quick-jump alphabet is provided at the top and bottom of the file for navigating right to a letter of interest. Each index entry identifies the type of object, the containing module or class, and provides hyperlinks to both the module and directly to the object within the module.


This top-level file contains your global tool applications list. It is generated from a template file of the same name. This contains essentially the same information as the standard package listing for the tool directory (inserted in the documentation tree just like any other package) but it packages the information differently, including dates and versions of the standalone tools.

targetPath/*.html, *.gif, *.css

Other support files used in the documentation tree.

Diagnostic Results

Pod::HtmlTree will report each step of documentation generation, including: each directory (package) it processes, each file (module) within the directory (the input Perl file and the output HTML file), whether the output file is already current with the input file, whether any required POD elements are missing, and the various index and summary file generations.

The standard pod2html translator is invoked for each Perl module. Any warnings from pod2html will also appear in the program output. Note, however, that Pod::HtmlTree is not able to determine whether there were or were not errors from pod2html. This means that, if you have not changed your input file, subsequent runs will report the output file is up-to-date, but it will still have the same uncorrected pod2html errors, even though it won't be reporting them.

The table of contents (TOC) generation diagnostics are particularly useful to verify that you got what you expected. Each package will be summarized with a list of the modules processed in that package. Similarly the main summary generation is summarized with a list of packages, and the global index generation reports the number of entries created for each letter of the alphabet.

You have a choice of directing the program log to either STDERR (via --nolog) or to a log file (via --log). If you activate the log file, you'll get a file called pod2htmltree.log in your sourcePath directory.

Successive Executions

To assist you with making sure your updates create only expected changes from run to run, all non-module documentation files (i.e. everything except the file generated directly from each Perl file) are backed up before generating the new version. These backup files have a .old extension.

Input Derivations

These sections must be present in every module (via =head1), otherwise Pod::HtmlTree will issue a warning: NAME, SYNOPSIS, REQUIRES, DESCRIPTION, BUGS, AUTHOR, and VERSION.

These sections, if present via =head1, are used for indexing: GLOBAL VARIABLES, FUNCTIONS, CLASS VARIABLES, CONSTRUCTOR, and METHODS. That is, each entry in each of these sections will have a hyperlinked entry in the global index to jump to it.

For tool applications, the version is extracted from the source file by matching this regular expression -- #Revision: (\d+\.\d+) # -- except that the octothorps (#) should be replaced by dollar signs ($). (If I actually wrote it with dollar signs it would be converted by RCS here.)

For module summaries, the first sentence in the NAME section of each module is extracted as the module description, which is determined by reading up until a period followed by whitespace. Note also that this first sentence is expected to be contained within an HTML element -- a P or DIV, etc. -- and that element wrapper is removed, assuming the template will format the sentence as it wishes.

For the package summary, the first sentence in the body element of each package description file (.../package.html) is extracted as the package description, which is determined by reading up until a period followed by whitespace.



pod2htmlTree(option..., command file..., package dir..., package file...)

The different arguments may be in any order and any quantity. An option has the form --name=value. The value may or may not need to be enclosed in quotation marks. This depends on whether it contains any spaces or other characters special to your shell. Inside a command file, which contains one option or element per line, everything after the equals sign is assigned to the value, except for enclosing (optional) quotation marks.

An element may be either a package directory or an individual package file. Say, for example, you have packages Here::one, Here::two, and There::more, all of these in /perl/lib. All of these are equivalent:

        pod2htmlTree( qw(--sourcePath=/perl/lib Here There ))
        pod2htmlTree( qw(--sourcePath=/perl/lib Here There/ ))
                qw(--sourcePath=/perl/lib Here/ Here/ There/ ))
        pod2htmlTree( qw(@cmd.conf ))

The last line assumes that you create a command file cmd.conf containing the same arguments (one per line) which might look like:


You may mix and match options and elements between the command line and command files. Precedence is determined as follows: For options, all command line options are processed first. Then all command file options are processed. If an option appears more than once, the last instance will be effective. For elements, these are processed in the order encountered. That is, you could consider elements within a command file as expanded in place on the command line.

command file

A string of the form @filename, the specified file contains other other options or package dirs or package files.

package dir

A directory name relative to sourcePath.

package file

A file name relative to sourcePath


One of the directives specified below:

    --header=string - HTML for top of page (in body element)

    --footer=string - HTML for top of page (in body element)

    --headElement=string - HTML for head element

    --bodyAttributes=string - HTML attribute string to add to BODY tag

    --sourcePath=path - input directory (.pm files)

    --targetPath=path - output directory (.html files)

    --templatePath=path - template directory (.thtml and auxiliary files)

    --javaAbsPath=path - absolute path to java API root

    --javaPackages=path - relative path from java API root to package level

    --jsAbsPath=path - absolute path to js API root

    --jsPackages=path - relative path from js API root to package level

    --doctitle=string - title for top of overview page

    --css=file name - style sheet file

    --headertoc - use header for top-level index page also

    --noheadertoc - do not use header for top-level index page (default)

    --log - write output to logfile

    --nolog - write output to stderr (default)

    --verbose - show informational messages

    --noverbose - suppress informational messages (default)

    --buildall - builds all files, whether changed or not

    --nobuildall - builds only those files which have changed (default)

    --genTime - include generated time in the meta generator tag

    --nogenTime - do not include generated time in the meta generator tag (default)

    --tools=path - path to tools or applications to document, if desired


All "=item" lines used in the pod text within the methods, functions, constructors, or class variable sections, will be indexed in the master index. There is no way to prevent pod2html from making an "=item" into a link, hence no way to distinguish a plain list item from a method/class/variable name.

Pod2html treats literal html as display text, converting "<" to &lt; and ">" to &gt;. This module repairs that for paired element tags, but not for singletons.


- Add option for specifying required sections (e.g. NAME, SYNOPSIS, ...).

- Add links from checkboxes to Java, JavaScript, test output, etc.

- Add meta tag generation.

- Add doc-files subdirectory copy for each package directory.

- Add index entry for subclass (via =head1 EXTENDS).


Michael Sorens


$Revision: 380 $ $Date: 2008-08-07 07:02:51 -0700 (Thu, 07 Aug 2008) $


CleanCode 0.9


perldoc, pod2html, javadoc


Hey! The above document had some coding errors, which are explained below:

Around line 680:

=back doesn't take any parameters, but you said =back -- end of option list

Around line 682:

=back doesn't take any parameters, but you said =back -- end of parameter list

Around line 684:

=back doesn't take any parameters, but you said =back -- end of METHODS section

CleanCode Perl Libraries Copyright © 2001-2013 Michael Sorens - Revised 2013.06.30 Get CleanCode at Fast, secure and Free Open Source software downloads