1

I have a bunch of namespaces (containing free functions) and classes (containing member functions, obviously), each of which has a Doxygen comment at the top level and some Doxygen comments for its members. They're within a top-level namespace (one for the whole project) and secondary namespaces (to break the project into packages). Like this:

  • proj/pkg1/foo.hpp: class proj::pkg1::Foo
  • proj/pkg1/bar.hpp: class proj::pkg1::Bar
  • proj/pkg1/baz.hpp: namespace proj::pkg1::Baz
  • proj/pkg2/one.hpp: class proj::pkg2::One
  • proj/pkg2/two.hpp: namespace proj::pkg2::Two

I don't have any @file comments. They'd be totally redundant, because there's already exactly one main comment per component, which is attached to the main class or namespace.

I tried running this through Doxygen, and the result is a mess:

  • The namespaces and classes are separated into two different hierarchies, both in the header row and the navigation panel. But I want them all in a single tree, because e.g. pkg2::One belongs alongside pkg2::Two.
  • The main hierarchy of namespaces is buried three levels down the navigation panel (Project name -> namespaces -> namespace list). It's next to "Namespace Members" - who uses that!?
  • There's another hierarchy for the files (and directories). This is redundant because these exactly match the hierarchy of namespaces (and classes).
  • This is digressing a bit now, but I'd also like to add comments to the package namespaces. These have the same problem of separating classes and namespaces (not such a big deal) but also show up various free functions e.g. operator<<(proj::pkg2::One.

Is there any way to clean things up a bit? Maybe with Sphinx and Breathe?

Example screen shot

Here is what Doxygen produces by default on the above code (it doesn't even mention Baz and Two!), and what I prefer it to look like:

Example mock screen shot

Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49
  • Which version of doxygen are you using. Can you show where the output is not as you expected / small complete example. – albert Feb 28 '19 at 08:51
  • @albert THe most recent version (1.8.15), but I don't think anything relevant has changed recently (I have had the same problem multiple times over the years). I already fully described some example files, and I have added a screenshot of what the output (which is no surprise for anyone used to Doxygen) and a mock up of the sort of thing I am looking for (apologies for my poor PhotoShop skills!). Don't take the mock up too literally, it doesn't have to look exactly like that. I just want to merge classes and namespaces and get rid of some of the junk. – Arthur Tacca Feb 28 '19 at 12:13
  • For the merging of the namelist entities and class entities, I don't have a direct answer, but mybe the grouping (see `\defgroup` etc) might give some results. Regarding the 'Files' entry see the configuration item `LAYOUT_FILE` and the command `doxygen -l ...`. Regarding the line with 'Main page etc' have a look at the configuration setting `DISABLE_INDEX`. – albert Feb 28 '19 at 12:22
  • @albert Thanks, using groups/modules is a a good idea. But as far as I can tell, it would mean writing a lot of boilerplate Doxygen in every file, or writing a script to generate the boilerplate automatically. I think that would be hard to understand/maintain in the long term. – Arthur Tacca Feb 28 '19 at 18:02
  • Well possibly part of the boilerplate can be accomplished with ALIASES where sat the begin of a group part one would have `\beginGroup`, possibly with arguents, and at the end of a group a `\endGroup`. – albert Feb 28 '19 at 18:43
  • 1
    Just a quick note of encouragement to say this question _got_ attention. I investigated to propose a solution, but sadly could not find one. Merging the class and namespace trees together would look better, this would be a good improvement to the doxygen tool (in my opinion). – Marc Alff Mar 08 '19 at 08:31
  • @MarcAlff Thanks Marc, that is encouraging! Your effort is much appreciated. I find it odd that there aren't better tools out there for generating documentation. Perhaps if you're really serious about documentation you just write it all out by hand. – Arthur Tacca Mar 10 '19 at 10:44

2 Answers2

1

This is a particularly horrible hack, but I mention it for the record. You could decide that classes are dealt with best by Doxygen, and relabel all the component namespaces (the third-level ones) to classes. Like this:

namespace proj {
namespace pkg1 {

/// @brief The Doxygen comment goes here.
#ifdef DOXYGEN
class
#else
namespace
#endif
Baz {

Then set PREDEFINED = DOXYGEN in the Doxyfile.

Obviously, the drawbacks to the this are that it looks ugly as sin in the source code, and it's confusing that it shows up as a "class" in the documentation.

Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49
0

To get the ball rolling, here's a possible solution:

Change expectations a bit: instead of hoping for the two level structure to be presented to readers all in one go, put up with part of it presented at a time. Make the user click through a separate page for each namespace in the tree:

  • The documentation page for the proj namespace shows all the packages it contains (i.e. in the example it shows namespaces pkg1 and pkg2).

  • Each package namespace page shows all of the classes and component namespaces in it (in separate lists, which is a little annoying, but at least all the stuff for each package is together).

You can hide the tree view with GENERATE_TREEVIEW=NO and hide the header row DISABLE_INDEX=YES.

The mainpage can just be a link to the top-level proj namespace page (with the usual content of the main page moved to the proj detailed description) with code like this:

/**
@mainpage
@ref proj "Click here for the proj documentation"
*/

A slight variation is to manually list the packages in the main page with code like this and bypass the proj namespace page. This would work well for a project that doesn't have an overall top-level namespace, or where you want finer control over the main page.

/**
@mainpage

Packages:
- @ref proj::pkg1 @n @copybrief proj::pkg1
- @ref proj::pkg2 @n @copybrief proj::pkg2
*/
Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49