【Doxygen】为项目生成一个炫酷的说明文档

在这里插入图片描述

【Doxygen】为项目生成一个炫酷的说明文档

1 Doxygen简介

Doxygen 是一个能从带注释的源码中自动生成说明文档的标准工具,它支持众多流行的编程语言,包括 C/C++C#PHPJavaPythonIDL

Doxygen能够从以下三个方面进行工作:

  • 从一组源文件中生成 HTML 格式的在线文档和 LaTeX 格式的离线文档,此外还提供了 RTF(富文本编辑器,例如MS-Word)、PostScript、超链接 PDF、压缩 HTML 和 Unix 等格式输出。
  • 从源码中提取代码结构,通过依赖关系图、继承图和协作图自动生成各种元素之间的关系图。
  • 为用户制作用户手册和网站

Doxygen 可以在 Mac OS、Linux 和 Windows 下工作,还可以在大多数其他 Unix 上运行。

2 安装 Doxygen

这里只介绍开发常用的安装方式,Ubuntu下可以直接从 apt 源进行安装

sudo apt-get install graphviz
sudo apt-get install doxygen
# 带 gui 的 doxygen
sudo apt-get install doxygen-gui

3 基本使用方式

在这里插入图片描述

图3-1 与Doxygen相关的不同工具之间的关系图

3.1 从命令行生成

3.1.1 创建配置文件
doxygen -g <config-file>
# 或(不含注释)
doxygen -s -g <config-file>

<config-file>为生成配置文件的名称,如果不输入则默认为Doxyfile,若已存在名为 <config-file>的文件,则会将原先的 <config-file>重命名为 <config-file>.bak。

3.1.2 修改配置文件

这里列举出常用的配置选项,关于完整的配置选项说明,可以参考 doxygen 官网提供的Config-Docs

3.1.2.1 项目配置
  • DOXYFILE_ENCODING

    指定用于配置文件中所有字符的编码,默认为 UTF-8。

  • PROJECT_NAME

    项目名称,默认为 My Project

3.1.2.2 输入配置
  • INPUT

    标记用于指定包含记录的源文件的文件和/或目录。

  • INPUT_ENCODING

    标记可用于指定 doxygen 解析的源文件的字符编码。

  • RECURSIVE

    指定是否也应搜索子目录以查找输入文件。

3.1.2.3 输出配置
  • OUTPUT_DIRECTORY

    标记用于指定将生成的文档写入的(相对或绝对)路径。如果输入了相对路径,则该路径将相对于 doxygen 的启动位置。如果留空,将使用当前目录。

  • OUTPUT_LANGUAGE

    标记用于指定编写 doxygen 生成的所有文档的语言。

3.1.2.4 构建配置
  • EXTRACT_ALL

    如果设置为 YES,则 doxygen 将假定文档中的所有实体都已记录,即使没有可用的文档也是如此。私有类成员和静态文件成员将被隐藏,除非EXTRACT_PRIVATE分别EXTRACT_STATIC标记设置为 YES.

  • EXTRACT_PRIVATE

    如果设置为 YES,则类的所有私有成员都将包含在文档中。

  • EXTRACT_STATIC

    如果设置为 YES,则文件的所有静态成员都将包含在文档中。

  • EXTRACT_LOCAL_CLASSES

    如果设置为 YES,则在源文件中本地定义的类(和结构)将包含在文档中。如果设置为 NO,则仅包括头文件中定义的类。

3.1.2.5 绘图配置
  • HAVE_DOT

    是否使用 Graphviz1 图形可视化工具包

  • CALL_GRAPH

    为每个全局函数或类方法生成一个调用依赖图,启用此选项将显着增加运行时间。

  • CALLER_GRAPH

    为每个全局函数或类方法生成调用者依赖图,启用此选项将显着增加运行时间。

3.1.3 使配置生效

最终让配置再次生效:

doxygen Doxyfile # 选择你自己的文件,默认是 Doxyfile

3.2 从 GUI 生成

在终端输入

doxywizard
# 修改配置文件
doxywizard Doxyfile

出现以下 GUI 界面,并在相应位置进行修改

3.2.1 向导模式配置

在这里插入图片描述

图3-2 向导模式配置
3.2.2 专业模式配置

在这里插入图片描述

图3-3 专业模式配置

最终,点击 Run doxygen 即可生成一份说明文档

在这里插入图片描述

图3-4 Run doxygen生成文档

3.3 查看文档

在生成的 html 中寻找 index.html 文件,打开。

在这里插入图片描述

当前页面为空白的主页,并且根据源码生成了两个可供查看的选项:Classes、Files

4 配合 CMake 进行配置

以上操作如果每发布一般代码,都需要手动配置一次,那将显得及其复杂,若能做到根据是否安装 Doxygen 来自动处理安装过程,将会特别方便。

为此,我参考了 OpenCVdoc/CMakeLists.txt 的源码,对利用 CMake 配置 Doxygen 做了一些总结。

4.1 FindDoxygen

查看本地路径 /usr/local/share/cmake-x.xx/Modules 可以发现一个 FindDoxygen.cmake 文件,里面对于 Doxygen 做了很多函数和预设变量的定义。

我们可以使用 find_package 来查找Doxygen,使用 doxygen_add_docs 函数来生成简易的 Doxyfile。2可参考以下代码:

find_package(Doxygen)
if (DOXYGEN_FOUND)
    doxygen_add_docs(abc ${CMAKE_CURRENT_SOURCE_DIR}/modules
    			         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    			         COMMENT "Generate man page")
endif()
  • WORKING_DIRECTORY 为工作路径
  • COMMENT 将作为add_custom_target()的命令进行传递

可以使用已经生成的 Doxyfile.abc 进行最终说明文档的生成,但仍然不够炫酷。

不过也可以在 build 文件夹下找到一个 Doxyfile.abc 和一个 CMakeDoxyfile.in 文件,其中 CMakeDoxyfile.in 文件可用于实时加载 CMake 变量,生成最终的 Doxyfile 文件,这正是下文要介绍的内容。

4.2 使用 configure_file 编写配置文件

4.2.1 configure_file 基本语法

具体的语法可参考作者的这一篇文章,这里展示在 OpenCV 中是如何使用的

# writing file
configure_file("${OPENCV_DOCS_DOXYGEN_LAYOUT}" DoxygenLayout.xml @ONLY)
configure_file("${OPENCV_DOCS_DOXYFILE_IN}" ${doxyfile} @ONLY)
configure_file(root.markdown.in ${rootfile} @ONLY)

先不考虑第一个 configure_file 的功能,第二个 configure_file 作用就是将 Doxyfile.in 生成一个 Doxyfile 文件,用于 Doxygen 的配置,第三个 configure_file 是为了生成 main page。这些 *.in 文件的内容与原始的文件基本一致,只不过所有的值均设置成了 CMake 变量,以更加灵活的载入。

4.2.2 编写 Doxyfile.in

这里给出了一个模板,其代码在附件1中,其中有个风格配置的一行代码:

HTML_EXTRA_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/stylesheet.css

这里使用到的 stylesheet.css 文件,文件内容可参考 OpenCV 下的 doc/stylesheet.css。没有安装 opencv 的小伙伴可参考附件2,需手动创建文件,并编辑代码。

4.2.3 编写 root.markdown.in

这一步是为了生成一个 markdown 文件,用来作为说明文档的 main page,一般主页面可以提供给读者一系列的模块、类的说明。

OpenCV 中是自动查找所有模块,并使用 cmake 的字符串操作,组合起来,其代码如下,可供参考

OpenCV modules {#mainpage}
==============

- @ref intro
- @ref tutorial_root
- @ref tutorial_py_root
@CMAKE_DOXYGEN_TUTORIAL_JS_ROOT@
@CMAKE_DOXYGEN_TUTORIAL_CONTRIB_ROOT@
- @ref faq
- @ref citelist

@CMAKE_DOXYGEN_MAIN_REFERENCE@

@CMAKE_DOXYGEN_EXTRA_REFERENCE@

当然也可以自己手写一个 root.markdown.in 文件,可能对于初学者来说更加友好,缺点就是如果模块、类等内容发生了改变,可能需要自己手动修改 root.markdown.in 文件。

4.3 配置生成信息

4.3.1 获取与 Doxyfile 相关的 CMake 变量

可参考以下 OpenCV 中的代码来设置 cmake 变量

# set export variables
### 解释:设置 Doxyfile 里的 INPUT 项
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_INPUT_LIST "${rootfile} ; ${faqfile}")
### 解释:其中 ${rootfile} 用在了 Doxyfile 中的 USE_MDFILE_AS_MAINPAGE 项
### 解释:设置 Doxygen 里的 INPUT 项
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_IMAGE_PATH "${doxygen_image_path}")
### 解释:设置 Doxygen 里的 EXCLUDE 项
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_EXCLUDE_LIST "${CMAKE_DOXYGEN_EXCLUDE_LIST}")
string(REPLACE ";" " " CMAKE_DOXYGEN_ENABLED_SECTIONS "${CMAKE_DOXYGEN_ENABLED_SECTIONS}")
# TODO: remove paths_doc from EXAMPLE_PATH after face module tutorials/samples moved to separate folders
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_EXAMPLE_PATH  "${example_path} ; ${paths_doc} ; ${paths_sample}")
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_INCLUDE_ROOTS "${paths_include}")
### 解释:设置 Doxyfile 里的 LAYOUT_FILE 项
set(CMAKE_DOXYGEN_LAYOUT "${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml")
### 解释:设置 Doxyfile 里的 OUTPUT_DIRECTORY 项
set(CMAKE_DOXYGEN_OUTPUT_PATH "doxygen")
### 解释:设置 root.markdown.in 内的参数
set(CMAKE_DOXYGEN_MAIN_REFERENCE "${refs_main}")
set(CMAKE_DOXYGEN_EXTRA_REFERENCE "${refs_extra}")
set(CMAKE_EXTRA_BIB_FILES "${bibfile} ${paths_bib}")
4.3.2 生成文档

在命令行中输入:

mkdir build
cd build
cmake ..

可以看到出现的 Doxyfile 文件,可以直接输入

doxygen Doxyfile

来生成对应的 html/index.html

也可采用以下方法,即在 CMakeLists.txt 中添加可被 make 的目标

add_custom_target(doxygen)
# execute 'make doxygen' to create *.html 
add_custom_command(
    TARGET doxygen
    POST_BUILD
    COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile

意思就是,如果在命令行中输入make doxygen,则可以会自动执行文档的生成过程,即运行 doxygen Doxyfile

4.4 效果展示

左边为 OpenCV 的文档,右边为作者仿照 OpenCV 设计的文档,可以看出,基本一致

在这里插入图片描述

图4 效果展示

附件

附件1

Doxyfile.in 模板文件

DOXYFILE_ENCODING      = UTF-8
PROJECT_NAME           = 
PROJECT_NUMBER         = 
PROJECT_BRIEF          = 
PROJECT_LOGO           = 
OUTPUT_DIRECTORY       = @CMAKE_DOXYGEN_OUTPUT_PATH@
CREATE_SUBDIRS         = YES
OUTPUT_LANGUAGE        = Chinese
BRIEF_MEMBER_DESC      = YES
REPEAT_BRIEF           = YES
ABBREVIATE_BRIEF       = "The $name class" \
                         "The $name widget" \
                         "The $name file" \
                         is \
                         provides \
                         specifies \
                         contains \
                         represents \
                         a \
                         an \
                         the
ALWAYS_DETAILED_SEC    = NO
INLINE_INHERITED_MEMB  = YES
FULL_PATH_NAMES        = YES
STRIP_FROM_PATH        =
STRIP_FROM_INC_PATH    =
SHORT_NAMES            = NO
JAVADOC_AUTOBRIEF      = NO
JAVADOC_BANNER         = NO
QT_AUTOBRIEF           = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS           = YES
SEPARATE_MEMBER_PAGES  = NO
TAB_SIZE               = 4
ALIASES                =
TCL_SUBST              =
OPTIMIZE_OUTPUT_FOR_C  = NO
OPTIMIZE_OUTPUT_JAVA   = NO
OPTIMIZE_FOR_FORTRAN   = NO
OPTIMIZE_OUTPUT_VHDL   = NO
OPTIMIZE_OUTPUT_SLICE  = NO
EXTENSION_MAPPING      =
MARKDOWN_SUPPORT       = YES
TOC_INCLUDE_HEADINGS   = 5
AUTOLINK_SUPPORT       = YES
BUILTIN_STL_SUPPORT    = YES
CPP_CLI_SUPPORT        = NO
SIP_SUPPORT            = NO
IDL_PROPERTY_SUPPORT   = YES
DISTRIBUTE_GROUP_DOC   = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING            = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS  = NO
TYPEDEF_HIDES_STRUCT   = NO
LOOKUP_CACHE_SIZE      = 0
EXTRACT_ALL            = YES
EXTRACT_PRIVATE        = YES
EXTRACT_PRIV_VIRTUAL   = YES
EXTRACT_PACKAGE        = YES
EXTRACT_STATIC         = YES
EXTRACT_LOCAL_CLASSES  = YES
EXTRACT_LOCAL_METHODS  = YES
EXTRACT_ANON_NSPACES   = NO
HIDE_UNDOC_MEMBERS     = NO
HIDE_UNDOC_CLASSES     = NO
HIDE_FRIEND_COMPOUNDS  = NO
HIDE_IN_BODY_DOCS      = NO
INTERNAL_DOCS          = NO
CASE_SENSE_NAMES       = YES
HIDE_SCOPE_NAMES       = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_INCLUDE_FILES     = YES
SHOW_GROUPED_MEMB_INC  = NO
FORCE_LOCAL_INCLUDES   = NO
INLINE_INFO            = YES
SORT_MEMBER_DOCS       = YES
SORT_BRIEF_DOCS        = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES       = NO
SORT_BY_SCOPE_NAME     = NO
STRICT_PROTO_MATCHING  = NO
GENERATE_TODOLIST      = YES
GENERATE_TESTLIST      = YES
GENERATE_BUGLIST       = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS       =
MAX_INITIALIZER_LINES  = 30
SHOW_USED_FILES        = YES
SHOW_FILES             = YES
SHOW_NAMESPACES        = YES
FILE_VERSION_FILTER    =
LAYOUT_FILE            = @CMAKE_DOXYGEN_LAYOUT@
CITE_BIB_FILES         =
QUIET                  = NO
WARNINGS               = YES
WARN_IF_UNDOCUMENTED   = YES
WARN_IF_DOC_ERROR      = YES
WARN_NO_PARAMDOC       = NO
WARN_AS_ERROR          = NO
WARN_FORMAT            = "$file:$line: $text"
WARN_LOGFILE           =
INPUT                  = @CMAKE_DOXYGEN_INPUT_LIST@
INPUT_ENCODING         = UTF-8
FILE_PATTERNS          = *.c \
                         *.cc \
                         *.cxx \
                         *.cpp \
                         *.c++ \
                         *.java \
                         *.ii \
                         *.ixx \
                         *.ipp \
                         *.i++ \
                         *.inl \
                         *.idl \
                         *.ddl \
                         *.odl \
                         *.h \
                         *.hh \
                         *.hxx \
                         *.hpp \
                         *.h++ \
                         *.cs \
                         *.d \
                         *.php \
                         *.php4 \
                         *.php5 \
                         *.phtml \
                         *.inc \
                         *.m \
                         *.markdown \
                         *.md \
                         *.mm \
                         *.dox \
                         *.doc \
                         *.txt \
                         *.py \
                         *.pyw \
                         *.f90 \
                         *.f95 \
                         *.f03 \
                         *.f08 \
                         *.f \
                         *.for \
                         *.tcl \
                         *.vhd \
                         *.vhdl \
                         *.ucf \
                         *.qsf \
                         *.ice
RECURSIVE              = YES
EXCLUDE                = @CMAKE_DOXYGEN_EXCLUDE_LIST@
EXCLUDE_SYMLINKS       = NO
EXCLUDE_PATTERNS       =
EXCLUDE_SYMBOLS        =
EXAMPLE_PATH           =
EXAMPLE_PATTERNS       = *
EXAMPLE_RECURSIVE      = NO
IMAGE_PATH             =
INPUT_FILTER           =
FILTER_PATTERNS        =
FILTER_SOURCE_FILES    = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE = @rootfile@
SOURCE_BROWSER         = YES
INLINE_SOURCES         = NO
STRIP_CODE_COMMENTS    = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION    = YES
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS        = YES
USE_HTAGS              = NO
VERBATIM_HEADERS       = YES
CLANG_ASSISTED_PARSING = NO
CLANG_OPTIONS          =
CLANG_DATABASE_PATH    =
ALPHABETICAL_INDEX     = YES
COLS_IN_ALPHA_INDEX    = 5
IGNORE_PREFIX          =
GENERATE_HTML          = YES
HTML_OUTPUT            = @CMAKE_DOXYGEN_OUTPUT_PATH@/html
HTML_FILE_EXTENSION    = .html
HTML_HEADER            =
HTML_FOOTER            =
HTML_STYLESHEET        =
HTML_EXTRA_STYLESHEET  = @CMAKE_CURRENT_SOURCE_DIR@/stylesheet.css
HTML_EXTRA_FILES       = @CMAKE_DOXYGEN_HTML_FILES@
HTML_COLORSTYLE_HUE    = 220
HTML_COLORSTYLE_SAT    = 100
HTML_COLORSTYLE_GAMMA  = 80
HTML_TIMESTAMP         = YES
HTML_DYNAMIC_MENUS     = YES
HTML_DYNAMIC_SECTIONS  = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET        = NO
DOCSET_FEEDNAME        = "Doxygen generated docs"
DOCSET_BUNDLE_ID       = org.doxygen.Project
DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME  = Publisher
GENERATE_HTMLHELP      = YES
CHM_FILE               =
HHC_LOCATION           =
GENERATE_CHI           = NO
CHM_INDEX_ENCODING     =
BINARY_TOC             = NO
TOC_EXPAND             = NO
GENERATE_QHP           = NO
QCH_FILE               =
QHP_NAMESPACE          = org.doxygen.Project
QHP_VIRTUAL_FOLDER     = doc
QHP_CUST_FILTER_NAME   =
QHP_CUST_FILTER_ATTRS  =
QHP_SECT_FILTER_ATTRS  =
QHG_LOCATION           =
GENERATE_ECLIPSEHELP   = NO
ECLIPSE_DOC_ID         = org.doxygen.Project
DISABLE_INDEX          = NO
GENERATE_TREEVIEW      = NO
ENUM_VALUES_PER_LINE   = 4
TREEVIEW_WIDTH         = 250
EXT_LINKS_IN_WINDOW    = NO
FORMULA_FONTSIZE       = 14
FORMULA_TRANSPARENT    = YES
FORMULA_MACROFILE      =
USE_MATHJAX            = NO
MATHJAX_FORMAT         = HTML-CSS
MATHJAX_RELPATH        = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/
MATHJAX_EXTENSIONS     =
MATHJAX_CODEFILE       =
SEARCHENGINE           = YES
SERVER_BASED_SEARCH    = NO
EXTERNAL_SEARCH        = NO
SEARCHENGINE_URL       =
SEARCHDATA_FILE        = searchdata.xml
EXTERNAL_SEARCH_ID     =
EXTRA_SEARCH_MAPPINGS  =
GENERATE_LATEX         = NO
LATEX_OUTPUT           = latex
LATEX_CMD_NAME         =
MAKEINDEX_CMD_NAME     = makeindex
LATEX_MAKEINDEX_CMD    = makeindex
COMPACT_LATEX          = NO
PAPER_TYPE             = a4
EXTRA_PACKAGES         =
LATEX_HEADER           =
LATEX_FOOTER           =
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES      =
PDF_HYPERLINKS         = YES
USE_PDFLATEX           = YES
LATEX_BATCHMODE        = NO
LATEX_HIDE_INDICES     = NO
LATEX_SOURCE_CODE      = NO
LATEX_BIB_STYLE        = plain
LATEX_TIMESTAMP        = NO
LATEX_EMOJI_DIRECTORY  =
GENERATE_RTF           = NO
RTF_OUTPUT             = rtf
COMPACT_RTF            = NO
RTF_HYPERLINKS         = NO
RTF_STYLESHEET_FILE    =
RTF_EXTENSIONS_FILE    =
RTF_SOURCE_CODE        = NO
GENERATE_MAN           = NO
MAN_OUTPUT             = man
MAN_EXTENSION          = .3
MAN_SUBDIR             =
MAN_LINKS              = NO
GENERATE_XML           = NO
XML_OUTPUT             = xml
XML_PROGRAMLISTING     = YES
XML_NS_MEMB_FILE_SCOPE = NO
GENERATE_DOCBOOK       = NO
DOCBOOK_OUTPUT         = docbook
DOCBOOK_PROGRAMLISTING = NO
GENERATE_AUTOGEN_DEF   = NO
GENERATE_PERLMOD       = NO
PERLMOD_LATEX          = NO
PERLMOD_PRETTY         = YES
PERLMOD_MAKEVAR_PREFIX =
ENABLE_PREPROCESSING   = YES
MACRO_EXPANSION        = NO
EXPAND_ONLY_PREDEF     = NO
SEARCH_INCLUDES        = YES
INCLUDE_PATH           =
INCLUDE_FILE_PATTERNS  =
PREDEFINED             =
EXPAND_AS_DEFINED      =
SKIP_FUNCTION_MACROS   = YES
TAGFILES               =
GENERATE_TAGFILE       =
ALLEXTERNALS           = NO
EXTERNAL_GROUPS        = YES
EXTERNAL_PAGES         = YES
CLASS_DIAGRAMS         = YES
DIA_PATH               =
HIDE_UNDOC_RELATIONS   = YES
HAVE_DOT               = YES
DOT_NUM_THREADS        = 0
DOT_FONTNAME           = Helvetica
DOT_FONTSIZE           = 10
DOT_FONTPATH           =
CLASS_GRAPH            = YES
COLLABORATION_GRAPH    = YES
GROUP_GRAPHS           = YES
UML_LOOK               = NO
UML_LIMIT_NUM_FIELDS   = 10
TEMPLATE_RELATIONS     = NO
INCLUDE_GRAPH          = YES
INCLUDED_BY_GRAPH      = YES
CALL_GRAPH             = YES
CALLER_GRAPH           = YES
GRAPHICAL_HIERARCHY    = YES
DIRECTORY_GRAPH        = YES
DOT_IMAGE_FORMAT       = svg
INTERACTIVE_SVG        = NO
DOT_PATH               =
DOTFILE_DIRS           =
MSCFILE_DIRS           =
DIAFILE_DIRS           =
PLANTUML_JAR_PATH      =
PLANTUML_CFG_FILE      =
PLANTUML_INCLUDE_PATH  =
DOT_GRAPH_MAX_NODES    = 50
MAX_DOT_GRAPH_DEPTH    = 0
DOT_TRANSPARENT        = NO
DOT_MULTI_TARGETS      = NO
GENERATE_LEGEND        = YES
DOT_CLEANUP            = YES

附件2

stylesheet.css 文件

/* The standard CSS for doxygen 1.8.6 */

body, table, div, p, dl {
    font: 400 14px/22px Helvetica, 'Segoe UI', Arial, freesans, sans-serif;
    word-wrap: break-word;
}

code {
    font-size: 85%;
    font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;
    white-space: pre-wrap;
    padding: 1px 5px;
    background-color: rgb(223, 229, 241);
    vertical-align: baseline;
}

body {
    background-image: url(bodybg.png);
    margin: 0 auto;
}

div.fragment {
    padding: 3px;
    padding-bottom: 0px;
}

div.line {
    padding-bottom: 3px;
    font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;
}

div.contents {
    width: 980px;
    margin: 0 auto;
    padding: 15px 15px;
    border: 1px solid rgb(10, 80, 122);
    background-color: #fff;
}

span.arrow {
    height: 13px;
}

div.image img{
    max-width: 900px;
}

#projectlogo
{
    text-align: center;
    vertical-align: middle;
    border-collapse: separate;
    padding-left: 0.5em;
}

参考文档


  1. Graphviz ↩︎

  2. FindDoxygen ↩︎

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Cccolt_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值