Doxygen copydoc tag to reuse code examples
Asked Answered
V

3

9

I want to reuse a block of example code using the \copydoc tag.

To explain the problem. Let's say I have two documented functions:

/** Aquires resource. */
Resource* AquireResource( int id );

/** Releases resource.*/
void ReleaseResource( Resource* res );

In many cases I want to put in a small code example of how to use the function in a context, which often involves using a range of functions which all might be sufficiently depicted by the same code example, for instance:

/** Aquires resource.
 *
 * \par Example:
 * \code
 * Resource* res = AquireResource( 42 );
 * ReleaseResource( res );
 * \endcode
 */
Resource* AquireResource( int id );

/** Releases resource.
 *
 * \par Example:
 * \code
 * Resource* res = AquireResource( 42 );
 * ReleaseResource( res );
 * \endcode
 */
void ReleaseResource( Resource* res );

So the code example is duplicated, not good. I want to use copydoc, something like this:

/** \page ResourceExampleTag
 * \code
 * Resource* res = AquireResource( 42 );
 * ReleaseResource( res );
 * \endcode
 */    

/** Aquires resource.
 *
 * \par Example:
 * \copydoc ResourceExampleTag
 */
Resource* AquireResource( int id );

/** Releases resource.
 *
 * \par Example:
 * \copydoc ResourceExampleTag
 */
void ReleaseResource( Resource* res );

I.e. code example in one place, reused in other places.

This is actually as far as I have gotten, but I'm not satisfied with it since I don't know how to hide the dummy page 'ResourceExampleTag' I'm creating to copy from. So somewhere in the resulting documentation there's a page with some code completely out of context. As far as I can see the thing here is to find a tag which can be referenced by copydoc and which doesn't render any content on itself. However, that's just my line of thought, there might be far better ones.

I can also mention that I (for several reasons I won't bother to go into) don't wish to use the \example tag with external example code files.

Thanks.

Venatic answered 15/2, 2011 at 11:1 Comment(0)
C
8

I've found the @snippet command to be more useful for creating examples inline like you are trying to do. Basically I have a source file for my examples, my_examples.cpp

/// [exampleMyFirst]
void foo(void)
{
    Resource* foo = AquireResource(42);
    ReleaseResource(foo);
    foo = nullptr; //Or NULL
}
/// [exampleMyFirst]

/// [exampleTwo]
void bar(void)
{
    std::cout << "Unrelated to my first example." << std::endl;
}
/// [exampleTwo]

Then in the doxygen documentation block for your function use @snippet to use the example.

/// Aquires resource.
///
/// @par Example:
/// @snippet my_examples.cpp exampleMyFirst
Resource* AquireResource( int id );

... And of course only after finishing the answer, do I realize you didn't want to use an external file, but since I stumbled upon the question trying to do what I described here, it might be useful to someone!

Chemiluminescence answered 8/12, 2013 at 2:7 Comment(1)
Actually, being able to use a single external file for all examples and neatly selecting them by tags is probably the cleanest I've seen thus far. Cheers.Venatic
R
12

This works for me:

class MyClass
{
  public:
    /**
     * @class hide_commonstuff
     * @par Example:
     * @code
     * The common example
     * @endcode
     */

    /**
     * First function.
     *
     * @copydoc hide_commonstuff
     */
    void first();

    /**
     * Second function.
     *
     * @copydoc hide_commonstuff
     */
    void second();
};

and then in the doxygen configuration you set EXCLUDE_SYMBOLS = hide_*

The the documentation is copied from the hide_commonstuff but this class is not shown in the class list.

Also: there needs to be a blank line before @copydoc or else it does not work (sometimes, not always...)

Romaromagna answered 7/2, 2012 at 15:40 Comment(3)
Waow thank you for the hint about the blank line above the copydoc tag for it to work!Deepdyed
This works well, but might there perhaps be some other tag that could be used for the method template instead of @class? Using @class for a method seems a little semantically dubious. I've tried the obvious @fn, but without success.Project
Instead of using EXCLUDE_SYMBOLS = hide_* in doxygen configuration you can add @private before @class for each class that you want to hide.Bywaters
C
8

I've found the @snippet command to be more useful for creating examples inline like you are trying to do. Basically I have a source file for my examples, my_examples.cpp

/// [exampleMyFirst]
void foo(void)
{
    Resource* foo = AquireResource(42);
    ReleaseResource(foo);
    foo = nullptr; //Or NULL
}
/// [exampleMyFirst]

/// [exampleTwo]
void bar(void)
{
    std::cout << "Unrelated to my first example." << std::endl;
}
/// [exampleTwo]

Then in the doxygen documentation block for your function use @snippet to use the example.

/// Aquires resource.
///
/// @par Example:
/// @snippet my_examples.cpp exampleMyFirst
Resource* AquireResource( int id );

... And of course only after finishing the answer, do I realize you didn't want to use an external file, but since I stumbled upon the question trying to do what I described here, it might be useful to someone!

Chemiluminescence answered 8/12, 2013 at 2:7 Comment(1)
Actually, being able to use a single external file for all examples and neatly selecting them by tags is probably the cleanest I've seen thus far. Cheers.Venatic
D
0

I had the same issue and couldn't find any elegant solution either. I eventually came up with the following:

1) On some random page, link to a new subpage called Hidden

/*! \mainpage My MainPage
   blah blah blah
   \subpage Hidden
   */

2) Create the hidden page, linking to your 'dummy' example topics. Name the page &nbsp;

/*! \page Hidden &nbsp;
    \subpage MyExample
   */

3) Now you can \copydoc MyExample wherever you like, and it is invisible to users of the HTML generated by doxygen.

Disconformity answered 24/6, 2011 at 3:36 Comment(1)
sorry, didn't get this to work. In the generated HTML, the index clearly show the (rather confusing) page hiearchy "mainpage"->"&nbsp;"->"MyExample"Venatic

© 2022 - 2024 — McMap. All rights reserved.