www.digitalmars.com Home | Search | D | Comments
Last update Mon Sep 19 2005
D
Language
Phobos
Comparisons

· Overview
· D for Win32
· Win32 DLLs in D
· C .h to D Modules
· FAQ
· Style Guide
· Example: wc
· Future
· D Change Log
· Tech Tips
· Glossary
· Acknowledgements

Tools
· DMD D Compiler
· GDC D Compiler
· Linker
· Profiler

Community
· News Digest
· News
· Forum
· Announcements
· Learn
· D links

Archives
· digitalmars.D
· digitalmars.D.dtl
· digitalmars.D.announce
· digitalmars.D.learn
· digitalmars.D.bugs
· D.gnu
· Old D

Embedded Documentation

The D programming language enables embedding both contracts and test code along side the actual code, which helps to keep them all consistent with each other. One thing lacking is the documentation, as ordinary comments are usually unsuitable for automated extraction and formatting into manual pages. Embedding the user documentation into the source code has important advantages, such as not having to write the documentation twice, and the likelihood of the documentation staying consistent with the code.

Some existing approaches to this are:

D's goals for embedded documentation are:
  1. It looks good as embedded documentation, not just after it is extracted and processed.
  2. It's easy and natural to write, i.e. minimal reliance on <tags> and other clumsy forms one would never see in a finished document.
  3. It does not repeat information that the compiler already knows from parsing the code.
  4. It doesn't rely on embedded HTML, as such will impede extraction and formatting for other purposes.
  5. It's based on existing D comment forms, so it is completely independent of parsers only interested in D code.
  6. It should look and feel different from code, so it won't be visually confused with code.
  7. It should be possible for the user to use Doxygen or other documentation extractor if desired.

Specification

The specification for the form of embedded documentation comments only specifies how information is to be presented to the compiler. It is implementation-defined how that information is used and the form of the final presentation. Whether the final presentation form is an HTML web page, a man page, a PDF file, etc. is not specified as part of the D Programming Language.

Phases of Processing

Embedded documentation comments are processed in a series of phases:
  1. Lexical - documentation comments are identified and attached to tokens.
  2. Parsing - documentation comments are associated with specific declarations and combined.
  3. Sections - each documentation comment is divided up into a sequence of sections.
  4. Special sections are processed.
  5. Highlighting of non-special sections is done.
  6. All sections for the module are combined.
  7. Macro text substitution is performed to produce the final result.

Lexical

Embedded documentation comments are one of the following forms:
  1. /** ... */ The two *'s after the opening /
  2. /++ ... +/ The two +'s after the opening /
  3. /// The three slashes
The following are all embedded documentation comments:
/// This is a one line documentation comment.

/** So is this. */

/++ And this. +/

/**
   This is a brief documentation comment.
 */

/**
 * The leading * on this line is not part of the documentation comment.
 */

/*********************************
   The extra *'s immediately following the /** are not
   part of the documentation comment.
 */

/++
   This is a brief documentation comment.
 +/

/++
 + The leading + on this line is not part of the documentation comment.
 +/

/+++++++++++++++++++++++++++++++++
   The extra +'s immediately following the /++ are not
   part of the documentation comment.
 +/

The extra *'s and +'s on the comment opening and left margin are ignored and are not part of the embedded documentation. Comments not following one of those forms are not documentation comments.

Parsing

Each documentation comment is associated with a declaration. If the documentation comment is on a line by itself or with only whitespace to the left, it refers to the next declaration. Multiple documentation comments applying to the same declaration are concatenated. Documentation comments not associated with a declaration are ignored. Documentation comments preceding the ModuleDeclaration apply to the entire module. If the documentation comment appears on the same line to the right of a declaration, it applies to that.

If a documentation comment for a declaration consists only of the identifier ditto then the documentation comment for the previous declaration at the same declaration scope is applied to this declaration as well.

If there is no documentation comment for a declaration, that declaration may not appear in the output. To ensure it does appear in the output, put an empty declaration comment for it.

int a;  /// documentation for a; b has no documentation
int b;

/** documentation for c and d */
/** more documentation for c and d */
int c;
/** ditto */
int d;

/** documentation for e and f */ int e;
int f;	/// ditto

/** documentation for g */
int g; /// more documentation for g

/// documentation for C and D
class C
{
    int x;    /// documentation for C.x

    /** documentation for C.y and C.z */
    int y;
    int z;    /// ditto
}

/// ditto
class D
{
}

Sections

The document comment is a series of Sections. A Section is a name that is the first non-blank character on a line immediately followed by a ':'. This name forms the section name. The section name is not case sensitive.

Summary

The first section is the Summary, and does not have a section name. It is first paragraph, up to a blank line or a section name. While the summary can be any length, try to keep it to one line. The Summary section is optional.

Synopsis

The next unnamed section is the Synopsis. It consists of all the paragraphs following the Summary until a section name is encountered or the end of the comment.

While the Synopsis section is optional, there cannot be a Synopsis without a Summary section.

/***********************************
 * Brief summary of what
 * myfunc does, forming the summary section.
 *
 * First paragraph of synopsis description.
 *
 * Second paragraph of
 * synopsis description.
 */

void myfunc() { }
Named sections follow the Summary and Synopsis unnamed sections.

Standard Sections

For consistency and predictability, there are several standard sections. None of these are required to be present.
Author:
Lists the author(s) of the declaration.
/**
 * Author: Melvin D. Nerd
 */
Version:
Specifies the version of the declaration.
/**
 * Version: 1.6a
 */
Deprecated:
Provides an explanation for and corrective action to take if the associated declaration is marked as deprecated.
/**
 * Deprecated: superseded by function bar().
 */

deprecated void foo() { ... }
License:
Any license information for copyrighted code.
/**
 * License: use freely for any purpose
 */

void bar() { ... }
Date:
Specifies the date of the last revision. The date should be in a form parseable by std.date.
/**
 * Date: March 14, 2003
 */
Returns:
Explains the return value of the function. If the function returns void, don't redundantly document it.
/**
 * Read the file.
 * Returns: The contents of the file.
 */

void[] readFile(char[] filename) { ... }
Throws:
Lists exceptions thrown and under what circumstances they are thrown.
/**
 * Write the file.
 * Throws: WriteException on failure.
 */

void writeFile(char[] filename) { ... }
References:
List of other symbols and URL's to related items.
/**
 * References:
 *    foo, bar, http://www.digitalmars.com/d/phobos/index.html
 */

Special Sections

Some sections have specialized meanings and syntax.
Params:
Function parameters can be documented by listing them in a params section. Each line that starts with an identifier followed by an '=' starts a new parameter description. A description can span multiple lines.
/***********************************
 * foo does this.
 * Params:
 *	x =	is for this
 *		and not for that
 *	y =	is for that
 */

void foo(int x, int y)
{
}
Copyright:
This contains the copyright notice. The macro COPYRIGHT is set to the contents of the section. The COPYRIGHT macro is often expanded in the boilerplate section. The copyright section only gets this special treatment when it is for the module declaration.
/** Copyright: Public Domain */

module foo;
Boilerplate:
The boilerplate section enables complete control over how the generated documentation is inserted into a boilerplate document. The documentation created is set as the replacement text for the BODY macro. Boilerplate sections only matter for the module declaration.
/**
 * Boilerplate:
 *	<html>
 *	<title>$(TITLE)</title>
 *	<body>
 *	<h1>$(TITLE)</h1>
 *	$(BODY)
 *	<hr>
 *	Last update: $(DATETIME)
 *	$(COPYRIGHT)
 *	</body>
 *	</html>
 */

module bar;
Macros:
The macros section follows the same syntax as the Params: section. It's a series of NAME=value pairs. The NAME is the macro name, and value is the replacement text.
/**
 * Macros:
 *	FOO =	now is the time for
 *		all good men
 *	BAR =	bar
 */

Macros

The documentation comment processor includes a simple macro text preprocessor. There are predefined macros, and macros defined by the Macros: section. When a appears in section text it is replaced with NAME's corresponding replacment text. The replacement text is then recursively scanned for more macros. If a macro is recursively encountered, only one level of recursion is performed. Macro invocations that cut across replacement text boundaries are not expanded. If NAME is not a macro name, it is assumed to be a file name, and the contents of the file with that name become the replacement text. (By convention, non-filename macro names are in all upper case, and filenames are not.) If the file does not exist, the replacement text has no characters in it. If a is desired to exist in the output without being macro expanded, add an extra $ as in: $(NAME). The extra $ will be elided.

Predefined Macros

BODY The generated document text before it is inserted into the boilerplate text.
TITLE Set to the module name.
DATETIME Set to the current date and time.
YEAR Set to the current year.
COPYRIGHT Set to the contents of any Copyright: section that is part of the module comment.

Highlighting

Embedded Comments

The documentation comments can themselves be commented using the <!-- comment text --> syntax. These comments do not nest.

Embedded Code

D code can be embedded using lines with at least three -'s in them to delinate the code section:
/++++++++++++++++++++++++
 + Our function.
 + Example:
 + --------------------------
 +  #include <stdio.h>
 +
 +  void foo()
 +  {
 +	printf("foo!\n");  /* print the string */
 +  }
 + --------------------------
 +/
Note that documentation comment uses the /++ ... +/ form so that /* ... */ can be used inside the code section.

Embedded HTML

HTML can be embedded into the documentation comments, and it will be passed through to the HTML output unchanged. However, since it is not necessarily true that HTML will be the desired output format of the embedded documentation comment extractor, it is best to avoid using it where practical.
/** Example of embedded HTML:
 *   <ol>
 *      <li> <a href="www.digitalmars.com">Digital Mars</a>
 *      <li> <a href="www.classicempire.com">Empire</a>
 *   </ol>
 */

Emphasis

Identifiers in documentation comments that are function parameters or are names that are in scope at the associated declaration are emphasized in the output. This emphasis can take the form of italics, boldface, a hyperlink, etc. How it is emphasized depends on what it is - a function parameter, type, D keyword, etc. To prevent unintended emphasis of an identifier, it can be preceded by an underscore (_). The underscore will be stripped from the output.

Character Entities

Because the characters <, > and & have special meaning to the documentation processor, to avoid confusion it can be best to replace them with their corresponding character entities:
Character Entity
< &lt;
> &gt;
& &amp;
It is not necessary to do this inside a code section, or if the special character is not immediately followed by a # or a letter.

Feedback and Comments

Add feedback and comments regarding this page.