Doxygen 内置了对多种语言的支持。这意味着,由 doxygen 生成的文本片段可以用英语(默认)以外的语言生成。输出语言通过配置文件(默认名称为 Doxyfile)中的配置选项 OUTPUT_LANGUAGE 选择。要在注释块内切换语言,可以使用 \~ 命令。
目前(1.13.0 版本),支持 42 种语言(按字母顺序排序):南非荷兰语、阿拉伯语、亚美尼亚语、巴西葡萄牙语、保加利亚语、加泰罗尼亚语、中文、中文繁体、克罗地亚语、捷克语、丹麦语、荷兰语、英语、世界语、芬兰语、法语、德语、希腊语、印地语、匈牙利语、印尼语、意大利语、日语 (+En)、韩语 (+En)、拉脱维亚语、立陶宛语、马其顿语、挪威语、波斯语、波兰语、葡萄牙语、罗马尼亚语、俄语、塞尔维亚语、塞尔维亚语西里尔文、斯洛伐克语、斯洛文尼亚语、西班牙语、瑞典语、土耳其语、乌克兰语和越南语。
下表列出了有关支持语言的信息。它按语言的字母顺序排序。 状态列是从源代码生成的,大约显示了翻译器上次更新的版本。
|
列表中的大多数人都表示他们也在忙于其他事情,因此如果您想帮助加快速度,请让他们(或我)知道。
如果您想添加对尚未列出的语言的支持,请阅读下一节。
这个简短的 HOWTO 解释了如何向 doxygen 添加对新语言的支持
只需按照以下步骤操作
YourLanguage
)添加支持。如果还没有其他人正在开发对该语言的支持,您将被指定为该语言的维护者。doxygen/src/config.xml
文件中,在 OUTPUT_LANGUAGE 部分的适当位置,添加以下行<value name='YourLanguage'/>
doxygen/src/translator_en.h
的副本,并将其命名为 doxygen/src/translator_<your_2_letter_country_code>.h
。我将在本文档的其余部分使用 xx
(大写版本为 XX
)。编辑 doxygen/src/language.cpp
:添加以下代码
#include<translator_xx.h>
现在,在 setTranslator()
中添加
case OUTPUT_LANGUAGE_t::YourLanguage: theTranslator = new TranslatorYourLanguage; break;
doxygen/src/translator_xx.h
TRANSLATOR_EN_H
重命名为 TRANSLATOR_XX_H
两次(即在文件开头的 #ifndef
和 #define
预处理器命令中)。TranslatorEnglish
重命名为 TranslatorYourLanguage
idLanguage()
中,将 "english" 更改为您的语言名称(仅使用小写字符)。根据语言的不同,您可能还希望更改成员函数 latexLanguageSupportCommand()
和其他函数(当您开始工作时,您会识别出它们)。tr
开头的成员函数返回的所有字符串。尽量匹配标点符号和大小写!要输入特殊字符(带重音符号),您可以ä
; 表示带有 umlaut
的 a
(即 ä
)。有关代码,请参阅 HTML 规范。doxygen/doc/maintainers.txt
并将自己添加到维护者列表中,如下所示make docs
)来构建文档。OUTPUT_LANGUAGE = your_language_name
来生成您的语言的输出。translator_xx.h
发送给我,以便我可以将其添加到 doxygen。还要发送您的姓名和电子邮件地址,以便将其包含在 maintainers.txt
列表中。Doxygen 的新版本可能会使用新的翻译句子。在这种情况下,Translator
类需要实现新的方法 - 其接口会发生变化。当然,英语句子需要翻译成其他语言。至少,语言相关的翻译器类必须实现新方法;否则,doxygen 甚至无法编译。等待所有语言维护者翻译完新句子并发送结果是不太现实的。以下文本描述了翻译器适配器的用法来解决该问题。
翻译器适配器的作用。 每当新版本中 Translator
类接口发生更改时,新的类 TranslatorAdapter_x_y_z
会被添加到 translator_adapter.h
文件中(这里的 x、y 和 z 是数字,对应于当前 Doxygen 的官方版本)。所有之前从 Translator
类派生的翻译器现在都从这个适配器类派生。
TranslatorAdapter_x_y_z
类实现了新的、必需的方法。如果新方法替换了一些类似但已过时的方法(例如,如果参数数量发生变化和/或较旧方法的功能被更改或丰富),则 TranslatorAdapter_x_y_z
类可以使用已过时的方法来获得结果,该结果尽可能接近目标语言中的较旧结果。如果不可能,则使用英语翻译器(根据定义,它始终是最新的)获得结果(默认翻译)。
例如, 当引入带有参数(用于确定首字母的大小写和单复数形式)的新 trFile()
方法来替换不带参数的旧方法 trFiles()
时,以下代码出现在其中一个翻译器适配器类中
/*! This is the default implementation of the obsolete method * used in the documentation of a group before the list of * links to documented files. This is possibly localized. */ virtual QCString trFiles() { return "Files"; } /*! This is the localized implementation of newer equivalent * using the obsolete method trFiles(). */ virtual QCString trFile(bool first_capital, bool singular) { if (first_capital && !singular) return trFiles(); // possibly localized, obsolete method else return english.trFile(first_capital, singular); }
trFiles()
不存在于 TranslatorEnglish
类中,因为它已被删除为过时。然而,它一直被使用,并且其调用已被
trFile(true, false)
在 Doxygen 源文件中替换。可能许多语言翻译器实现了过时的方法,因此在这些情况下使用相同的语言相关结果是完全有意义的。TranslatorEnglish
没有实现旧方法。它从抽象类 Translator
派生。另一方面,另一种语言的旧翻译器没有实现新的 trFile()
方法。因此,它从另一个基类派生 - TranslatorAdapter_x_y_z
。TranslatorAdapter_x_y_z
类必须实现新的、必需的 trFile()
方法。但是,如果未实现 trFiles()
方法,则不会编译翻译器适配器。这就是在翻译器适配器类中实现旧方法的原因(使用从 TranslatorEnglish 中删除的相同代码)。
最简单的方法是将参数传递给英语翻译器并返回其结果。相反,适配器在一种特殊情况下使用旧的 trFiles()
– 当调用新的 trFile(true, false)
时。这是引入新方法时最常用的情况 – 请参见上文。虽然这看起来太复杂,但该技术允许核心源的开发人员更改翻译器接口,而用户甚至可能不会注意到更改。当然,当新的 trFile()
与不同的参数一起使用时,将返回英语结果,并且非英语用户会注意到。在这里,语言翻译器的维护者应该至少实现一个特定的方法。
语言翻译器的基类说明了什么? 如果语言翻译器类从任何适配器类继承,则需要维护。在这种情况下,该语言翻译器被认为不是最新的。另一方面,如果语言翻译器直接从抽象类 Translator
派生,则该语言翻译器是最新的。
翻译器适配器类是链接的,因此较旧的翻译器适配器类使用一步更新的翻译器适配器作为基类。较新的适配器比旧的适配器执行更少的适配工作。最旧的适配器类(间接)从所有适配器类派生。选择适配器类的名称时,其后缀是从不需要适配器的 Doxygen 的上一个官方版本派生的。这样,可以大致说出语言翻译器类最后一次更新的时间 - 请参阅下面的详细信息。
最新的翻译器适配器从抽象的 TranslatorAdapterBase
类派生,该类直接从抽象的 Translator
类派生。它仅添加私有的英语翻译器成员,以便在适配器类中轻松实现默认翻译,并且它还强制执行一种用于通知用户语言翻译不是最新的方法(因此生成的某些文件中的某些句子可能会以英语显示)。
一旦没有任何语言翻译器使用最旧的适配器类,就可以将其从 Doxygen 项目中删除。维护人员应尝试达到具有最少数量的翻译器适配器类的状态。
为了简化对受支持语言的语言翻译器类的维护,开发了 translator.py
Python 脚本(位于 doxygen/doc
目录中)。它从每个语言的源文件中提取有关过时方法和新方法的重要信息。该信息存储在翻译器报告 ASCII 文件 (translator_report.txt
) 中。
您可以将此文件作为 translator_report.txt
找到。
查看语言翻译器的基类,该脚本还会猜测翻译器的状态 - 请参阅上面语言表的最后一列。生成 Doxygen 文档时,会自动调用 translator.py
。您也可以在感觉它可以帮助您时手动运行该脚本。当然,您并非必须使用该脚本的结果。您可以通过查看适配器类及其基类来找到相同的信息。
我应该如何更新我的语言翻译器? 首先,您应该是语言维护者,或者您应该让他/她知道更改。以下文本是为语言维护者作为主要受众而编写的。
更新您的语言时,可以采用几种方法。如果您不是特别忙,则应始终选择最激进的方法。当更新花费的时间比您预期的要多得多时,您可以随时决定使用一些合适的翻译器适配器来稍后完成更改,并仍然使您的翻译器工作。
更新语言翻译器的最激进的方法 是使您的翻译器类直接从抽象类 Translator
派生,并为需要实现的方法提供翻译 - 如果您忘记实现其中一些方法,编译器会告诉您。如果您有疑问,请查看 TranslatorEnglish
类以识别已实现方法的目的。查看以前使用的适配器类有时可能会有所帮助,但也可能会产生误导,因为适配器类还会实现过时的方法(请参见前面的 trFiles()
示例)。
换句话说,最新的语言翻译器根本不需要 TranslatorAdapter_x_y_z
类,您也不需要实现 Translator
类要求的任何其他方法(即 Translator
的纯虚方法 - 它们以 =0;
结尾)。
如果一切编译正常,请尝试运行 translator.py
,并查看 doxygen/doc
目录下的翻译器报告(ASCII 文件)。仅当脚本未检测到任何特殊内容时,您的翻译器才会被标记为最新。如果翻译器使用 Translator
基类,则可能仍有一些与您的源代码相关的注释。在这种情况下,翻译器被标记为几乎是最新的。也就是说,在您的语言部分中可能会列出完全未使用的过时方法。只需删除其代码(并再次运行 translator.py
)。此外,当您忘记将翻译器类的基类更改为一些较新的适配器类或直接更改为 Translator 类时,您将会收到通知。
如果您没有时间完成所有更新,您仍然应该从上面描述的最激进的方法开始。您可以随时将基类更改为实现所有尚未实现的方法的翻译器适配器类。
如果您希望逐步更新您的翻译器,请查看 TranslatorEnglish
(translator_en.h
文件)。在其中,您将找到类似 new since 1.2.4
的注释,该注释始终分隔在指定版本中实现的一些方法。请实现注释下方的一组方法,该注释使用与您的翻译器适配器类相同的版本号。(例如,如果您的翻译器类未实现 new since 1.2.4
注释下面的方法,则必须使用 TranslatorAdapter_1_2_4
。当您实现它们时,您的类应使用较新的翻译器适配器。
偶尔运行 translator.py
脚本,并提供您的 xx
标识(来自 translator_xx.h
)以创建较短(也更快生成)的翻译器报告 – 它将仅包含与您的翻译器相关的信息。一旦您达到应将基类更改为某些较新的适配器的状态,您将在翻译器报告中看到该注释。
警告:不要忘记编译 Doxygen 以发现是否可编译。translator.py
不会检查相对于编译器而言一切是否正确。因此,有时它可能会谎报必要的基类。
最过时的语言翻译器 会导致实现过于复杂的适配器。因此,Doxygen 开发人员可能会决定从 TranslatorEnglish
类派生此类翻译器,根据定义,该类始终是最新的。
这样做时,所有缺失的方法都将替换为英语翻译。这意味着未实现的方法将始终返回英语结果。此类翻译器使用单词 obsolete
标记。您应该将其读取为确实过时。无法猜测上次更新的时间。
通常,可以从过时的方法构造更好的结果。因此,如果可能,应使用翻译器适配器类。另一方面,为真正过时的翻译器实现适配器会带来过多的维护和运行时开销。