gettext軟件包提供給程序員、翻譯人員,甚至用戶,一套完整的工具和文檔來幫助生成多語言消息。
由於gettext庫採用GPL,無法在商用軟件中使用,不過仍可以使用gettext工具包來進行代碼中的字符串處理。
代碼中的字符串ID和前置註釋
gettext可以處理類似以下格式的字符串ID相關代碼:
// STR_ACCOUNT_LOGIN=尊敬的%s,您登錄遊戲的時間:%s 登錄城市:%s。
_snprintf(szInfo, sizeof(szInfo) - 1, g_objStrMgr.GetStr("STR_ACCOUNT_LOGIN"), ...
批處理文件示例
使用以下批處理文件提取示例代碼中的字符串ID及前置註釋:
::Requires GnuWin32 touch, xgettext, msginit, iconv, sed
CD /D "%0\.." 1>NUL 2>&1
DEL client.po gb18030.po msgid.po msgstr.po msgstr.txt 1>NUL 2>&1
touch client.po
FOR %%X IN (3DRole\Network\*.cpp, 3DRole\*.cpp, BaseCode\*.cpp, MyShell\*.cpp) DO (
xgettext --from-code GB18030 -d client -j -c -kGetStr -s %%X
)
REM msginit --locale=zh_CN --no-wrap -i client.po
iconv -c -f utf-8 -t gb18030 client.po > gb18030.po
sed -l 0 -n -e "/^msgid \"\(.*\)\"/ s//\1/p" gb18030.po | uniq > msgid.po
sed -l 0 -n -e "/^#\. / { /^#\. ~/ d; p }" gb18030.po | uniq > msgstr.po
sed -l 0 -n -e "/^#\. / s///p" msgstr.po > msgstr.txt
在實際項目使用時,需要替換”FOR %%X IN (…)”括號內的源代碼文件名匹配規則和xgettext命令的-k參數。
client.po和gb18030.po
使用xgettext提取並在client.po和gb18030.po中保存的信息:
#. STR_ACCOUNT_LOGIN=尊敬的%s,您登錄遊戲的時間:%s 登錄城市:%s。
#: MyShell\DlgAccountLoginAlert.cpp:175
msgid "STR_ACCOUNT_LOGIN"
msgstr ""
當多個文件引用了同一個字符串ID,或者同一文件多處引用了同一個字符串ID,以”#: “開頭的行(或多行)包含了所有引用文件及行號。例如:
#. STR_ACCOUNT_LOGIN_DIFF=與本次登錄不同。
#: MyShell\DlgAccountLoginAlert.cpp:171 MyShell\DlgAccountLoginAlert.cpp:176
msgid "STR_ACCOUNT_LOGIN_DIFF"
msgstr ""
msgid.po
包含gb18030.po中msgid開頭的行中引號內的字符串ID:
STR_ACCOUNT_LOGIN
msgstr.po
包含gb18030.po中的前置註釋行:
#. STR_ACCOUNT_LOGIN=尊敬的%s,您登錄遊戲的時間:%s 登錄城市:%s。
msgstr.txt
刪除了msgstr.po中的前置”#. “:
STR_ACCOUNT_LOGIN=尊敬的%s,您登錄遊戲的時間:%s 登錄城市:%s。
批處理文件說明
使用gettext工具包提取代碼中的字符串配置,基本原理和步驟如下:
- 使用xgettext,通過指定參數”-kGetStr”將代碼中的GetStr(“字符串ID”)中的”字符串ID”及前置註釋行提取到client.po文件;
- 使用iconv將client.po(UTF8編碼)轉換爲gb18030.po(GB18030編碼),因爲sed在中文命令提示符窗口環境處理UTF8編碼的文件會出錯,所以先將文件轉換爲GB18030編碼;
- 使用sed將gb18030.po中的字符串ID提取到msgid.po,用於後期字符串ID配置項的檢查;
- 使用sed將gb18030.po中的代碼註釋提取到msgstr.po和msgstr.txt。其中msgstr.po保留了gb18030.po原始行的格式,方便文件比較;msgstr.txt是去掉”#. “的,如果代碼註釋編寫符合規範,稍作修改即可作爲正式資源發佈。
優點
- msgid.po文件直接從代碼導出,與程序版本同步,避免了人工處理字符串ID可能出現錯漏、重複和多餘的情況;
- 如果代碼中字符串ID的前置註釋符合一定規則,就可以直接從代碼導出msgstr.txt,後期製作只要將它同msgid.po進行比對和翻譯。