I'm finally giving up the angle bracket tax imposed on me by Microsoft's XML documentation format (and what's the point, since the MSVC environment still doesn't do anything fancy with it for C++ projects) and switching my current project to using Doxygen with a Javadoc style syntax.
It is fantastic. The inline documentation is much easier to read and type, and the generated output is so much more useful and versatile. In particular, I have the MULTILINE_CPP_IS_BRIEF
option turned on, which allows me to write as long of a "brief" description as I want, and then break up my "details" documentation into paragraphs using blank lines. In other words:
/// Changes the active viewing area of the currently selected region.
///
/// The modification is merely enqueued. This function has no effect until the
/// FlushRegion() function is called.
///
/// Newly-exposed regions will not be repainted automatically. The user must also
/// call the UpdateRegion() function on these regions to cause their contents to
/// be redrawn.
///
/// @param dx The amount, in pixels, to shift the visible region horizontally.
/// @param dy The amount, in pixels, to shift the visible region vertically.
///
/// @remarks
/// Note that this function is reentrant, but not thread-safe!
void ScrollRegion(int dx, int dy);
This gives me exactly the output I desire, while keeping down the number of noisy meta-commands like @brief
and \details
that I have to use.
The problem comes when I try to include a second paragraph in my "remarks" section, just like I did (implicitly) for the "details" section. For example:
/// Changes the active viewing area of the currently selected region.
///
/// The modification is merely enqueued. This function has no effect until the
/// FlushRegion() function is called.
///
/// Newly-exposed regions will not be repainted automatically. The user must also
/// call the UpdateRegion() function on these regions to cause their contents to
/// be redrawn.
///
/// @param dx The amount, in pixels, to shift the visible region horizontally.
/// @param dy The amount, in pixels, to shift the visible region vertically.
///
/// @remarks
/// Note that this function is reentrant, but not thread-safe!
///
/// If thread safety is required, the user must handle locking and unlocking
/// the region manually.
void ScrollRegion(int dx, int dy);
The generated output does not interpret the second paragraph in the @remarks
section as part of the remarks. I can tell because it is not indented to the same level in the HTML output, and it is not located under the <simplesect kind="remark">
tag in the XML output.
I tried adding a @par
command to the beginning of the second paragraph, but that didn't do what I wanted, either. The new paragraph is still not a child of the "remarks" section. In the XML output, it is getting placed inside of a new <simplesect kind="para">
tag that is a sibling of the original <simplesect kind="remark">
tag.
While researching this, I saw that someone else had duplicated the @remarks
command:
/// Changes the active viewing area of the currently selected region.
///
/// The modification is merely enqueued. This function has no effect until the
/// FlushRegion() function is called.
///
/// Newly-exposed regions will not be repainted automatically. The user must also
/// call the UpdateRegion() function on these regions to cause their contents to
/// be redrawn.
///
/// @param dx The amount, in pixels, to shift the visible region horizontally.
/// @param dy The amount, in pixels, to shift the visible region vertically.
///
/// @remarks
/// Note that this function is reentrant, but not thread-safe!
/// @remarks
/// If thread safety is required, the user must handle locking and unlocking
/// the region manually.
void ScrollRegion(int dx, int dy);
That does produce the output that I desire. Both paragraphs are nested in <para>
tags under the <simplesect kind="remark">
tag in the XML output, and the visual relationship is correct in the HTML output. But that's ugly and looks like a mistake to me.
Is there a standard way to do this that I'm missing? Surely I'm not the first person to want multiple paragraphs in the "remarks" section of my documentation... And this isn't limited to @remarks
; the same thing happens with @internal
, for example.
I have the latest version of Doxygen installed (1.8.2), but I very much doubt that this is version-specific.
Your final example code, that is
/// @remarks
/// Note that this function is reentrant, but not thread-safe!
/// @remarks
/// If thread safety is required, the user must handle locking and unlocking
/// the region manually.
is exactly the expected use of \remarks
for multi-paragraph comment blocks. From the doxygen manual (emphasis mine):
\remark { remark text }
Starts a paragraph where one or more remarks may be entered. The paragraph will be indented. The text of the paragraph has no special internal structure. All visual enhancement commands may be used inside the paragraph. Multiple adjacent
\remark
commands will be joined into a single paragraph. Each remark will start on a new line. Alternatively, one\remark
command may mention several remarks. The\remark
command ends when a blank line or some other sectioning command is encountered.
So \remark
(and \remarks
, which is just the same as \remark
) ends at the end of a paragraph, but adjacent \remark
s will be stitched together to form one \remark
block.
You are right to say that this behaviour is not limited to \remarks
and \remark
. The same applies to any command that takes a paragraph of text as an argument, see, for example, \bug
, \todo
, \warning
etc.
One solution that seems to work that I haven't seen mentioned here, is to end your lines with \n. This will keep everything grouped together, while putting in the white space you may want to see.
If you want a blank line, make sure the line above has \n, and you have a blank line with \n on it.
In your example, you would want:
/// @remarks
/// Note that this function is reentrant, but not thread-safe!\n
/// \n
/// If thread safety is required, the user must handle locking and unlocking
/// the region manually.
And that should make it appear as you want it to appear.
If you don't like having multiple @remarks lines in your source for your multi-paragraph remarks, I think you can use @parblock & @endparblock to include multiple paragraphs for a single @remark.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With