0

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:

  • \example and \include only allow you to paste the entire contents of a file into a code block. Since I don't want to have #include example_foo.cpp show up at the top of every example in the documentation, these directives aren't of any help.
  • \snippets don't seem to be mergeable into a single code block.
  • \dontinclude uses \skip and \until, but their search pattern is displayed in the code block.

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.

3
  • Which version of doxygen are you using? For the \snippet command you need also to have some placeholders (like [...] and preferably use the \noop command in front of them so they won't show up in regular documentation, which means you can use the snippets in your real code and use that as snippets as well) . Commented May 14 at 9:46
  • @albert My project and the MRE's Dockerfile are using Doxygen 1.9.4, though if there are any new Doxygen features that I absolutely need, I could convince my team members to update Doxgen. See the question's code blocks for how I've used \snippet and //! [one]. I don't think the \noop command helps for resolving my issue. Commented May 14 at 11:29
  • 1
    Doxygen 1.9.4 is a bit older (May 5, 2022) the curent version is doxygen 1.13.2. The later will not solve the problem that I assume you have (the empty line between the 2 snippets) as this is because of it are 2 different "parts". The newer doxygen version has some improvements and also some significant improvements in the results regarding the \snippet command. I created an "answer" base on the \dontinclude that I think meets your needs (at least with the direct doxygen interpretation in HTML). Commented May 14 at 12:04

2 Answers 2

2

An answer based on the \dontincludeand just based on doxygen output.

Using as nums/nums_struct.hpp from the original post:

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

we get with doxygen 1.13.2 (and something similar with doxygen 1.9.4):

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.