从 1.8.3 版本开始,Doxygen 提供了使用外部索引工具和搜索引擎搜索 HTML 的功能。 这有几个优点
为了避免每个人都必须开始编写自己的索引器和搜索引擎,Doxygen 为每个操作提供了一个示例工具:用于索引数据的 doxyindexer
和用于在索引中搜索的 doxysearch.cgi
。
数据流如下图所示
doxygen
生成原始搜索数据doxyindexer
将数据索引到搜索数据库 doxysearch.db
doxysearch.cgi
。doxysearch.cgi
工具将对数据库执行查询并返回结果。第一步是通过 Web 服务器使搜索引擎可用。 如果你使用 doxysearch.cgi
,这意味着使 CGI 二进制文件可从 Web 服务器访问(即,能够通过以 http: 开头的 URL 从浏览器运行它)
如何设置 Web 服务器不在本文档的范围之内,但是如果你例如安装了 Apache,则可以将 doxysearch.cgi
文件从 Doxygen 的 bin
目录复制到 Apache Web 服务器的 cgi-bin
目录。 有关详细信息,请阅读 apache 文档。
要测试 doxysearch.cgi
是否可访问,请启动 Web 浏览器并将 URL 指向该二进制文件,并在末尾添加 ?test
http://yoursite.com/path/to/cgi/doxysearch.cgi?test
你应该收到以下消息
Test failed: cannot find search index doxysearch.db
如果你使用 Internet Explorer,系统可能会提示你下载一个文件,然后该文件将包含此消息。
由于我们没有创建或安装 doxysearch.db
,因此测试失败是正常的。 如何纠正这一点将在下一节中讨论。
在继续下一节之前,请将上述 URL(不包括 ?test
部分)添加到 Doxygen 配置文件中的 SEARCHENGINE_URL 标签
SEARCHENGINE_URL = http://yoursite.com/path/to/cgi/doxysearch.cgi
要使用外部搜索选项,请确保在 Doxygen 的配置文件中启用以下选项
SEARCHENGINE = YES SERVER_BASED_SEARCH = YES EXTERNAL_SEARCH = YES
这将使 Doxygen 在输出目录(使用 OUTPUT_DIRECTORY 配置)中生成一个名为 searchdata.xml
的文件。 你可以使用 SEARCHDATA_FILE 选项更改文件名(和位置)。
下一步是将原始搜索数据放入索引中以进行高效搜索。 你可以使用 doxyindexer
来完成此操作。 只需从命令行运行它
doxyindexer searchdata.xml
这将创建一个名为 doxysearch.db
的目录,其中包含一些文件。 默认情况下,该目录将在启动 doxyindexer
的位置创建,但你可以使用 -o
选项更改该目录。
将 doxysearch.db
目录复制到与 doxysearch.cgi
所在的目录相同的目录,并通过将浏览器指向以下位置来重新运行浏览器测试
http://yoursite.com/path/to/cgi/doxysearch.cgi?test
你现在应该收到以下消息
Test successful.
现在你应该能够从 HTML 输出中搜索单词和符号。
如果你有多个 Doxygen 项目并且这些项目是相关的,则可能需要在任何项目的文档中搜索所有项目中的单词。
为了实现这一点,需要做的就是将所有项目的搜索数据组合到一个索引中,例如,对于在目录 project_A 和 project_B 中生成 searchdata.xml 的两个项目 A 和 B,运行
doxyindexer project_A/searchdata.xml project_B/searchdata.xml
然后将生成的 doxysearch.db
复制到 doxysearch.cgi
所在的目录。
searchdata.xml
文件不包含任何绝对路径或链接,那么如何将多个项目的搜索结果链接回正确的文档集? 这就是 EXTERNAL_SEARCH_ID 和 EXTRA_SEARCH_MAPPINGS 选项发挥作用的地方。
为了能够识别不同的项目,需要使用 EXTERNAL_SEARCH_ID 为每个项目设置唯一的 ID。
要将搜索结果链接到正确的项目,你需要使用 EXTRA_SEARCH_MAPPINGS 标签定义每个项目的映射。 通过此选项,你可以定义从其他项目的 ID 到这些项目的文档的(相对)位置的映射。
因此,对于项目 A 和 B,配置文件的相关部分可能如下所示
project_A/Doxyfile ------------------ EXTERNAL_SEARCH_ID = A EXTRA_SEARCH_MAPPINGS = B=../../project_B/html
对于项目 A,对于项目 B
project_B/Doxyfile ------------------ EXTERNAL_SEARCH_ID = B EXTRA_SEARCH_MAPPINGS = A=../../project_A/html
通过这些设置,项目 A 和 B 可以共享同一个搜索数据库,并且搜索结果将链接到正确的文档集。
当你修改源代码时,你应该重新运行 doxygen
以再次获得最新的文档。 当使用外部搜索时,你还需要通过重新运行 doxyindexer
来更新搜索索引。 你可以将对 doxygen
和 doxyindexer
的调用包装在一个脚本中,以简化此过程。
前面的部分假设你使用工具 doxyindexer
和 doxysearch.cgi
来执行索引和搜索,但是你也可以根据需要编写自己的索引和搜索工具。
为此,以下 3 个接口很重要
接下来的小节将更详细地描述这些接口。
Doxygen 生成的搜索数据遵循 Solr XML 索引消息格式。
索引器的输入是一个 XML 文件,它由一个包含多个 <doc>
标签的 <add>
标签组成,而 <doc>
标签又包含多个 <field>
标签。
下面是一个 doc 节点的示例,其中包含一个方法的搜索数据和元数据
<add> ... <doc> <field name="type">function</field> <field name="name">QXmlReader::setDTDHandler</field> <field name="args">(QXmlDTDHandler *handler)=0</field> <field name="tag">qtools.tag</field> <field name="url">de/df6/class_q_xml_reader.html#a0b24b1fe26a4c32a8032d68ee14d5dba</field> <field name="keywords">setDTDHandler QXmlReader::setDTDHandler QXmlReader</field> <field name="text">Sets the DTD handler to handler DTDHandler()</field> </doc> ... </add>
每个字段都有一个名称。 支持以下字段名称
当从 Doxygen 生成的 HTML 页面调用搜索引擎时,会通过 查询字符串传递多个参数。
传递以下字段
应该从完整的搜索结果列表中返回范围 [n*p - n*(p+1)-1]
。
这是一个查询如何的示例。
http://yoursite.com/path/to/cgi/doxysearch.cgi?q=list&n=20&p=1&cb=dummy
它表示对单词“list”的查询 (q=list
),请求 20 个搜索结果 (n=20
),从结果编号 20 开始 (p=1
),并使用回调“dummy” (cb=dummy
)
当调用上一小节中所示的搜索引擎时,它应该回复结果。 回复的格式是 带填充的 JSON,它基本上是一个包装在函数调用中的 JavaScript 结构。 函数的名称应该是回调的名称(如查询中的 cb 字段所传递)。
对于上一小节中所示的示例查询,回复的主要结构应如下所示
dummy({ "hits":179, "first":20, "count":20, "page":1, "pages":9, "query": "list", "items":[ ... ]})
这些字段的含义如下
这里展示了items数组中元素的示例格式。
{"type": "function", "name": "QDir::entryInfoList(const QString &nameFilter, int filterSpec=DefaultFilter, int sortSpec=DefaultSort) const", "tag": "qtools.tag", "url": "d5/d8d/class_q_dir.html#a9439ea6b331957f38dbad981c4d050ef", "fragments":[ "Returns a <span class=\"hl\">list</span> of QFileInfo objects for all files and directories...", "... pointer to a QFileInfoList The <span class=\"hl\">list</span> is owned by the QDir object...", "... to keep the entries of the <span class=\"hl\">list</span> after a subsequent call to this..." ] },
该项的字段具有以下含义:
<span class="hl">
和</span>
标签中,以便在输出中突出显示。