Frameworks/Frameworks Documentation Policy
Introduction
Classes in the KDE frameworks are used by many Qt and KDE applications, hence, their usage should be as simple as possible. To help in that endeavor it should be fully documented to let any developer use it. New classes that are added to KDE frameworks must comply with this doc, all existing classes are grandfathered in, but need to be updated to comply if they do not. The KDE library documentation is based upon the Java documentation specification. Follow the link for full in depth documentation about that format.
These guidelines apply not only to classes in KDE frameworks, but also to libraries elsewhere (KDE PIM, for instance, has a large number of support libraries that need documentation). To some extent they also apply to applications, if only so that it is easier for new developers to contribute meaningfully to the application — well-documented code is easy-to-extend code.
Files in the Repository Root Dir
The repository root dir must contain two files: README.md and metainfo.yaml.
README.md
The content of this file is used to generate the front page of the framework documentation. It must feature at least the following fields:
# $FrameworkName One line description. ## Introduction Longer description.
The introduction should give quick pointers to what are the important classes (the main objects handled by the framework), and a small code snippet showing how to perform a simple task using the framework, if possible.
metainfo.yaml
This file is used by various tools to generate the documentation. It must contain a tier key which must be a number indicating the framework tier.
It may also contain a framework-dependencies key containing a list of frameworks this framework depends on. This key is used by KApidox dependency diagram generator to ensure it captures all dependencies. In most situations, this key can be skipped: you only need to add in specific situations, like if you depend on a framework but do not link to any of its targets (because you only use CMake macros provided by the framework) or because a framework dependency is optional but you want to ensure it is mentioned in the diagram.
For example, the kded framework depends on CMake macros provided by the KInit framework. Here is what kded.yaml looks like:
tier: 3 # this is only for backward compatibility. group: Frameworks subgroup: Tier 3 public_lib: true framework-dependencies: - kinit
Other keys are possible, and using them is highly encouraged. They allow api.kde.org to display more info about the framework:
- maintainer: KDE Identity identifier of the maintainer of the framework
- description: Short one-line description, should be approximately 5 words. On API, it is displayed after the framework name in the info box: "KArchive: File compression"
- platforms: List of platforms that this framework has been tested on
- libraries: List of libraries exported by the framework, an example is given hereafter
- cmakename: Name of CMake module installed by the library (the name that must be used in find_package)
Here is an example of a complete metainfo.yaml file (from the Sonnet framework):
maintainer: sandsmark description: Support for spellchecking tier: 1 type: solution platforms: - name: All portingAid: false deprecated: false release: true libraries: - qmake: SonnetCore # Library name given to ecm_generate_pri_file cmake: "KF5::SonnetCore" # Name given to add_library - qmake: SonnetUi cmake: "KF5::SonnetUi" cmakename: KF5Sonnet # Name of the KF5SonnetConfig.cmake.in file, without the Config.cmake.in part public_lib: true group: Frameworks subgroup: Tier 1
Document the Classes
Add a Class Description
Doxygen uses the @brief sentence about the class to generate a short class description. If no such sentence is defined, doxygen is configured by the KDE API documentation tools like KApiDox & ECMAddQch to use instead the first sentence of the class for that. This sentence should provide the reason for why the class exists and when to use it, i.e. the description should give a simple overview of what the class does. Examples: "KMyWidgetClass is a class to handle lists", "A widget that shows balls bouncing.", "Monitors directory(s) for changes". The first sentence should be able to stand on its own when displayed by an IDE as the short description. Note: to work-around doxygen detecting the end of the sentence by the first "." character followed by whitespace, but falsely also doing that with abbreviations like "e.g.", escape the following whitespace with "\ ", like "e.g.\ ".
Suggestions for when the class should and should not be used are very helpful, same with referencing classes that are similar, but fill different needs.
@author should be used to show who the author(s) of the class are. If there are more than one @author tag, @par Maintainer: Foo Bar ([email protected]) should be added. This is required so that developers will know whom is the correct person to contact when they find a bug or have a patch.
Provide Example Code
A simple example usage of the class should be provided. Not only does example code show how the functions in the class interact, but they are good summaries and should be placed in the class descriptions. Note that developers will often copy this coder verbatim as a starting point and so great care should be taken to make sure that the code is clean, clear and concise. Good full variable names such as stream or file should be chosen instead of abbreviations like s and fl. @code and @endcode should be used to mark code examples.
Example Application
If applicable, provide an example application which shows the usage of the class. A test application or existing application that a developer can reference is an excellent resource for developers looking to learn about the class.
Add Screenshots
If the class is a widget add a screenshot. Screenshots provide a simple and easy way for developers to recognize what the class provides. The screenshots should reside in class description. Images can be placed in docs/pics and included with @image, like this:
/**
* ...
* @image html myclass.png "Image subtitle"
*/
Document Public and Protected Members
Developers do not read reference documentation like a book, they scan it for the information that they need. This is why it is important that everything is at the place they expect it to be. IDE's might parse the functions and so it is important that the correct meta data is present and not hidden in the description. Functions should use the "@" tags in the following order:
- @brief
- @description
- @param
- @return
- @exception
- @see
- @author
- @since
- @deprecated
KApiDoc and ECMAddQch configure doxygen to alternatively use the first sentence, if no @brief tag is set.
General usage guidelines when using @param, @return ...etc:
- Tag names should be all lower case
- If there is just one sentence then there should be no period at the end
- The first word should not be capitalized
- There should not be a dash between the parameter name and the description. The "-" is added by the doc processor and if the developer adds one then there might be two in the resulting html/pdf/tex/etc documentation.
Correct:
/**
* ...
* @param foo the value to convert
* @param bar the base to be used when converting @p foo.
* This can be 8 (octal), 10 (decimal), or 16 (hexadecimal).
*/
Incorrect:
/**
* ...
* @param foo The value to convert
* ^ (Don't capitalize the first letter)
* @param foo the value to convert.
* ^ (For one sentence, don't use period at the end)
* @Param foo the value to convert
* ^ (Don't capitalize the first letter of tag (doxygen command) name)
* @param foo-the value to convert
* ^ (Don't add a -, the docs tools will add that automatically)
* @param bar the base to be used when converting @p foo.
* This can be 8 (octal), 10 (decimal), or 16 (hexadecimal)
* ^ (Multi-sentence docs block, should have a period at the end)
*/
Functions that return bool should not use "iff" in @return statements.
Correct:
/**
* ...
* @return @c true if button is on and is a toggle button, @c false otherwise
*/
Incorrect:
/**
* ...
* @return @c true **iff** button is on and is a toggle button
*/
@deprecated should be added to any function or class that should be removed in the next binary incompatible release (3.0, 4.0, 5.0). The comment should state the version at which it got deprecated and the class/function that replaces it, if any.
Correct:
/**
* ...
* @deprecated Since 4.2. Use foo().
*/
Incorrect:
/**
* ...
* @deprecated No longer use.
*/
Document Enumerations
Enums must be documented, and each enumerated value has to be explained. Same policy as functions.
Writing Style
Avoid humor and exclamation marks, it is confusing.
Check spelling and grammar: Documentation represents a project a lot more than you might think. Take the time to give it the proper polish it deserves. For a lot of developers the documentation will not only explain what the class does, but will be the only view into how the class works.
Build the API Documentation before Committing any Code
Use at least one of the API documentation generation tools used with KDE Frameworks to build the doc locally and fix any errors or warnings in the documentation so others do not have to:
- For the online documentation tool KApidox see its documentation for how to run it locally on a KDE Frameworks module.
- For the offline docs created with ECMAddQch, ensure to have the build flag BUILD_QCH set to TRUE before running make, and for a quick turn-around inspect the intermediate HTML files in the KF5${MODULENAME}_ECMQchDoxygen/ in the build dir, otherwise the generated & installed QCH file.
If Doxygen complains about a particular parameter not being documented, document it. A typical example is:
/**
* @param msecs the number of milliseconds until the timeout
* is signalled
*/
void setTimeout(uint msecs, bool repeat);
Here the second parameter is not documented, and Doxygen will complain. Add the relevant documentation otherwise crucial information about the use of the class is missing.
If Doxygen complains about @param referring to a parameter that isn't there, add the name for the parameter.
/**
* @param msecs the number of milliseconds until the timeout
* is signalled
* @param repeat whether the timeout should happen every
* @p msecs milliseconds, or just once
*/
void setTimeout(uint, bool);
Here, Doxygen will complain that the names of the parameters do not occur in the function signature. Add the names. The lack of names can be really confusing if you have a method with several parameters of the same type. Probably the documentation lists the parameters in the order they occur in the function signature, but there is no way to tell.
Sometimes there is a conflict between reducing Doxygen warnings and compile warnings. This happens in interface definitions where you give a default implementation of a method with no real body, like the following:
virtual void setTimeout(uint, bool) { }
This compiles fine; Doxygen will complain about missing names, so you add names:
virtual void setTimeout(uint timeout, bool repeat) { }
Now the compilation gives warnings because parameters timeout and repeat are not used in the function body. There is the Q_UNUSED macro to deal with this. It "uses" its argument, which shuts the compiler up.
virtual void setTimeout(uint timeout, bool repeat)
{
Q_UNUSED(timeout);
Q_UNUSED(repeat);
}
With the function defined like this, both Doxygen and the C++ compiler are happy. Q_UNUSED does not incur any run-time penalty.