Doxygen で多言語対応

Posted Mon Jul 14 2014

SDK などを作成していると,多言語に対応したドキュメントを作成したいことがあります.今回仕事で Doxygen を使って日,英,韓のドキュメントを作成しなくてはいけないことがあって,そのときの事をまとめておきます.

コメントの多言語切替

Doxygen の Expert タブの ENABLED_SECTIONS で tag を定義し,生成対象に合わせて切り替えます.今回は japanse,english タグを定義し判別します.コメントを書くときに言語ごとにコメントを tag 内に記入します.言語間で共通の表記は tag の外に出します.

Doxygen でドキュメント生成時に生成対象の tag を有効にすることで,ドキュメント中で定義した tag 内のコメントのみが有効になり,所望の言語のドキュメントが得られるというわけです.

/**
 * @file doxygen_multilingual.h
 */

/** @if japanese 処理が成功した時の戻り値 @endif */
/** @if english Return value on success @endif */
#define SUCCESS 0
/** @if japanese 処理が失敗した時の戻り値 @endif */
/** @if english Return value on failure @endif */
#define FAILURE -1

/**
 * @if japanese
 * @brief エラーコード
 * @endif
 * @if english
 * @brief Error code
 * @endif
 *
 * @see GetError
 * @since 1.0.0
 */
typedef enum _Error {
  /** @if japanese エラー無し @endif */
  /** @if english No error @endif */
  NO_ERROR,
  /** @if japanese ファイルがありません @endif */ 
  /** @if english File not be found @endif */
  CANNOT_FIND_THE_FILE
} Error;

/**
 * @if japanese
 * @brief 最新のエラーコードを取得します
 * @return 最新のエラーコードを返します
 * @endif
 * @if english
 * @brief Get latest error code
 * @return Returns latest error code
 * @endif
 * @since 1.0.0
 */
int Error GetError();

最終的にヘッダーをユーザ配布する場合には英語のコメントのみを残したいなどの要求があるかと思います.私もそのような要求があり,最終的には python で不要コメントを除去するスクリプトを書きました.下記のスクリプトでは english tag 内のコメントのみを残し,japanse,korean tag 内のコメントを削除します.

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys

if __name__ == '__main__':

    of = open(sys.argv[2], "wt")

    write_flag = True
    with open(sys.argv[1]) as source:
        for line in source:
            if line.find("@if japanese") > 0:
                if not line.find("@endif") > 0:
                    write_flag = False
                continue
            elif line.find("@if korean") > 0:
                if not line.find("@endif") > 0:
                    write_flag = False
                continue
            elif write_flag == False and line.find("@endif") > 0:
                write_flag = True
                continue
            elif line.find("@if english") > 0:
                #if not line.find("@endif") > 0:
                continue
            elif line.find("@endif") > 0:
                continue

            if write_flag:
                of.write(line)

    of.close()