HeaderDoc:
API Documentation from Header Files

Author: Matt Morse (matt@apple.com)
Last modified: 11/30/2001
 

Table of Contents

Purpose

HeaderDoc is a system for embedding structured commentary in C and C++ header files and producing rich HTML output from that commentary. HeaderDoc comments are similar in appearance to JavaDoc comments in a Java source file, but there are differences related to handling specifics of C and C++ and to providing a slightly more formal tag set to simplify parsing.

A simple HeaderDoc comment for a function might look like this:

/*!
  @function HMBalloonRect
  @discussion Use HMBalloonRect to get information about the size of a help balloon before the Help Manager displays it.
  @param inMessage The help message for the help balloon. 
  @param outRect The coordinates of the rectangle that encloses the help message. The upper-left 
                 corner of the rectangle has the coordinates (0,0).
*/
OSErr HMBalloonRect (const HMMessageRecord *inMessage, Rect *outRect);

When converted to HTML (by headerDoc2HTML, described below), the tagged comment above produces this output:

HMBalloonRect

OSErr HMBalloonRect (const HMMessageRecord *inMessage, Rect *outRect);

Use HMBalloonRect to get information about the size of a help balloon before the Help Manager displays it.

Parameters

Name Description
inMessage The help message for the help balloon.
outRect The coordinates of the rectangle that encloses the help message. The upper-left corner of the rectangle has the coordinates (0,0).

Also included with the main script (headerDoc2HTML) is gatherHeaderDoc, a utility script that creates a master table of contents for all documentation generated by headerDoc2HTML. Information on running gatherHeaderDoc is provided in the next section.

Running the Scripts

HeaderDoc includes two scripts, headerDoc2HTML.pl which generates documentation for each header it encounters, and gatherHeaderDoc.pl which finds these islands of documentation and assembles a master table of contents linking them together.


Running headerDoc2HTML.pl

Once you have a header containing HeaderDoc comments, you can run the headerDoc2HTML.pl script to generate HTML output like this:

        > headerDoc2HTML.pl  MyHeader.h

This will process "MyHeader.h" and create an output directory called "MyHeader" in the same directory as the input file. To view the results in your web browser, open the file index.html that you find inside the output directory.

Instead of specifying a single input file (as above), you can specify an input directory, if you wish. HeaderDoc will process every '.h' file in the input directory (and all of its subdirectories), generating an output directory of HTML files for each header that contains HeaderDoc comments.

If you want to specify another directory for the output, use the "-o" switch:

        > headerDoc2HTML.pl -o /tmp MyHeader.h 

You can use the "-v" switch to make HeaderDoc report the versions of all its constituent modules. This can be useful for bug reporting purposes.

        > headerDoc2HTML.pl -v 

Running gatherHeaderDoc.pl

This script scans an input directory (recursively) for any documentation generated by headerDoc2HTML. It creates a master table of contents (named MasterTOC.html by default--the name can be changed by setting a new name in the configuration file). It also adds a "top" link to all the documentation sets it visits to make it easier to navigate back to the master table of contents.

Here's an example of how to create documentation for a number of headers (the sample ones provided with the scripts) and then generate a master table of contents:

   > headerDoc2HTML.pl -o OutputDir ExampleHeaders
   > gatherHeaderDoc.pl OutputDir

You can now open the file OutputDir/MasterTOC.html in your browser to see the interlinked sets of documentation.


Running the Scripts using MacPerl

HeaderDoc runs on Mac OS 9 and earlier assuming MacPerl is installed. (You can get MacPerl from the CPAN ports page.) Here's what you need to do to run HeaderDoc using MacPerl:

The Configuration File

You can set values for some commonly altered variables. Currently, the configuration file lets you set these things:

copyrightOwner
The copyright notice that appears at the bottom of the HTML pages. Unless you specify a value, no copyright will appear.
defaultFrameName
The name of the file containing the frameset instructions (by default, index.html).
compositePageName
The name of the file containing the printable HTML page (by default, CompositePage.html).
masterTOCName
The name of the file containing the master table of contents for a series of headers (by default, MasterTOC.html). (This variable is used by the gatherHeaderDoc script.)
apiUIDPrefix
The prefix for named anchors in the HTML (by default, apple_ref). (In the HTML, HeaderDoc adds a self-describing named anchor near each API declaration -- for example <a name="//apple_ref/c/func/CFArrayAppendValue">. These can be useful for index generation and other purposes. See Symbol Markers for HTML-based Documentation for more information.)

HeaderDoc looks in three places for values for these variables, in this order:

  1. In the script itself (see the declaration of the %config hash near the top of headerDoc2HTML).
  2. In the home directory of the user, in Library/Preferences/com.apple.headerDoc2HTML.config
  3. In a file named headerDoc2HTML.config in the same folder as the script.

A variable can be assigned a value in any of these places, but only the last value read for a given variable will affect the output of a run of the script. If you are happy with the default values for these variables (as described above), you don't need to provide a configuration file. If you want to change just one or more values, provide a configuration file that declares just those values.

The format of the configuration file is this:

    key1 => value1
    key2 => value2

Here is a sample configuration file.


HeaderDoc Comments and Tags

HeaderDoc comments are of the form:

  /*!
    @function FunctionName
    @discussion This is a comment about FunctionName.
  */

In their simplest form (as above) they differ from standard C comments in only two ways:

  1. The addition of the "!" character next to the opening asterisk
  2. The addition of a tag that announces the type of API being commented ("@function", above).

However, you can use additional JavaDoc-like tags within the HeaderDoc comment to identify specific fields of information. These tags will make the comments more amenable to conversion to HTML. For example, a more complete comment might look like this:

  /*! 
    @function HMBalloonRect
    @abstract Reports size and location of help ballon.
    @discussion Use HMBalloonRect to get information about the size of a help balloon 
        before the Help Manager displays it.
    @param inMessage The help message for the help balloon.
    @param outRect The coordinates of the rectangle that encloses the help message. 
        The upper-left corner of the rectangle has the coordinates (0,0).
  */

Tags are indicated by the "@" character, which must appear as the first non-whitespace character on a line.

The first tag in a comment announces the API type of the declaration (function, struct, enum, and so on). The next two lines (tagged @abstract and @discussion) provide documentation about the API element as a whole. The abstract can be used in summary lists, and the discussion can be used in the detailed documentation about the API element.

The abstract and discussion tags are optional, but encouraged. Their use enables various improvements in the HTML output, such as summary pages. However, if there is untagged text following the API type tag and name (@function HMBalloonRect, above) it is assumed to be a discussion. With such untagged text, HeaderDoc assumes the discussion extends from the end of the API-type comment to the next HeaderDoc tag or to the end of the HeaderDoc comment, whichever occurs first.

HeaderDoc understands some variants in commenting style. In particular, you can have a one-line comment like this:

 /*! @var settle_time		Latency before next read. */
 

...and you can use leading asterisks on each line of a multiline comment:

  /*! 
   * @function HMBalloonRect
   * @abstract Reports size and location of help ballon.
   * @discussion Use HMBalloonRect to get information about the size of a help balloon 
   *      before the Help Manager displays it.
   * @param inMessage The help message for the help balloon.
   * @param outRect The coordinates of the rectangle that encloses the help message. 
   *      The upper-left corner of the rectangle has the coordinates (0,0).
   */
 

If you want to specify a line break in the HTML version of a comment, use two carriage returns between lines rather than one. For example, the text of the discussion in this comment:

  /*! 
   * @function HMBalloonRect
   * @discussion Use HMBalloonRect to get information about the size of a help balloon 
   *      before the Help Manager displays it.
   *
   *      By checking the help balloon size before display, you can guard against...
   */
 

...will be formatted as two paragraphs in the HTML output:

HMBalloonRect

OSErr HMBalloonRect (const HMMessageRecord *inMessage, Rect *outRect);

Use HMBalloonRect to get information about the size of a help balloon before the Help Manager displays it.

By checking the help balloon size before display, you can guard against...

 

 

Tags for All Headers

Often, you'll want to add a comment for the header as a whole in addition to comments for individual API elements. For example, if the header declares API for a specific manager (in Mac OS terminology), you may want to provide introductory information about the manager or discuss issues that apply to many of the functions within the manager's API. Likewise, if the header declares a C++ class, you could discuss the class in relation to its superclass or subclasses.

The value you give for the @header tag serves as the title for the HTML pages generated by headerDoc2HTML. The text you associate with the @header tag is used for the introductory page of the HTML website the script produces.

Tag
Example
Identifies
Fields
@header @header Repast Manager The name under which the API is categorized. Typically used to declare the Manager name (for classic Mac APIs) or class name (for object-oriented APIs)
1

Example:

/*!
  @header Repast Manager
  The Repast Manager provides a functional interface to the repast driver. 
  Use the functions declared here to generate, distribute, and consume meals.
*/

Tags By Language Type

Tags are largely specific to a particular programming language—the @method tag has no place in a C header, for example. Refer to the following sections for information about which tags are available for a particular language context.