python-sphinxdoxygen

How to merge Doxygen snippets?


I have a project using Doxygen, Breathe, and Sphinx for documentation. The hardcoded example snippets of code in the documentation have become a pain to maintain, as the project is constantly evolving. I want to make the example snippets be covered by our automated tests.

I experimented with \example, \include, \snippet, and \dontinclude, but each of them seem to have problems:

I am not interested in any of the directives that require you to hardcode the line numbers, since that's very brittle.

Of these, \snippet seems the most promising and useful:

two separate code blocks

But I'd like to merge the snippets, since these separate code blocks look ugly.

I've created a minimal reproducible example repository here:

.
├── Dockerfile
├── docs
│   ├── conf.py
│   ├── doxygen
│   │   └── Doxyfile
│   └── index.rst
├── example
│   └── nums.cpp
├── nums
│   └── nums_struct.hpp
└── README.md

example/nums.cpp:

//! [one]
int one() {
    return 1;
}
//! [one]

int hidden() {
    return 42;
}

//! [two]
int two() {
    return 2;
}
//! [two]

int main() {
    return one() + two();
}

nums/nums_struct.hpp:

/// \snippet nums.cpp one
/// \snippet nums.cpp two
struct nums_struct
{};

I'm on Arch Linux, but the command sudo docker build . -t hello && sudo docker run -v .:/example hello should work on other Linux distros out of the box, with Docker as the only dependency. It outputs docs/_build/html/index.html, which you can view using your browser.

There was a similar question in 2017 titled Is there a way to merge snippets or make a disjoint snippet in Doxygen?, but it didn't get any answers.


Solution

  • Thanks to @albert for nudging me in the right direction.

    His answer does not handle functions containing braces, like if-statement curly braces that indicate the start and stop of the scope.

    I figured out that by placing the end marker (//! [stop_one] here) at the end of a line of code, we can prevent a second newline from appearing in the docs.

    So using this nums/nums_struct.hpp:

    /// \dontinclude nums.cpp
    /// \skipline start_one
    /// \until stop_one
    /// \skipline start_two
    /// \until stop_two
    struct nums_struct
    {};
    

    and this example/nums.cpp:

    //! [start_one]
    int one() {
        if (1) {
            return 1;
        }
        return 1;
    } //! [stop_one]
    
    int hidden() {
        return 42;
    }
    
    //! [start_two]
    int two() {
        return 2;
    } //! [stop_two]
    
    int main() {
        return one() + two();
    }
    

    we can get the output I was originally looking for:

    enter image description here