Writing Documentation

It is our firm belief that software can only be successful if it
is properly documented. Too many academic software projects die
prematurely once their creators leave the university or the
workgroup in which the software was developed, since with their
creators also knowledge of internal structures, interfaces, and
the valuable bag of tricks leaves, a gap that can not be closed by
reading sources, trial-and-error, and guessing.

The deal.II project has therefore from its
infancy adopted a policy that every aspect of the interface
needs to be well-documented before its inclusion into the
source tree. Since we have found that it is impossible to keep
documentation up-to-date if it is not written directly into the
program code, we write the documentation directly at the place of
declaration of a function or class and use automatic tools to
extract this information from the files and process it into HTML
for our web-pages, or LaTeX for printing.

In addition to the API documentation, we maintain a series of
well-documented example programs, which also follow a certain
``literate programming'' style in that the explanations of what
is happening are integrated into the program source by means of
comments, and are extracted by small scripts.

doxygen will then generate a page for the class
TestClass and document each of the member functions
and variables. The content of the @author tag will be
included into the online documentation of the class.

Extended Layout

In order to allow better structured output for long comments,
doxygen supports a great number of tags for enumerations,
sectioning, markup, and other fields. We encourage you to take a
look at the doxygen webpage to get an overview. However,
here is a brief summary of the most often used features:

Virtual functions:
Do not document virtual functions in derived classes, if there
is nothing different from the base class. If a virtual
function is documented in a base class, doxygen will
automatically copy this documentation to the derived
classes. This mechanism is interrupted, if a documentation
block is found in the derived class.

Itemized lists:
By writing comments like the following,

/**
* <ul>
* <li> foo
* <li> bar
* </ul>
*/

you can get itemized lists both in the online and printed
documentation:

foo

bar

In other words, one can use standard HTML tags for this
task. Likewise, you can get numbered lists by using the
respective HTML tags <ol>.

Verbatim output:

If you write comments like this,

/**
* @verbatim
* void foobar ()
* {
* i = 0;
* }
* @endverbatim
*/

you will get the lines between the verbatim environment with
the same formatting and in typewriter font:

void foobar ()
{
i = 0;
}

This is useful if you want to include small sample code snippets
into your documentation. In particular, it is important that
the formatting is preserved, which is not the case for all
other text.

Typewriter font:

In order to use typewriter font for instance for function
arguments or variables, use the <code> HTML
tag. For a single word, you can also use the form @p
one_word_without_spaces. The <tt> is obsolete in HTML5

If you refer to member variables and member functions
doxygen has better options than this: use
function_name() to reference member functions and
#variable_name for member variables to create links
automatically. Refer to the documentation of doxygen to
get even more options for global variables.

Emphasis:

To generate output in italics, use the @em
one_word_without_spaces tag or the <em>
HTML tag. To generate boldface, use <b>

Formulæ:

For simple and short formulæ use the <i>
HTML tag. Note that you can use <sub> and
<sup> to get subscripts an superscripts,
respectively. Only for longer formulæ use
$formula$ to generate a LaTeX formula which will then be
included as a graphical image.

Sections:

Sections in class and function documentations can be
generated using the <hN> HTML headline
tags. Headlines inside class documentation should start at
level 3 (<h3>) to stay consistent with the
structure of the doxygen output.

Sections cannot be referenced, unless you add a <A
NAME="..."> name anchor to them. If you really have
to do this, please make sure the name does not interfere with
doxygen generated anchors.

Exclusion from documentation:

doxygen sometimes has problems with inlined
functions of template classes. For these cases (and other cases of
parts of the code to be excluded from documentation), we define a
preprocessor symbol DOXYGEN when running
doxygen. Therefore, the following template can be
used to avoid documentation:

Code examples for the usage of single classes

Writing example files for classes is supported by
doxygen. These example files go into
deal.II/examples/doxygen. If they are short,
documentation should be inside and they are included into the
documentation with @include filename. Take a look how
the class BlockMatrixArray does this.

Larger example files should be documented using the
doxygen command @dotinclude and
related commands. However, if these programs do something
reasonable and do not only demonstrate a single topic, you should
consider converting them to a complete example program in the
step-XX series.

Writing example programs for the tutorial

Tutorial programs consist of an introduction, a well documented
code, and a section that shows the output and numerical results
of running the program. These three parts are written in separate
files: for the step-xx program, for example, they
would be in the
files examples/doc/step-xx/doc/intro.dox,
examples/doc/step-xx/step-xx.cc and
examples/doc/step-xx/doc/results.dox. There are a
number of scripts that then process and concatenate these three
different files and send them through doxygen for generation of
HTML output. In general, if you want to see how certain markup
features can be used, it is worthwhile looking at the existing
tutorial program pages and the files they are generated from.

The introduction

The introduction, as well as the results section, will be
processed as if they were doxygen comments. In other words, all
the usual doxygen markup will work in these sections, including
latex formulas, though the format for the formula environment is
a bit awkward. Since it takes much longer to run doxygen for all
of deal.II than to run latex, most of the lengthier
introductions are just written in latex (with a minimal amount
of markup) and later converted into doxygen format. One thing to
be aware of is that you can reference formulas in doxygen, so
you have to work around that using text rather than formula
numbers.

More important is what goes into the introduction. Typically,
this would first be a statement of the problem that we want to
solve. Take a look, for example, at
the step-22
or step-31 tutorial programs. Then come a few
sections in which we would discuss in mathematical terms the
algorithms that we want to use; this could, for example, include
the time stepping, discretization, or solver
approaches. step-22
and step-31 are again good, if lengthy, examples
for this.

On the other hand, if a program is an extension of a previous
program, these things need not be repeated: you would just
reference the previous program. For
example, step-16 does not talk about adaptive meshes
any more — it
extends step-6 and simply refers there for
details. Likewise, step-32 simply refers
to step-31 for the problem statement and basic
algorithm and simply focuses on those parts that are new
compared to
step-31.

The purpose of the introduction is to explain what the program
is doing. It should set the mindset so that when you read
through the code you already know why we are doing
something. You may not yet know how this done, but this
is what the documentation within the code is doing. At least you
don't have to wonder any more why we are building up this
complicated preconditioner — we've already discussed this
in the introduction.

If it helps the understanding, the introduction can refer to
particular pieces of code (but doesn't have to). For example,
the introduction to step-20 has pretty lengthy code snippets that
explain how to implement a general interface of operators that
may or may not be matrices. This would be awkward to do within
the code since in the code the view is somewhat smaller (you
have to have complete parameter lists, follow the syntax of the
programming language, etc, all of which obscures the things one
wants to discuss when giving a broad overview related to
particular C++ constructs). On the other hand, showing code
snippets in the introduction risks duplicating code in two
places, which will eventually get out of synch. Consequently,
this instrument should only be used sparingly.

The actual code

At present, the tools that extract information from the actual example
programs code are rather dumb. They are, to be precise, three Perl
scripts located in the directory of the
deal.II/doc/doxygen/tutorial tree, where
the .cc files of the tutorial programs are converted
into doxygen input files. In essence, what these scripts do is to
create doxygen input that contains the comments of the program as
text, and the actual code of the programs as code snippets. You
can see this when you look at the pages for each of the tutorials
where the code is indented relative to the text.

The whole thing being interpreted by doxygen means that you can
put anything doxygen understands into comments. This includes,
for example references to classes or members in the library (in
fact, you just need to write their name out and doxygen will
automatically link them), formulas, lists, etc. It all will come
out as if you had written comments for doxygen in the first
place.

The bigger question is how to write the comments that
explain what's going on in individual code blocks. Many years
back we wrote them so that every line or every two lines had
their own comment. You can still see this in some of the older
tutorial programs, though many of them have in the meantime been
converted to a newer style: it turns out that if you have
comments so frequently, it becomes hard to follow the flow of an
algorithm. In essence, you know exactly what each line does, but
you can't get an overview of what the function as a whole
does. But that's exactly the point of the tutorial programs, of
course!

So the way we now believe tutorial programs should be written is
to have comments for each logical block. For example,
the solve() function in many of the programs is
relatively straightforward and has at most a dozen lines of
code. So put a comment in front of the function that explains
all the things that are going on in the function, and then show
the function without comments in it — this way, a reader
will read through the half or full page of documentation
understanding the big picture, and can then see the whole
function all at once on a single screen without having to scroll
up and down. In the old way, the code would be spread out over a
couple pages, with comments between almost any two lines, making
it hard to see how it all fits together.

It is somewhat subjective how much code you should leave in each
block that you document separately. It might be a single line if
something really important and difficult happens there, but most
of the time it's probably more along the lines of 6 to 12 lines
— a small enough part of the code so that it's easy enough
to grasp by looking at it all at once, but large enough that it
contributes a significant part or all of an algorithm.

The results section

The results section should show (some of) the output of a
program, such as the console output and/or a visualization of
graphical output. It should also contain a brief discussion of
this output. It is intended to demonstrate what the program
does, so that a reader can see what happens if the program were
executed without actually running it. It helps to show a few
nice graphics there.

This section needs not be overly comprehensive. If the program
is the implementation of a method that's discussed in an
accompanying paper, it's entirely ok to say "for further
numerical results, see ...".

Like the introduction, the results section file is copied
verbatim into input for doxygen, so all doxygen markup is
possible there.