本章涵盖两个主题
特殊注释块是一个 C 或 C++ 风格的注释块,带有一些额外的标记,因此 Doxygen 知道它是一段需要出现在生成的文档中的结构化文本。下一节介绍了 Doxygen 支持的各种样式。
对于 Python、VHDL 和 Fortran 代码,有不同的注释约定,可以在Python 中的注释块、VHDL 中的注释块和Fortran 中的注释块章节中找到。
对于代码中的每个实体,都有两种(或在某些情况下三种)类型的描述,它们共同构成该实体的文档;简要描述和详细描述,两者都是可选的。对于方法和函数,还有第三种类型的描述,即所谓的主体内描述,它由方法或函数主体中找到的所有注释块的串联组成。
允许有多个简要或详细描述(但不建议,因为描述出现的顺序未指定)。
顾名思义,简要描述是简短的一句话,而详细描述提供了更长、更详细的文档。“主体内”描述也可以作为详细描述,或者可以描述一系列实现细节。对于 HTML 输出,简要描述还用于在引用项目的地方提供工具提示。
有几种方法可以将注释块标记为详细描述
您可以使用 Javadoc 样式,它由以两个 * 开头的 C 样式注释块组成,如下所示
/** * ... text ... */
或者您可以使用 Qt 样式,并在 C 样式注释块的开头添加一个感叹号 (!),如本例所示
/*! * ... text ... */
在这两种情况下,中间的 * 都是可选的,因此
/*! ... text ... */
也是有效的。
第三种选择是使用至少两行 C++ 注释行,其中每行都以附加的斜杠或感叹号开头。以下是两种情况的示例
/// /// ... text ... ///
或
//! //!... text ... //!
请注意,在这种情况下,空行会结束文档块。
有些人喜欢使他们的注释块在文档中更加可见。为此,您可以使用以下方法
/*******************************************//** * ... text ***********************************************/
注意:2 个斜杠用于结束普通注释块并开始特殊注释块。
注意:使用 clang-format 之类的格式化工具时要小心,因为它可能会将这种类型的注释视为 2 个单独的注释,并在它们之间引入空格。
或
///////////////////////////////////////////////// /// ... text ... /////////////////////////////////////////////////
或
/*********************************************** * ... text ***********************************************/
只要JAVADOC_BANNER设置为 YES
。
单击此处,查看 Doxygen 生成的相应 HTML 文档。
对于简要描述,还有几种可能性
可以使用\brief命令以及上述注释块之一。此命令在段落末尾结束,因此详细描述在空行之后。
这是一个例子
/*! \brief Brief description. * Brief description continued. * * Detailed description starts here. */
如果配置文件的JAVADOC_AUTOBRIEF设置为YES
,则使用 Javadoc 样式注释块将自动启动一个简要描述,该描述在第一个点号、问号或感叹号后跟空格或新行时结束。这是一个例子
/** Brief description which ends at this dot. Details follow * here. */
该选项对于多行特殊 C++ 注释具有相同的效果
/// Brief description which ends at this dot. Details follow /// here.
第三种选择是使用不超过一行的特殊 C++ 样式注释。以下是两个例子
/// Brief description. /** Detailed description. */
或
//! Brief description. //! Detailed description //! starts here.
请注意最后一个示例中的空行,这是将简要描述与包含详细描述的块分开所必需的。JAVADOC_AUTOBRIEF对于这种情况也应设置为NO
。
如您所见,Doxygen 非常灵活。如果您有多个详细描述,如下例所示
//! Brief description, which is //! really a detailed description since it spans multiple lines. /*! Another detailed description! */
它们将被连接起来。请注意,如果描述位于代码中的不同位置,也会出现这种情况!在这种情况下,顺序将取决于 Doxygen 解析代码的顺序。
与大多数其他文档系统不同,Doxygen 还允许您将成员(包括全局函数)的文档放在定义之前。这样,文档可以放置在源文件中,而不是头文件中。这使头文件保持简洁,并允许成员的实现者更直接地访问文档。作为折衷方案,简要描述可以放在声明之前,详细描述可以放在成员定义之前。
如果要记录文件、结构体、联合体、类或枚举的成员,有时希望将文档块放在成员之后而不是之前。为此,您必须在注释块中添加一个额外的 < 标记。请注意,这也适用于函数的参数。
以下是一些例子
int var; /*!< Detailed description after the member */
此块可用于将 Qt 样式的详细文档块放在成员之后。执行相同操作的其他方法是
int var; /**< Detailed description after the member */
或
int var; //!< Detailed description after the member //!<
或
int var; ///< Detailed description after the member ///<
大多数情况下,人们只想在成员之后放置一个简要描述。这可以通过以下方式完成
int var; //!< Brief description after the member
或
int var; ///< Brief description after the member
对于函数,可以使用 @param 命令来记录参数,然后使用 [in]
、[out]
、[in,out]
来记录方向。对于内联文档,也可以通过从方向属性开始来实现,例如
void foo(int v /**< [in] docs for input parameter v. */);
请注意,这些块的结构和含义与上一节中的特殊注释块相同,只是 < 表示成员位于块之前而不是之后。
以下是使用这些注释块的示例
单击此处,查看 Doxygen 生成的相应 HTML 文档。
\class
)不允许在这些注释块内使用。YES
时,在应用宏的地方,注释也会被替换,并且此注释随后被用作最后遇到的项的文档,而不是宏定义本身!以下是使用 Qt 风格的 C++ 代码文档示例
点击这里查看 Doxygen 生成的相应 HTML 文档。
简要描述包含在类、命名空间或文件的成员概述中,并使用小号斜体字体打印(可以通过在配置文件中将 BRIEF_MEMBER_DESC 设置为 NO
来隐藏此描述)。默认情况下,简要描述会成为详细描述的第一句话(但可以通过将 REPEAT_BRIEF 标签设置为 NO
来更改)。对于 Qt 样式,简要描述和详细描述都是可选的。
默认情况下,Javadoc 样式文档块的行为方式与 Qt 样式文档块相同。然而,这不符合 Javadoc 规范,其中文档块的第一句话会自动被视为简要描述。要启用此行为,您应该在配置文件中将 JAVADOC_AUTOBRIEF 设置为 YES。如果您启用此选项并且想要在句子中间放置一个点而不结束它,则应该在其后放置一个反斜杠和一个空格。这是一个例子
/** Brief description (e.g.\ using only a few words). Details follow. */
这里是上面显示的代码片段,这次使用 Javadoc 样式进行文档记录,并将 JAVADOC_AUTOBRIEF 设置为 YES
点击这里查看 Doxygen 生成的相应 HTML 文档。
类似地,如果希望将 Qt 样式文档块的第一句话自动视为简要描述,则可以在配置文件中将 QT_AUTOBRIEF 设置为 YES。
在上一节的示例中,注释块始终位于文件、类或命名空间的声明或定义前面,或者位于其成员的前面或后面。虽然这通常很方便,但有时可能需要将文档放在其他地方。对于文档化文件,这是必需的,因为不存在“在文件前面”这样的东西。
Doxygen 允许您将文档块放在几乎任何地方(例外情况是在函数体内部或普通的 C 样式注释块内部)。
对于不将文档块直接放在项目之前(或之后)的代价是需要在文档块内放置一个结构命令,这会导致一些信息重复。因此,在实践中,您应该避免使用结构命令,除非其他要求迫使您这样做。
结构命令(如所有其他命令)以反斜杠 (\
) 或 at 符号 (@
) 开头,如果您更喜欢 Javadoc 样式,则后跟命令名称和一个或多个参数。例如,如果您想记录上面示例中的类 Test
,您也可以将以下文档块放在 Doxygen 读取的输入中的某处
/*! \class Test \brief A test class. A more detailed class description. */
这里使用特殊命令 \class
来指示注释块包含类 Test
的文档。其他结构命令包括
\struct
用于记录 C 结构体。\union
用于记录联合体。\enum
用于记录枚举类型。\fn
用于记录函数。\var
用于记录变量或 typedef 或枚举值。\def
用于记录 #define。\typedef
用于记录类型定义。\file
用于记录文件。\namespace
用于记录命名空间。\package
用于记录 Java 包。\interface
用于记录 IDL 接口。有关这些命令和许多其他命令的详细信息,请参阅特殊命令部分。
要记录 C++ 类的成员,您还必须记录类本身。命名空间也是如此。要记录全局 C 函数、typedef、枚举或预处理器定义,您必须首先记录包含它的文件(通常这将是头文件,因为该文件包含导出到其他源文件的信息)。
/*! \file */或一个
/** @file */行。
这是一个名为 structcmd.h
的 C 头文件的示例,该文件使用结构命令进行文档记录
点击这里查看 Doxygen 生成的相应 HTML 文档。
由于上面示例中的每个注释块都包含一个结构命令,因此所有注释块都可以移动到另一个位置或输入文件(例如源文件),而不会影响生成的文档。这种方法的缺点是原型会重复,因此所有更改都必须进行两次!因此,您应该首先考虑这是否真的需要,并尽可能避免使用结构命令。我经常收到在函数前面的注释块中包含 \fn 命令的示例。这显然是 \fn 命令是多余的并且只会导致问题的情况。
当您将注释块放在扩展名为 .dox
、.txt
、.doc
、.md
或 .markdown
的文件中,或者当扩展名通过 EXTENSION_MAPPING 映射到 md
时,Doxygen 将从文件列表中隐藏此文件。
如果您有一个 Doxygen 无法解析但仍然想记录的文件,您可以使用 \verbinclude 以原样显示它,例如
/*! \file myscript.sh * Look at this nice script: * \verbinclude myscript.sh */
确保脚本明确列在 INPUT 中,或者 FILE_PATTERNS 包含 .sh
扩展名,并且可以在通过 EXAMPLE_PATH 设置的路径中找到该脚本。
对于 Python,有一种使用所谓的文档字符串 ("""
) 来记录代码的标准方法。此类字符串存储在 __doc__
中,并且可以在运行时检索。Doxygen 将提取此类注释,并假设它们必须以预格式化的方式表示。
点击这里查看 Doxygen 生成的相应 HTML 文档。
"""
时,不支持 Doxygen 的任何特殊命令,并且文本以逐字文本显示,请参阅 \verbatim。要使用 Doxygen 的特殊命令并将文本作为常规文档而不是 """
,请使用 """!
或在配置文件中将 PYTHON_DOCSTRING 设置为 NO
。"""
,还可以使用 '''
。还有另一种方法可以使用以 "##" 或 "##<" 开头的注释来记录 Python 代码。这些类型的注释块更符合 Doxygen 支持的其他语言的文档块的工作方式,并且这也允许使用特殊命令。
这是相同的示例,但现在使用 Doxygen 样式的注释
点击这里查看 Doxygen 生成的相应 HTML 文档。
由于 Python 看起来更像 Java 而不是 C 或 C++,您应该在配置文件中将 OPTIMIZE_OUTPUT_JAVA 设置为 YES
。
对于 VHDL,注释通常以“--”开头。Doxygen 将提取以“--!”开头的注释。VHDL 中只有两种类型的注释块;单行“--!”注释表示简要描述,多行“--!”注释(其中每行都重复使用“--!”前缀)表示详细描述。
注释始终位于要记录的项的前面,但有一个例外:对于端口,注释也可以位于项的后面,此时被视为该端口的简要描述。
以下是一个带有 Doxygen 注释的 VHDL 文件示例
点击此处查看 Doxygen 生成的相应 HTML 文档。
从 VHDL 2008 开始,也可以使用 /
*
样式注释。
Doxygen 将 /
* ... *
/
处理为普通注释,并将 /
*! ... *
/
样式注释处理为 Doxygen 要解析的特殊注释。
要获得外观正确的输出,您需要在配置文件中将 OPTIMIZE_OUTPUT_VHDL 设置为 YES
。这也会影响许多其他设置。如果它们尚未正确设置,Doxygen 将发出警告,告知哪些设置被覆盖。
当将 Doxygen 用于 Fortran 代码时,您应该将 OPTIMIZE_FOR_FORTRAN 设置为 YES
。
解析器会尝试猜测源代码是固定格式的 Fortran 代码还是自由格式的 Fortran 代码。这可能并不总是正确。如果不是,则应使用 EXTENSION_MAPPING 来纠正此问题。通过设置 EXTENSION_MAPPING = f=FortranFixed f90=FortranFree
,扩展名为 f
的文件被解释为固定格式的 Fortran 代码,扩展名为 f90
的文件被解释为自由格式的 Fortran 代码。
对于 Fortran,“!>”或“!<”表示注释开始,“!!”或“!>”可用于将单行注释延续为多行注释。
以下是一个已记录的 Fortran 子例程的示例
作为替代方案,您也可以在固定格式代码中使用注释
上一节重点介绍了如何使代码中的注释为 Doxygen 所知,它解释了简要描述和详细描述之间的区别,以及结构命令的使用。
在本节中,我们将查看注释块本身的内容。
Doxygen 支持多种格式化注释的样式。
最简单的形式是使用纯文本。这将在输出中按原样显示,非常适合简短描述。
对于较长的描述,您通常会需要更多结构,例如逐字文本块、列表或简单表格。为此,Doxygen 支持 Markdown 语法,包括 Markdown Extra 扩展的一部分。
Markdown 被设计成非常易于阅读和书写。其格式受纯文本邮件的启发。Markdown 非常适合简单的通用格式,例如项目的介绍页面。Doxygen 还支持直接读取 Markdown 文件。有关更多详细信息,请参阅Markdown 支持章节。
对于特定于编程语言的格式,Doxygen 在 Markdown 格式的基础上提供了两种附加标记形式。