You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Julian Foad <ju...@btopenworld.com> on 2005/04/07 23:00:53 UTC

Doxygen policy ideas

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/

Re: Doxygen policy ideas

Posted by Branko Čibej <br...@xbc.nu>.
Julian Foad wrote:

> Certainly not @c. We should let Doxygen generate links wherever 
> possible. '#' is for macros, not types.
>
> According to the manual on www.doxygen.org, '#' can mark any symbol, 
> and is almost identical to a '::' prefix.  Not that we would 
> necessarily want to use it that freely.  The manual doesn't seem to 
> make any recommendations about best usage - it only documents the syntax.
>
>
>>> 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").
>>
>>
>> +1
>
>
> You contradict yourself here.  How would you prefer to mark types that 
> aren't structures?

Hm, yes, I forgot that doxy treats structs specially. Ignore my 
ignorance; # it is, then, as I do think that links are important.

-- Brane


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Doxygen policy ideas

Posted by Julian Foad <ju...@btopenworld.com>.
Thanks for the review, Branko.  I'll incorporate your feedback in the second 
draft.  Comments on a few of your points:

Branko Čibej wrote:
> Other preformatted text should be enclosed in @verbatim and 
> @endverbatim. Using the latest version of doxygen, you almost never need 
> HTML tags any more.

Good.  I'll read up on that.


> Julian Foad wrote:
>> 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.
> 
> What, in the API docs? No way. If we have such a bug that it's necessary 
> to say so in the API documentation, use @bug or @todo. Doxygen will 
> generate a separate list of such items.

I'll review the existing "###" comments (about 35 of them) and see what's best 
for them.


>> [UNSURE.]
>> Refer to a Subversion public structure with just its name (not with 
>> "@c").
[...]
>> Alternatives: Prefix "#" or "::", and/or "@c".
[...]
> Certainly not @c. We should let Doxygen generate links wherever 
> possible. '#' is for macros, not types.

According to the manual on www.doxygen.org, '#' can mark any symbol, and is 
almost identical to a '::' prefix.  Not that we would necessarily want to use 
it that freely.  The manual doesn't seem to make any recommendations about best 
usage - it only documents the syntax.


>> 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").
> 
> +1

You contradict yourself here.  How would you prefer to mark types that aren't 
structures?


- Julian

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Doxygen policy ideas

Posted by Branko Čibej <br...@xbc.nu>.
Julian Foad wrote:

> 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. */
>   }

If we document these, I'd only allow these two forms:

    /** One line (brief) comment. */

and

    /**
     * Brief description.
     * Optional longer description.
     */

That is, the /** and */ in multiline comments should be on a line by 
themselves. That way the text alignmebt is nicer, and multiline comments 
more visible. This applies to most of your examples, so I won't repeat 
it later on.

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

Yup, use doxygen's links instead.

> 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.

Nope, if it's code it should be between @code and @endcode, like so:

    /**
     * Transmogrify the xylph in @a nadger.
     * The lifetime of the returned zobkin is controlled by
     * metamorphing the @a fondal; for example:
     * @code
     * fondal = meta(morph, global_fondal);
     * zobkin = transmogrify(get_default_xylph(), fondal);
     * @endcode
     */

Other preformatted text should be enclosed in @verbatim and 
@endverbatim. Using the latest version of doxygen, you almost never need 
HTML tags any more.

> 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.

What, in the API docs? No way. If we have such a bug that it's necessary 
to say so in the API documentation, use @bug or @todo. Doxygen will 
generate a separate list of such items.

> [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.

+1

> 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.

It's interesting to note that Doxygen treats @a strictly as a formatting 
directive; i.e., it won't associate the names tagged with @a with 
function parameters. That's a pity, because we can't get warnings about 
misspellings or missing argument documentation.


> 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".

I think @a is correct here, given the context. @c is for constants.


> [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().

I guess this is consistent.


> 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().

+1

> [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

Certainly not @c. We should let Doxygen generate links wherever 
possible. '#' is for macros, not types.


> 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

+1

> Quote any other symbol (e.g. APR symbol, enumerated constant, literal) 
> with "@c ..." for a single word or "<tt>...</tt>" for multiple words.

Ah, i hate the <tt> bit...but I can't think of an alternative. @verbatim 
is multiline, unfortunately...

> 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.

-1. The links are extremely useful.

>The "Modules" list (from "@defgroup") is very poor.
>  
>
Yup. Usage of @defgroup and @ingrouop is another thing we should set a 
policy on and document.

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

>Ensure that "Similar to" and "Same as" and "Like" are followed by a cross-reference.
>  
>
Ah, @see :)

>Rare use of @copydoc, @em, @name, @see.  Maybe eliminate or use more widely?
>  
>
"Similar to foo()" is @see foo()

-- Brane


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Doxygen policy ideas

Posted by Julian Foad <ju...@btopenworld.com>.
Please ignore the attachment: it is an older draft of the main text, and I 
didn't mean to include it.

- Julian


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Doxygen policy ideas

Posted by Max Bowsher <ma...@ukf.net>.
Julian Foad wrote:
>> 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.

Yes! Very definitely!

One addition:

We should start to put stuff on the main page (@mainpage), and use it, and 
extra pages, to document aspects of the API which spread across multiple 
symbols - for example:
Pool is last argument
Policy on NULL inputs
Description of how to use errors, and SVN_ERR()

Max.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org