![]() |
Home | Libraries | People | FAQ | More |
Within the Boost community there are several styles of documenting. Most libraries nowadays are using QuickBook, the WikiWiki style documentation.
Boost.Geometry started with Doxygen, and during review it was decided to go to QuickBook. However, it was convenient to keep Doxygen also there: it does a good job of connecting descriptions to function and class declarations.
Doxygen is able to generate XML (besides the normal HTML output), containing all documentation.
So the challenge was to translate the XML generated by doxygen to QuickBook. At least, translate parts of it. Boost contains currently two tools using XSLT to go from Doxygen-XML to BoostBook, or to QuickBook. These tools are used within Boost.Random and Boost.Asio (and maybe more). However, this XSLT process was quite hard, did not deliver (yet) the wished results, and we are all C++ programmers. So another tool was born, this time in C++ using RapidXML, going from Doxygen-XML to QuickBook with the ability to mix both.
The process is as following:
This chain is currently called by "make_qbk.py", a Python script which calls the chain above in the right order. Python ensures that the chain can be handled in both Windows and Linux environments (it is probably possible to call all parts with bjam too).
There reference matrix is the only thing written in BoostBook. It is an XML file with an overview of all Boost.Geometry functionality. Presenting it like this is not possible within QuickBook, therefore BoostBook XML is used here. It is included by the QuickBook code. The Boost.Asio documentation contains a similar reference matrix.
With Doxygen it is possible to define aliases. Specificly for doxygen_xml2qbk, the alias \qbk{...} was defined. This alias \qbk{...} add some XML-tags around the text inside the alias, such that that included part is recognizable by the converter.
So the C++ code might look like this:
/*! \brief Some explanation \ingroup some_group \details Some details \tparam Geometry Description of the template parameter \param geometry Description of the variable \qbk{ [include reference/more_documentation.qbk] } */
First you see normal Doxygen comments. The last line uses the alias \qbk{...} to include a QuickBook file. So most of the documentation can be written in that QuickBook file: behaviour, complexity, examples, related pages, etc.
In the example above a QuickBook include statement is used. But any QuickBook code can be used, the QuickBook code does not have to be stored in a separate file. Two more samples:
/*! ... \qbk{ [heading Example] [area_with_strategy] [area_with_strategy_output] [heading Available Strategies] [link geometry.reference.strategies.strategy_area_cartesian Cartesian] } */
In this example pieces of QuickBook are included, two headers, two examples (this is the QuickBook way - the examples are defined elsewhere), and a link.
There are two issues: the comma and the asterisk. If within the \qbk alias a comma is used, it is recognized by Doxygen as another parameter, and therefore will not deliver the correct results, or result into errors. This is easily solvable by escaping comma's (by putting a backslash directly before the comma, \, ). It within the \qbk alias an asterisk is used on the first line, it is interpreted by Doxygen as well. This asterisk can be escaped as well, and this time it is doxygen_qbk2xml which handles this escape and translates it back into an asterisk.
Boost.Geometry contains a lot of overloads, two functions with the same name and, for example, a different number of parameters. Or, as another example, a const and a non-const version. They can be marked specificly to the doxygen_xml2qbk tool with the \qbk alias, by adding a specific description for the overload. So, for example, \qbk{distinguish,with strategy} will result in another page where the text "with strategy" is added, and it is processed as "_with_strategy" within the QuickBook section name.
With overloads, part of the documentation must be shared, and other part must not. The descriptions are often the same. But the examples are usually not. So it is a balance between sharing documentation, including shared documentation, avoiding too much separate QuickBook files containing pieces of documentation and avoiding including too much QuickBook code within the C++ code...
While documenting a large library, it is unavoidable that you have to document the same parameters in different places. For example, the template parameter Geometry, and the variable geometry, occur at least 100 times in our library.
To avoid repeating the same text again and again, Doxygen aliases are used. So \tparam_geometry means that the generic description for a template parameter geometry is inserted. \param_geometry does the same for a parameter. This is all handled by Doxygen itself. The aliases can also be parameterized, for example: \return_calc{area} is expanded to: The calculated area
This is for Doxygen alone and is not related to doxygen_xml2qbk or QuickBook.
QuickBook has the same functionality for the same purpose: macro's or templates can be defined. Within Boost.Geometry this is used in the QuickBook parts of the documentation. So the general rule would be: where it is possible to use a Doxygen alias, we use a Doxygen alias. If we are outside the scope of Doxygen and we want to define a macro, we use a QuickBook macro.
Stated otherwise, we don't use the generated Doxygen documentation, but if we would, it would look correct and would not be unreadable by unexpanded QuickBook macro's.
We favour the use of code examples within the generated documentation. Example code must be correct, so examples must compile, run, and produce the correct results. QuickBook has a nice solution to include and present C++ source code, including syntax highlighting. So we generally present the example (a complete example including necessary headerfiles) and the output. Asserts are not used here, these are examples and no tests.
So this is why we did enclose in the \qbk alias above:
[heading Example] [area_with_strategy] [area_with_strategy_output]
We define a heading, we include the example (here denoted by the name "area_with_strategy") and we include the output of the sample "area_with_strategy_output". Note that we simulate that the output is C++ code, a trick giving the appropriate formatting (there might be other ways to get the same effect).
All these QuickBook examples are included in the doc/src/examples/* folders, where also a Jamfile is present. Running bjam there ensures that nothing is broken in the examples.
Some examples, if relevant, are accompagnied by images. The images are generated by the example themselves (though marked as commented out for QuickBook), deliver an SVG file which can be manually converted to a PNG (I'm using InkScape for that which is quite convenient).