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.

sharkin
  • 12,162
  • 24
  • 86
  • 122

3 Answers3

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...)

rve
  • 5,897
  • 3
  • 40
  • 64
  • 2
    Waow thank you for the hint about the blank line above the copydoc tag for it to work! – greydet May 29 '13 at 15:26
  • 1
    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. – Arto Bendiken Sep 22 '13 at 03:26
  • 1
    Instead of using `EXCLUDE_SYMBOLS = hide_*` in doxygen configuration you can add `@private` before `@class` for each class that you want to hide. – BillyJoe Aug 30 '19 at 10:04
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!

Tim Beaudet
  • 791
  • 7
  • 16
  • 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. – sharkin Dec 11 '13 at 10:29
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.

BenM
  • 11
  • 1
  • sorry, didn't get this to work. In the generated HTML, the index clearly show the (rather confusing) page hiearchy "mainpage"->" "->"MyExample" – sharkin Jun 27 '11 at 13:30