Doxygenはリリース1.8.3から、外部インデックスツールと検索エンジンを使用してHTMLを検索する機能を提供します。これにはいくつかの利点があります。
誰もが独自のインデクサーと検索エンジンを書き始めるのを避けるため、Doxygenは各アクションの例ツールを提供します:データのインデックス作成にはdoxyindexer、インデックスの検索にはdoxysearch.cgi。
データフローは以下の図に示されています。
最初のステップは、検索エンジンをWebサーバー経由で利用可能にすることです。doxysearch.cgiを使用する場合、これはCGIバイナリをWebサーバーから利用可能にする(すなわち、http:で始まるURLを介してブラウザから実行できるようにする)ことを意味します。
Webサーバーのセットアップ方法は本ドキュメントの範囲外ですが、例えばApacheがインストールされている場合、Doxygenのbinディレクトリにあるdoxysearch.cgiファイルを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が配置されているのと同じディレクトリにコピーし、ブラウザで以下のURLにアクセスしてブラウザテストを再実行します。
http://yoursite.com/path/to/cgi/doxysearch.cgi?test
これで以下のメッセージが表示されるはずです。
Test successful.
これでHTML出力から単語や記号を検索できるようになります。
Doxygenプロジェクトが複数あり、これらのプロジェクトが関連している場合、いずれかのプロジェクトのドキュメント内からすべてのプロジェクトの単語を検索できるようにすることが望ましい場合があります。
これを可能にするために必要なのは、すべてのプロジェクトの検索データを単一のインデックスに結合することだけです。例えば、searchdata.xmlがproject_Aとproject_Bディレクトリに生成される2つのプロジェクト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>タグを含む1つの<add>タグで構成され、それらはさらに複数の<field>タグを含みます。
以下に、1つのメソッドの検索データとメタデータを含む1つの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..." ] },
このような項目のフィールドの意味は以下の通りです。