iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Documentation rules and guidelines

Tagging your code

Use the following instead of plain strings in your comments:

  • \todo will add an item to the todo list
  • \test will add an item to the test list
  • \bug will add an item to the bug list
  • \deprecated will add an item to the deprecated list

For example:

//! Cool class
/*! Class that does something cool.
\todo Make it hot too */
class CoolClass { ... };

Modules, groups of related functions

Generally speaking, our goal is that users should be able to access information:

  • by browsing over the Modules section of the doc
  • by search for a name, or browsing the various class lists, file lists, etc
  • through linking between related doc pages

See how it's done for GenericImage.

  • First, in GenericImage.H we start with a top-level group, which will appear nicely under the Modules section of the documentation:
    /*! \defgroup genericimage GenericImage class and concepts
    GenericImage is a thin wrapper for an Image of any pixel type. Writing general algorithms that work with
    GenericImage allows them to apply to any image type. */
  • Then, we document GenericImage itself, make it belong to the genericimage group:
    /*! GenericImage class
    ...
    \ingroup genericimage */
    class GenericImage { ... };
  • Finally, if you want to cross-link to other groups, use the \see command; for example:
    /*! \defgroup genericimageoperators GenericImage Operators
    ...
    \ingroup genericimage
    \see image */
    /*! @{ */ // **********************************************************************
    ...
    /*! @} */ // **********************************************************************

And note how we use the arrobas curly braces to here include into our group all the operators that will be defined.

Note
Why use this rather than a bunch of \relates directives in each of the operators? This would make each operator appear in the doc page of the GenericImage class, which is great except that it masks teh general comment block we have about how all GenericImage operators work, promote pixels, etc.

Helper enums or other helpers

For classes that have helpers, for example, some enums that define parameters of functions associated with the class: Just define your group to only include the class; then indicate for each helper that it relates to the class. This will list the helpers in the doc page of the class, as opposed to cluttering the page of your group. See for example how it's done in Image.H where:

  • we define a group called 'image'
  • in the doc of Image we mention that it is in the group image
  • but in the doc of ImageInitPolicy and ImageFlags we simply mark those as related to the Image class as opposed to being in the group. Thus they will appear in the doc of the image class but not in the page describing the group. This is the desired behavior as in the group's page we want a clear and uncluttered high-level view, while in the class documentation we need to know the details.

However, for enums that are only used in functions and cannot be related to a class, we mush add those to the group where the function belongs. Have a look at Text.H for an example: TextAnchor is documented and added to textdrawing group, like the drawText() function is.

Macro-modules

  • All internal NRT macros (not to be used directly by users) should have a name that starts with NRT_MACRO_
  • All NRT macros that users may use should have a name that starts with NRT_
  • Simple macros that just define a value can be documented like classes, variables, etc
  • macros that declare a complex function whose internal guts are of no interest to end users should be documented as follows. First, in a .H file, only write a documentation block attached to nothing and that includes a \def for the macro name:
    //! Optional brief description of the macro
    /*! \def NRT_MY_MACRO(x, y)
    \hideinitializer
    Convenience macro to achieve blah. */
    Then, in an Impl.H file hidden in the details/ subdirectory, define your macro but do not document the macro definition itself. Finally, to create a link to your macro definition from within some other documentation, use
    /*! blah blah. See for example #NRT_MY_MACRO(x, y) */
    See for example NRT_DEFINE_ENUM_CLASS(name, SEQ) in Typing/Enum.H and Typing/details/EnumImpl.H

NRT Enums

For enums defined using NRT_DEFINE_ENUM_CLASS, we basically manually instruct doxygen that we are creating a new class. Adapt the following to your own enums:

//! BoundedSet insert policy
/*! \class BoundedSetInsertPolicy
When trying to push a new element into the set, if it matches one already in the set:
- if \c nrt::BoundedSetInsertPolicy::Preserve, keep the old one and discard the new incoming one, or,
- if \c nrt::BoundedSetInsertPolicy::Replace, replace the old one with the new one.
\relates BoundedSet */

Examples

Try as much as possible to create test-XXX.C files in the tests/ directory, and to focus each one on fully exercising a particular class or set of functions.

Either make a little test program that does something, like test-Component.C where people can play with parameters, etc, or use the boost testing framework to check a bunch of things, like test-GenericImage.C

The way examples are treated in doxygen is as follows: one declares a file as being en example somewhere, using the \example directive. That file is then scanned for classes, functions, etc, and for the ones that are found, an Examples: section is added to their documentation.

In NRT, we also instruct Doxygen that all files in tests/ are examples (see doc/doxygen.cfg)

Note that sometimes doxygen does not make the connection between a class and an example file. For example, in test-Module.C we do show how nrt::Module works, but only via classes that derive from nrt::Module ... In such cases, add an explicit link to the example file in the doc of your class. For instance:

//! Base class for a Module
/*! User modules should derive from nrt::Module and [...]
See \link test-Module.C \endlink for examples. */
class Module
{ ... };

There is a bit of trial and error that is required here. After you add a new example file, run a make doc, and check out the classes that you think should link to your example. If you don't find the relevant Examples: sections in there, just add the explicit link. The easiest is to look at your example file as marked up by doxygen and as it appears in the Examples tab at the top of your doxygen pages: everything that is clickable in there will be correctly linked (which you can check by clicking on those classes, functions, etc and verifying they have an Examples: section).

It may help doxygen if you fully qualify the classes or functions you use in your examples. For example, in test-Async.C we clearly specify nrt::async() (as opposed to using the namespace nrt and then calling async() without the namespace qualifier). This properly links test-Async.C to the documentation of nrt::async().