Wording and style for Doxygen documentation

Discussion of all aspects of the game engine, including development of new and existing features.

Moderator: Forum Moderators

CrawlCycle
Posts: 27
Joined: November 20th, 2020, 5:07 am

Wording and style for Doxygen documentation

Post by CrawlCycle »

The wiki has a short style guide for using Doxygen: https://wiki.wesnoth.org/Doxygen
However, I think the guide is incomplete for the following reasons.
  • The guide doesn't specify the standard terminology
  • The guide also doesn't specify the one and only way to format things.
I write down my personal way here, in case that I forget.
If it doesn't make sense, please feel free to comment.
--♦--
Location of Doxygen block
  • Don’t duplicate the Doxygen comment in the header file and in the implementation file.
  • Put the Doxygen comments for public APIs into the header file (.hpp).
  • Doxygen comments for private APIs can go to the implementation file (.cpp).
The page at https://wiki.wesnoth.org/Doxygen is 10 years old.
source: irc 11/21/2020

Style
  • Always use @ instead of \ for the special commands of Doxygen.
  • Use the /** ... */ style of Doxygen comment block.

Code: Select all

/** Don't use @brief for one line comment. */
/**< Don't use @brief for one line comment for an attribute. */
(Visual studio code can't handle ///< well.)

The Doxygen blocks should similarly use /* ... */ in the following fashion.

Code: Select all

	/**
	 * Variant for storing WML attributes.
	 * The most efficient type is used when assigning a value. For instance,
	 * strings "yes", "no", "true", "false" will be detected and stored as boolean.
	 * @note The blank variant is only used when querying missing attributes.
	 *       It is not stored in config objects.
	 */
source: irc 11/21/2020

General

The order of the sections is:
  • Brief description followed by detailed description.
  • @pre
  • @tparam (in the order of the template parameters of the function/method).
  • @param (in the same order as they appear in the signature of the function/method).
  • @return
  • @retval
  • @throw
  • @note
  • @warning
  • @example and @code ... @endcode
Other rules:
  • Always document the behavior instead of the internal logic of the public API.
  • Don't duplicate documentation for the non-const and const version of a method.
    Use @copydoc to document the const version.
  • Each line of a doxygen block has at most 79 characters.
  • Skip anything that is meaningless.
    For example, we don't need the @param line to know the parameter key is "The key".

    Code: Select all

    	/**
    	 * Append an empty node to the list of children with the @key.
    	 * @param key The key.
    	 * @throw     If this node is invalid, throw an exception.
    	 */
    	config& add_child(config_key_type key);
    
Description
The brief description of every function (including methods of a class) must start with one of the following verbs:
  • Construct (Constructor)
  • Create (Create a new object)
  • Get (Get something within this object. Example: attribute. or an item in an array within the object )
  • Set (Set the value of something within this object. Opposite of "get".)
  • Calculate (Non-trivial calculation)
  • Find (Trivial calculation)
  • Check (Return a bool without modifying this object or the arguments)
  • Append (Add an existing object to the end of an ordered structure, such as a list, array, or vector.).
  • Insert (Insert an existing object to a position in an ordered structure)
Notes
  • Note that the verbs have no -s or -es at the end because the brief description should be in imperative mood.
  • "Create" instead of "make" because "make" has a less specific meaning than create.
    For example, "make it ..." can mean "make it correct". But "create it" must mean create something.
    Example:

    Code: Select all

    /** 
     * Get the attribute with the @p key, or create an empty attribute with the key 
     * if no such attribute exists.
     */
    
  • Use period at the end of the brief description.
  • Don't use @brief or @details
    Since JAVADOC_AUTOBRIEF = YES in Wesnoth's DoxyFile, the period would allow
    seamless transition from brief to detailed description:

    Code: Select all

        /**
         * Brief description which ends at this dot. Details follow
         * here.
         */
  • Don't use passive voice.
  • Don't write "a reference to xyz" or "a pointer to xyz" because the signature of the function already tells that.

    Code: Select all

    Replace /** Get a reference to the attribute with the given @a key */
    by      /** Get the attribute with the @a key */
    
    Replace /** Get a pointer to the attribute with the given @a key */
    by      /** Get the attribute with the @a key */
    
Wording
Index.
  • Use first to refer to the front item. For example x[0] is the first item of the array x.
  • Use last to refer to the last item.
  • Don't talk about the actual value of an index. For example, don't use n^{th} or item 3.
    This helps to avoid the inconsistency between English and C++.
    English starts counting from one. C++ starts indexing from 0.
  • Use end to refer exclusively to a pointer to the one beyond the last item.
Other.
  • Multiple instead of several
  • One instead of single
  • Mandatory (the function throws an error if it can't get the object)

    Code: Select all

    /** 
     * Get the mandatory first child with the key.
    ...
     * @throw        If the child with the key does not exist, throw a
     *               @ref wml_exception.
     */
  • Singleton (the function returns a local static variable)
Ideas Issues
Existing doxygen comment in config.hpp:

Code: Select all

	/**
	 * Raises an exception if @a this is not valid.
	 */
	void check_valid() const;
Now what to do with this?
Last edited by CrawlCycle on November 26th, 2020, 9:28 am, edited 73 times in total.
User avatar
Pentarctagon
Project Manager
Posts: 5526
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Wording and style for Doxygen documentation

Post by Pentarctagon »

Another good place to ask if people have any opinions is on Wesnoth's Discord or IRC development channel. To be honest though, if you have a good reason to do something different than the Doxygen wiki page says, then I think you should feel free to do it that way. After all, the wiki page hasn't been updated in about a decade, so I wouldn't take it as something that people would be inherently opposed to changing.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
CrawlCycle
Posts: 27
Joined: November 20th, 2020, 5:07 am

Re: Wording and style for Doxygen documentation

Post by CrawlCycle »

@Pentarctagon Thanks. I will probably work on the documentation a bit more and then ask at the IRC.

Putting the brief description in the header make sense if:
  • the code base uses a lot of templates in many header files, or
  • a lot of developers use console editors (vi, vim, emacs etc)
Jumping from usage to implementation takes only 1 mouse click in graphical IDE (such as CLion, eclipse, Code::Blocks).
I would think that putting the brief description in both header and source is an unnecessary duplication.
Last edited by CrawlCycle on November 21st, 2020, 6:58 pm, edited 1 time in total.
User avatar
Pentarctagon
Project Manager
Posts: 5526
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Wording and style for Doxygen documentation

Post by Pentarctagon »

I don't know of any current developers who use console editors, so that's not much of a concern to me.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Wording and style for Doxygen documentation

Post by Celtic_Minstrel »

CrawlCycle wrote: November 21st, 2020, 3:58 am Don't use the plural form of the verb.
The verb forms you cited immediately prior to this were all plural. In English, adding an S to a noun makes it plural, but adding an S to a verb makes it singular.
CrawlCycle wrote: November 21st, 2020, 3:58 am Don't use passive voice.
This should be taken as a guideline, not a hard rule. Sometimes passive voice might make it sound more natural. That said, it's still a good guideline to avoid passive voice where possible.
CrawlCycle wrote: November 21st, 2020, 3:58 am Each line of a doxygen block has at most 79 characters.
Personally, I wouldn't take this as a hard limit. If you're only two characters over, who cares?
[*] Don't write "a reference to xyz" because the signature of the function already tells that.
CrawlCycle wrote: November 21st, 2020, 3:58 amUse zeroth instead of first to refer to the front item.
I actually don't like this convention at all. It doesn't make any sense when extended beyond the front item - you'd have to call the item at index 1 the first item when it's definitely no such thing! I'd much prefer to use "first" to refer to the front item, or if others dislike this, then just don't use ordinals at all and refer to it as "item 0" or the like.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
CrawlCycle
Posts: 27
Joined: November 20th, 2020, 5:07 am

Re: Wording and style for Doxygen documentation

Post by CrawlCycle »

Celtic_Minstrel wrote: November 22nd, 2020, 7:58 am The verb forms you cited immediately prior to this were all plural. In English, adding an S to a noun makes it plural, but adding an S to a verb makes it singular.
I probably should call it the imperative mood and infinitive form instead of plural form.
User avatar
octalot
General Code Maintainer
Posts: 783
Joined: July 17th, 2010, 7:40 pm
Location: Austria

Re: Wording and style for Doxygen documentation

Post by octalot »

I use a console editor, and jumping from usage to implementation takes only 2 keypresses :D
Putting the whole doc in the .hpp sounds good to me.
CrawlCycle
Posts: 27
Joined: November 20th, 2020, 5:07 am

Re: Wording and style for Doxygen documentation

Post by CrawlCycle »

Celtic_Minstrel wrote: November 22nd, 2020, 7:58 am
CrawlCycle wrote: November 21st, 2020, 3:58 amUse zeroth instead of first to refer to the front item.
I actually don't like this convention at all. It doesn't make any sense when extended beyond the front item - you'd have to call the item at index 1 the first item when it's definitely no such thing! I'd much prefer to use "first" to refer to the front item, or if others dislike this, then just don't use ordinals at all and refer to it as "item 0" or the like.
I can use first to refer to the front item.

I don't quite get your point about index 1 though. I can call x[0] the zeroth item and call x[1] the first item. The English and index match in this case (e.g. 0 = zeroth, 1 = first).

On the other hand, std::pair uses first and second to refer to the two items in the pair.

Code: Select all

/**
 * Get the mandatory first child with the key.
 * Get the mandatory zeroth child with the key.
 * Get the mandatory child 0 with the key.
 * Get the mandatory front child with the key.
 */
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Wording and style for Doxygen documentation

Post by Celtic_Minstrel »

CrawlCycle wrote: November 22nd, 2020, 2:48 pm I can call x[0] the zeroth item and call x[1] the first item.
That's exactly the problem. It's confusing if the first item isn't the first item.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
CrawlCycle
Posts: 27
Joined: November 20th, 2020, 5:07 am

Re: Wording and style for Doxygen documentation

Post by CrawlCycle »

Celtic_Minstrel wrote: November 22nd, 2020, 3:43 pm
CrawlCycle wrote: November 22nd, 2020, 2:48 pm I can call x[0] the zeroth item and call x[1] the first item.
That's exactly the problem. It's confusing if the first item isn't the first item.
I am trying to follow the rule to use first to refer to the front element of an array.
But that rule leads to this problem.

If we use first to refer to the front element, we have the following:
  • 1st -> x[0]
  • 2nd -> x[1]
  • 3rd -> x[2]
  • nth -> x[n - 1]
  • (n + 1)th -> x[n]
Then,

Code: Select all

	/**
	 * Get the (n + 1)th child with the key, or the static invalid node if there
	 * is none.
	 */
	config &child(config_key_type key, int n = 0);
Is it ok to replace all nth by (n + 1)th?
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Wording and style for Doxygen documentation

Post by Celtic_Minstrel »

I think what I would recommend is to avoid ordinals altogether if this bothers you. Don't say "first" or "zeroth" or "second" or even "nth". Say "child n" or similar.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
CrawlCycle
Posts: 27
Joined: November 20th, 2020, 5:07 am

Re: Wording and style for Doxygen documentation

Post by CrawlCycle »

Celtic_Minstrel wrote: November 22nd, 2020, 6:58 pm I think what I would recommend is to avoid ordinals altogether if this bothers you. Don't say "first" or "zeroth" or "second" or even "nth". Say "child n" or similar.
If we use child 0 to refer to the front child, the new description would be:
  • Code: Select all

    /** Get the child 0 with the key */
However this description has two possible meanings:
  1. Get the front child, among all children with the given key.
  2. Get the front child if the front child's key is same as the given key.
If we can use parentheses in English, the new description may become:
  • Code: Select all

    /** Get the (child with the key) 0 */
    Notice that this is a reversal of the order of tokens, compared to the next description.
The original description may become:
  • Code: Select all

    /** Get the first (child with the key) */
In simple English, the scope of each quantifier (e.g. first, all, ...) seems to be everything that follows the quantifier and within the same clause.
The "0" in "child 0" doesn't follow this pattern of quantifiers in simple English.

By simple English, I mean at least no reversal of the normal order of words in English.

How to rewrite this description without using ordinals and keep it short?
Last edited by CrawlCycle on November 22nd, 2020, 7:28 pm, edited 1 time in total.
User avatar
Pentarctagon
Project Manager
Posts: 5526
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Wording and style for Doxygen documentation

Post by Pentarctagon »

I think this is getting overthought. Very few people are going to get confused by what "first" means, regardless of whether it refers to [0] (WML, C++) or [1] (lua). It's the element that has no other elements before it.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
CrawlCycle
Posts: 27
Joined: November 20th, 2020, 5:07 am

Re: Wording and style for Doxygen documentation

Post by CrawlCycle »

cppreference.com seems to follow two rules:

Talk about first and last element: Don't talk about the actual value of any index (such as nth):
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Wording and style for Doxygen documentation

Post by Celtic_Minstrel »

CrawlCycle wrote: November 22nd, 2020, 7:18 pm
Celtic_Minstrel wrote: November 22nd, 2020, 6:58 pm I think what I would recommend is to avoid ordinals altogether if this bothers you. Don't say "first" or "zeroth" or "second" or even "nth". Say "child n" or similar.
If we use child 0 to refer to the front child, the new description would be:
  • Code: Select all

    /** Get the child 0 with the key */
However this description has two possible meanings:
  1. Get the front child, among all children with the given key.
  2. Get the front child if the front child's key is same as the given key.
If we can use parentheses in English, the new description may become:
  • Code: Select all

    /** Get the (child with the key) 0 */
    Notice that this is a reversal of the order of tokens, compared to the next description.
The original description may become:
  • Code: Select all

    /** Get the first (child with the key) */
In simple English, the scope of each quantifier (e.g. first, all, ...) seems to be everything that follows the quantifier and within the same clause.
The "0" in "child 0" doesn't follow this pattern of quantifiers in simple English.

By simple English, I mean at least no reversal of the normal order of words in English.

How to rewrite this description without using ordinals and keep it short?
Yeah, in this context the non-ordinal form doesn't make much sense. I think there's probably no choice but to use ordinals here and say "first"? As Pentarctagon says, I think using "first" for element 0 is the most logical choice; avoiding other ordinals like "second" and "nth" is fine too.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Post Reply