/** @page libsbml-coding Coding conventions for libSBML The following is a collection of guidelines for libSBML authors and other interested persons to follow when writing libSBML code and documenting it.
@ref coding-general @n @ref coding-doxygen-summary @n @ref coding-doc-h @n @ref coding-doc-cpp @n |
/**
, then it will be
ignored by Doxygen. This can be either bad or good, depending on the
intention behind the comment.
@li Please write in complete sentences, with correct English grammar and
punctuation. @em Do @em not treat new lines as new sentences or beginnings
of different comments. Here is an example of what should be @em avoided:
@verbatim
/**
* creates a foo object
* given arg is the template
*/
@endverbatim
The text above doesn't end sentences with periods, doesn't begin sentences
with capitals, doesn't form complete sentences, etc. When Doxygen is used
to generate HTML documentation from this, it turns into one long run-on
paragraph, and it's unreadable.
@li Please write sentences with @em two (2) spaces after the terminating
period, not one. First, this makes the resulting text easier to read
compared to when sentence-ending periods are followed by only one space.
Second, text editing programs such as Emacs have special features to
recognize sentences based on this pattern, and they make proficient users
of those editors much happier because they can use sentence-oriented
editing commands.
@li Watch out that Doxygen automatically turns entity names it recognizes
in text into links to the definition of that entity. This is usually what
you want to have happen; for example, when describing the Model class, you
may mention classes such as Species and Compartment, and those should be
turned into convenient links to their definitions in the API documentation.
However, sometimes you don't want that to happen. To prevent Doxygen from
linking a word, put a percentage sign (\%) in front of it, as in @c
\%%Model. Doxygen will remove the percentage sign and leave the rest of
the word unlinked, resulting in the plain word %Model appearing in the
finished document.
@li We are using a feature of Doxygen that makes it use the first sentence
of a documentation comment as the "brief" description of the entity being
described (which may be a class, a method, a class data member, a function,
a typedef, etc.). This means that the first sentence up to a period or a
blank line will be pulled out separately and used as a one-line summary in
certain contexts by Doxygen. The following is an example:
@verbatim
/**
* This is the brief description. After the first sentence, everything
* else is part of the detailed description and not the brief one. This
* third sentence is also part of the detailed description.
*/
@endverbatim
Consequently, to emphasize this and remind people that this is going to
happen when the API documentation is generated, it is better to format the
text in the as in the following example:
@verbatim
/**
* This is the brief description.
*
* This is the beginning of the detailed description....
*/
@endverbatim
The visual split makes it really obvious what's going to happen.
@li Please try to limit lengths of lines to 79 characters long or less.
This makes code and documentation generally easier to read and edit in
different software tools. Sometimes it's too difficult to avoid a long
line, and then it's okay, but generally it's possible to reformat code in
such away as to keep things to 79 characters.
@li Sometimes code is meant to be part of the internal implementation and
not advertised to users of the library. To make Doxygen ignore blocks of
code, wrap the code with the comment
@verbatim
/** @cond doxygen-libsbml-internal */
@endverbatim
at the beginning and
@verbatim
/** @endcond doxygen-libsbml-internal */
@endverbatim
at the end of the block. (Explanation: this sets up a conditional that
will only be "seen" by Doxygen if the symbol "doxygen-libsbml-internal" is
defined. Since it's never defined in the Doxygen configuration, it will
the block will be ignored.)
@section coding-doxygen-summary Summary of commonly-used Doxygen commands in libSBML
The following is a summary of the doxygen commands we have found useful so
far in documenting libSBML. This is only intended as a quick orientation;
they are illustrated in the other sections below, and the complete details
of their definitions and use can be found online at the Doxygen website.
Command | Meaning | |
\@file | Defines the name of the current file. | |
\@brief | Provides a one-sentence description of the entity being described (a file, a class, etc.). | |
\@author | Names the author of the entity being described (a file, a class, etc.). | |
\@c |
Puts the following word in typewriter ("code") font. To style more than one
word, use <code>the words</code> . If you need to
put something that contains HTML tags in typewriter font, use the
<code>the words</code> form, and use the HTML
character codes \< and\> to embed the
openening '@c <' and '@c >' characters inside the words .
| |
\@em |
Puts the following word in italic font, for emphasis. To put multiple words
in italics, use <em>the words</em> .
| |
\@n |
Forces a newline, like HTML's <br> .
| |
\@p | Puts the following word in typewriter ("code") font. This form is preferred when the word is a parameter to a method or function. | |
\@li | Starts (or continues) a bullet list. You can insert the first @c \@li in a comment, and the item will continue until a paragraph break or the next @c \@li command. (Note: even though Doxygen will also recognize hyphens at the beginning of a line as starting a list item, avoid using that approach in favor of the @c \@li command. | |
\@class | Declares that the following documentation block refers to the named class. Useful only when the block does not immediately precede the class definition (e.g., when it's at the beginning of the file). | |
\@param | Declares a parameter to a method or function. The first word following @c \@param will be the name of the parameter, and the rest of the text (up to a period or blank) will be used as the description. | |
\@return | Declares the return value from a method or function. | |
\@see | Formats a reference to another entity in the documentation. Commonly used to refer to related classes or methods. | |
\@note | Formats the following paragraph with the heading "Note:". Useful to call out something special about a class, function, file or other entity, such as a behavior that should be brought to the attention of users or a note about API changes compared to previous versions of the software or SBML. As a convention, please put @c \@note blocks at the end of a documentation block, for uniformity in the API documentation. | |
\@warning | Formats the following paragraph with the heading "Warning:". This is a stronger statement than \@note, and is useful to call attention to backward-incompatible changes or potentially error-provoking situations. As a convention, please put @c \@warning blocks at the end of a documentation block, for uniformity in the API documentation. | |
\@bug | Formats the following paragraph with the heading "Bugs:". Useful to indicate that something is known to be a problem in some part of the code. As a convention, please put @c \@bug blocks at the end of a documentation block, for uniformity in the API documentation. |
<a
href="http://sbml.org">home page</a>
.
@section coding-doc-h Guidelines for documenting .h files
It is important to note that the documentation of global functions,
variables, typedefs, and enums will only be included in the output of
Doxygen if the file they are in is documented as well.
@li Here is a template header file suitable for use when creating a new .h
file for libSBML (and in fact, it's the same for .cpp files, too):
@verbatim
/**
* @file [filename]
* @brief [succinct description of what's in this file]
* @author [author's name]
*
* $Id$
* $HeadURL$
*
**/
@endverbatim
Of course, you should substitute appropriate content where the text is
bracked by @c [ and @c ]. The @c $Id$ and @c $HeadURL$ keywords will
automatically be substituted by CVS or SVN upon the first check-in. The
following is an complete example taken from an actual libSBML file at the
time of this writing:
@verbatim
/**
* @file Compartment.h
* @brief The libSBML class of object implementing SBML's Compartment.
* @author Ben Bornstein
*
* $Id: libsbml-coding.txt 7249 2008-06-26 22:48:40Z bbornstei $
* $HeadURL: https://sbml.svn.sourceforge.net/svnroot/sbml/trunk/libsbml/src/sbml/Compartment.h $
*
**/
#ifndef Compartment_h
#define Compartment_h
...
@endverbatim
@li A .h file will typically have a class declaration in it. The @em
normal way that one would document the class is to put a comment block in
front of the class declaration, as in the following fragment:
@verbatim
/**
* The libSBML class implementing SBML's CompartmentType construct.
*
* CompartmentTypes in SBML are ...
*/
class LIBSBML_EXTERN CompartmentType : public SBase
{
public:
...
@endverbatim
Unfortunately, we are hit here by a small problem of how to generate
descriptions for different programming languages from the same source
files. In particular, those class declarations in the .h files are usually
surrounded by \#ifdef __cplusplus
, which means they become
invisible when we use Doxygen to generate the descriptions for anything
other than C++. Thus, for the special case of documentation of classes,
please put the documentation in the file header rather that ahead
of the class itself in the file. The following example illustrates this
procedure (and note how more than one class can be described in the
header):
@verbatim
/**
* @file CompartmentType.h
* @brief Definitions of CompartmentType and ListOfCompartmentTypes.
* @author Ben Bornstein
*
* $Id: CompartmentType.h 7249 2008-06-26 22:48:40Z mhucka $
* $Source: /cvsroot/sbml/libsbml/src/sbml/CompartmentType.h,v $
*
*
*
* @class CompartmentType.
* @brief LibSBML implementation of SBML's %CompartmentType construct.
*
* A compartment type in SBML is a grouping construct used to
* establish a relationship between multiple Compartment objects.
* ....
*
*
* @class ListOfCompartmentTypes.
* @brief LibSBML implementation of SBML's ListOfCompartmentTypes construct.
*
* The various ListOf___ classes in SBML are merely containers used for
* organizing the main components of an SBML model. All are derived from
*....
*/
#ifndef CompartmentType_h
#define CompartmentType_h
...
@endverbatim
@li For each method or data member in the class definition, include a
comment block ahead of it, making sure to provide at least a brief
description. If it's a method and the method returns a value, use @c
\@return to describe the returned value; if it takes parameters, use @c
\@param to describe the parameters. If you also need to refer to the
parameters in the textual description of the method, use the @c \@p
command. The following example illustrates this:
@verbatim
/**
* Creates a new CompartmentType, optionally with the given @p id and
* @p name attribute values.
*
* In SBML, identifiers are required for CompartmentType objects;
* however, the identifier does not have to be set at the time of
* creation of the object, and instead can be set using the setId()
* method on the SBase parent class.
*
* @param id a string, the identifier of this CompartmentType instance
* @param name a string, the optional name of this
*/
CompartmentType (const std::string& id = "", const std::string& name = "");
@endverbatim
@li Please try to leave 2 blank lines between method declarations and other
items in the definitions of classes. This makes it easier for the eye to
spot transitions between method definitions, despite the blank lines that
exist within comment blocks. Here is an example taken from a class
definition in a .h file:
@verbatim
class LIBSBML_EXTERN CompartmentType : public SBase
{
public:
/**
* Creates a new CompartmentType, optionally with the given @p id and @p
* name attribute values.
*
* In SBML, identifiers are required for CompartmentType objects;
* however, the identifier does not have to be set at the time of
* creation of the object, and instead can be set using the setId()
* method on the SBase parent class.
*
* @param id a string, the identifier of this CompartmentType instance
* @param name a string, the optional name of this
*/
CompartmentType (const std::string& id = "", const std::string& name = "");
/**
* Destroys this CompartmentType.
*/
virtual ~CompartmentType ();
/**
* Copy constructor; creates a copy of this CompartmentType.
*/
CompartmentType(const CompartmentType& orig);
/**
* Assignment operator for CompartmentType.
*/
CompartmentType& operator=(const CompartmentType& orig);
@endverbatim
@section coding-doc-cpp Guidelines for documenting .cpp files
The .cpp files can be handled very similarly to the .h files described
above. You may use the same header template shown in the previous section
about .h files, and all the same guidelines apply.
The principal difference is that it is not necessary to repeat the class
description placed in the .h file, nor indeed is it necessary to copy or
recreate the documentation of class methods. As already mentioned, when
the API manual is generated by Doxygen, it will use the comments from the
.h file as the source of the documentation for the class and methods.
However, it @em is important to document @em functions, because these are
not defined by the .h files. This is especially important for the C
wrappers around the C++ methods. All the same documentation conventions
described so far apply to describing functions. The following example
provides an illustration:
@verbatim
/**
* Creates a new CompartmentType with the given @p id and @p name attribute
* values.
*
* In SBML Level 2 and beyond, the identifier attribute of a
* CompartmentType is required to have a value, but the name is optional.
* Programs calling this function can legitimately use an empty string for
* the @p name parameter.
*
* @param sid the value to assign as the identifier of this CompartmentType
* @param name the value to assign as the name of this CompartmentType
*
* @return a pointer to the newly created CompartmentType_t structure.
*/
LIBSBML_EXTERN
CompartmentType_t *
CompartmentType_createWith (const char *sid, const char *name);
@endverbatim
@section coding-misc-doxygen Miscellaneous Doxygen notes
@li The doxygen command @c \@internal is (according to the doxygen
documentation) supposed to let you flag things as internal implementation
code, such that it is not put in the finished documentation. This would be
great if we could use it, but I (MH) have been unable to make this work.
(Yes, there is a configuration flag, and yes, I've tried setting it both
ways.)
*/