[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Doxygen policy ideas

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: 2005-04-08 01:00:53 CEST

SUMMARY

Noticing that our Doxygen HTML API documentation is rather untidy, I submit
that we ought to document and improve our use of Doxygen mark-up, to make it
easier to learn and to apply correctly, and to make the result more consistent,
more attractive and more useful. I present a proposal and solicit feedback.

INTRODUCTION

The documentation of our public API is one of the primary references for those
developing against Subversion libraries, both within and outside the core
project. Our use of Doxygen mark-up in the header file comments facilitates
the automatic generation of user-friendly forms of API documentation such as
hyper-linked HTML pages. For the result to be attractive and useful, certain
styles of commenting must be adhered to.

It has come to my attention while reviewing the public API that our use of
Doxygen mark-up is less than consistent. This is probably because many
developers, including me, did not know Doxygen and simply tried to copy what
they saw others had done. Most people have got the hang of starting a Doxygen
comment with "/**" and referring to an argument with "@a", but that is only the
beginning and even the definition of what is "an argument" is not always obvious.

I feel it would be useful to develop some guidelines for commenting our APIs,
and write them up in HACKING. To this end I have read up on Doxygen and made
some proposals. To begin with, these proposals are the union of all my
thoughts on the subject. I expect to trim them down a bit after feedback on
which ones people like and don't like, because if we try to use too many of the
possibilities Doxygen offers then it will be too difficult to remember and to
apply consistently.

===========================================================================

DOXYGEN USAGE GUIDELINES: GENERAL

Subversion uses Doxygen mark-up in its public API documentation. See
<http://www.stack.nl/~dimitri/doxygen/>. To generate API documentation in
HTML, run "doxygen" from the Subversion source tree root, pointing it at its
configuration file, like this: "doxygen doc/doxygen.conf". It will generate
documentation under "doc/doxygen" (as specified in the configuration file), and
send progress and error/warning output to standard output and standard error
respectively.

Doxygen recognises many different kinds of mark-up within special documentation
comments. This document describes the small subset of Doxygen mark-up that is
used in the Subversion APIs. It is aimed at the competent programmer who is
modifying or adding interfaces within an existing Subversion library.

Start a Doxygen comment with "/**", and end it with "*/". Any continuation
lines should start with an asterisk aligned under the first opening asterisk,
and if the comment end marker is on a line by itself its asterisk should also
align there. A normal Doxygen comment comes immediately before the code that
it documents. A Doxygen comment may come immediately after a member (of a
struct, enum, etc.) by starting it with "/**<".
Examples:
   /** One-line comment. */
   #define GLOBAL_MACRO BLAH

   /** More than one
    * line. */
   typedef struct foo foo;

   /** More than one
    * line.
    */
   struct foo {
     int member; /**< Documentation of this member. */
   }

Use "@" rather than "\" to introduce Doxygen commands.
Examples:
   @a arg1

The first sentence of a Doxygen comment is the brief description. It should
follow immediately after "/** ", start with a capital letter if the first word
is a plain English word, and end with a full stop, but need not be a full
sentence. It should state the subject of the interface without redundant words
like "Interface to", "Function for", etc.
Examples:
   /** Copy the foo @a src over the foo @a dest. */
   void copy(foo *dest, const foo *src);

After the brief description there can be a long description which should start
after a blank line. It should add information to the brief description, and
not unnecessarily repeat what was said in it. If the long description is
actually rather short, it can start after the full stop of the brief
description (see the Doxygen option JAVADOC_AUTOBRIEF).
Examples:
   /** Brief description only. */

   /** Brief description. More
    * details. */

   /** Brief description.
    *
    * Long (many-line)
    * description.
    */

In particular, "@since" and "@deprecated" should not appear at the beginning of
the comment.
Reason: In this case, Doxygen would use the "@since" comment as the brief
description, or would use an empty brief description if "@deprecated" appeared
first.
Examples:
   /** Copy @a src to @a dst.
    * @since New in 1.2. */

   /** Copy @a src to @a dst.
    *
    * @deprecated Provided for backward compatibility with the 1.1 API.
    *
    * Similar to copy(), except that the result is always green.
    */

Do not use words like "above" and "below" to reference other APIs.
Reason: The documentation may be laid out differently from the source files.

Surround pre-formatted text, whose horizontal and vertical spacing is to be
preserved, by "<pre>...</pre>", or by "<code>...</code>" if it is C source
code. This should only be used where necessary, and should not detract unduly
from the presentation in the header files themselves. It should not be used on
plain text paragraphs like notes and warnings.

A note or warning should be a paragraph starting with "@note" or "@warning",
not "NOTE:", etc. If the source code needs attention (e.g. is buggy) then use
a "###" attention marker as well.

[UNSURE. UNIMPORTANT.]
Use the plain English words "true", "false" and "null" rather than upper case
or marked up versions like "TRUE", "@c NULL", etc.
Reasons: The TRUE, FALSE and NULL macros are so common that there is no need
for every interface that uses them to link to them, nor to remind the reader
that these are the particular macro names we use to represent truth and
falsehood and null pointers.
Example:
   If @a prompt is true, return null.
   @a string may be null, in which case set @a *found to false.

DOXYGEN USAGE POLICY: SYMBOL REFERENCES (LINKS AND QUOTING)

Refer to an argument of the current function with "@a". The documentation
writer may, but need not, treat the name of the argument as a word in the
sentence. (Sometimes it is very convenient to do so.) The "@a" is never
considered to be a word in the sentence; it is absent from the Doxygen output.
Examples:
   Print the string @a string.
   Print a @a string.

The members of a structure, enumeration, etc. should have their own
documentation comments, but if they are documented within the container's
comment, then refer to them with "@a ...".
Reasons: In terms of documentation, a member of a structure is very similar to
an argument of a function.
Alternatives: "@c".

[UNSURE.]
Refer to an argument of a different function with prefix "@a ".
Reason: "@a" doesn't actually mark the item as an argument, it just marks it in
a particular font, so using "@a" for all arguments makes sense.
Note: I'm not sure I agree with this. I'd also be happy to have them quoted
differently, e.g. with "@c" or with quotation marks.
Examples:
   Pass @a input straight on to the @a receive parameter of svn_other_function().

Refer to any function with suffix "()", and not with prefix "@c".
Reasons: It looks good in the source text. Doxygen makes it into a link
automatically if it is a documented symbol, and if not, it still looks good in
the output.
Examples:
   Like svn_error_create() but uses printf().

[UNSURE.]
Refer to a Subversion public structure with just its name (not with "@c").
Refer to a member of one with "struct_name::member_name".
Reasons: Doxygen treats a structure as a class, and so regards it as a primary
type, and always makes it into a link if it is a documented symbol.
Alternatives: Prefix "#" or "::", and/or "@c".
Examples:
   svn_string_t
   svn_opt_revision_t::kind

Refer to any other Subversion public symbol in the global namespace (e.g.
typedef, #define macro, but not enumerated constants) with prefix "#" (not with
"@c").
Reasons: It generates a link, and it is neater in the source than "@c".
Enumerated constants are excluded because Doxygen considers them to be in their
own namespaces, not global.
Alternatives: prefix "::".
Examples:
   #svn_revnum_t
   #SVN_INVALID_REVNUM

Quote any other symbol (e.g. APR symbol, enumerated constant, literal) with "@c
..." for a single word or "<tt>...</tt>" for multiple words.
Reason: These are not references, and just need to be written in a distinctive
font, which is what "@c" and it multi-word equivalent "<tt>" do.
Examples:
   @c NULL
   @c SVN_ERR_CANCELLED
   @c int
   <tt>const char *</tt>
   @c apr_hash_t
   <tt>apr_hash_t *</tt>
   <tt>#svn_string_t *</tt>
   <tt>/dev/null</tt>

[SIMPLER: Instead of the last three rules (svn_struct, #svn_other, @c non-svn),
perhaps just the following:]
Quote any non-function symbol or literal with "@c name" or "<tt>naming words</tt>".
Reasons: Simple rule. It is what we are doing already. Generates a
cross-reference only for structures, but that may be good enough for now.

===========================================================================

Apologies for such a long posting. Please give an initial reaction to the
various points, but don't critique the presentation and wording of this first
draft too deeply. And if you agree or disagree with something, please always
try to say why.

As a significant and fairly uncontentious practical step, I have prepared a
patch that ensures every reference to a Subversion function ends in "()",
without touching anything else. Until I investigated Doxygen, I didn't realise
that the parentheses had any effect at all, but now I am convinced that is the
best way of marking functions.

- Julian

-- 
http://www.foad.me.uk/

DOXYGEN USAGE POLICY

Subversion's public APIs use Doxygen mark-up in their documentation. See <http://www.stack.nl/~dimitri/doxygen/>. To generate API documentation in HTML, run "doxygen" from the Subversion source tree root, pointing it at its configuration file: "doxygen doc/doxygen.conf". It will generate documentation under "doc/doxygen" (as specified in the configuration file), and send progress and error/warning output to standard output and standard error respectively.

Doxygen recognises many different kinds of mark-up within documentation comments. This document describes the small subset of Doxygen mark-up that is used in the Subversion APIs. In this description, "should" means "prefer" but not "require".

Start Doxygen comments with "/**", and end with "*/". Any continuation lines should start with an asterisk aligned under the first opening asterisk, and if the comment end marker is on a line by itself its asterisk should also align there. A normal Doxygen comment comes immediately before the code that it documents. A Doxygen comment may come immediately after a member (of a struct, enum, etc.) by starting it with "/**<".
Examples:
  /** One line. */
  /** More than one
   * line. */
  /** More than one
   * line.
   */
  int member; /**< Documentation of this member. */

Use "@", not "\", to introduce Doxygen commands.
Examples:
  @a arg1

The first sentence of a Doxygen comment is the brief description. It should follow immediately after "/** ", start with a capital letter if the first word is a plain English word, and end with a full stop. It should state the subject of the interface without redundant words like "Interface to", "Function for", etc. (See the Doxygen option JAVADOC_AUTOBRIEF.)
Examples:
  /** Copy @a src_path to @a dst_path.

After the brief description there can be a long description which should start after a blank line. If the long description is actually rather short, it can start after the full stop of the brief description (see the Doxygen option JAVADOC_AUTOBRIEF).
Examples:
  /** Brief description only. */
  /** Brief description. Longer
   * description. */
  /** Brief description.
   *
   * Long (many-line)
   * description.
   */

In particular, "@since" and "@deprecated" should not appear at the beginning of the comment.
Reason: In this case, Doxygen uses the "@since" comment as the brief description, or uses an empty brief description if "@deprecated" appears first.
Examples:
  /** Copy @a src_path to @a dst_path.
   * @since New in 1.2. */
  /** Copy @a src_path to @a dst_path.
   *
   * @since New in 1.2.
   *
   * Longer description.
   */

Do not use words like "above" and "below" to reference other APIs.
Reason: The documentation may be laid out differently from the source files.

Surround pre-formatted text, whose horizontal and vertical spacing is to be preserved, by "<pre>...</pre>", or by "<code>...</code>" if it is C source code. This should only be used where necessary, and should not detract from the presentation in the header files themselves. It should not be used on plain text paragraphs like notes and warnings.

A note or warning should be a paragraph starting with "@note" or "@warning", not "NOTE:", etc.

Say "true" and "false" rather than "TRUE", "@c TRUE", etc.
Reasons: The TRUE and FALSE macros are so common that there is no need for every interface that uses them to link to them and specify explicitly that these are the macros that we use to represent truth and falsehood.
Example:
  If @a prompt is true, ...

REFERENCES (LINKS AND QUOTING)

Refer to a Subversion public function with suffix "()" (not with "@c"). For a function type, either suffix "()" or prefix "#".
Alternatives: Prefix "#" or "::".
Examples:
  svn_error_create()
  svn_io_walk_func_t()
  #svn_io_walk_func_t

Refer to a Subversion public structure with just its name (not with "@c"). Refer to a member of one with "struct_name::member_name".
Alternatives: Prefix "#" or "::".
Reasons: Doxygen treats a structure as a class, and so regards it as a primary type, and always makes a cross-reference from its name. (### Doesn't always work, e.g. in the comment of svn_ra_svn_item_t::u::list.)
Examples:
  svn_string_t
  svn_opt_revision_t::kind

Refer to any other Subversion public symbol in the global namespace (e.g. typedef, #define macro, but not enumerated constants) with prefix "#" (not with "@c").
Reasons: Enumerated constants are excluded because Doxygen considers them to be in their own namespaces, not global.
Alternatives: prefix "::".
Examples:
  #SVN_INVALID_REVNUM

Quote any other symbol (e.g. APR symbol, enumerated constant, literal) with "@c ..." for a single word or "<tt>...</tt>" for multiple words.
Reason: These are not references, and just need to be written in a distinctive font, which is what "@c" and it multi-word equivalent "<tt>" do.
Examples:
  @c NULL
  @c SVN_ERR_CANCELLED
  @c int
  <tt>const char *</tt>
  @c apr_hash_t
  <tt>apr_hash_t *</tt>
  <tt>#svn_string_t *</tt>
  <tt>/dev/null</tt>

Refer to a member of the current structure, enumeration, etc. with "@c ..." or "@a ..." (### which?).

Refer to an argument of the current function with "@a". The documentation writer may, but need not, treat the name of the argument as a word in the sentence. (Sometimes it is very convenient to do so.) The "@a" is never considered to be a word in the sentence; it is absent from the Doxygen output.
Examples:
  Print the string @a string.
  Print a @a string.

Refer to an argument of a different function with prefix "@a ".
Reason: "@a" doesn't mark the item as an argument, it just marks it in a particular font, so using "@a" for all arguments makes sense.
Note: I'm not sure I agree with this. I'd also be happy to have them quoted differently, e.g. with "@c" or with quotation marks.
Examples:
  Pass @a input straight on to the @a receive parameter of svn_other_function().

TASKS

Write up our Doxygen usage policy in HACKING.

Implement the policy in the present headers:
  @since/@deprecated not first
  Functions end with "()" (doxy-parens.patch)

The "Modules" list (from "@defgroup") is very poor.

Ensure that every hash has its key and value types documented. (This is not a Doxygen issue.)

Ensure that "Similar to" and "Same as" and "Like" are followed by a cross-reference.

Rare use of @copydoc, @em, @name, @see. Maybe eliminate or use more widely?

"@c const ...", "@a const ...": wrong scope of "@c", wrong use of "@a". Use "<tt>".

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Apr 8 01:02:52 2005

This is an archived mail posted to the Subversion Dev mailing list.