使用gettext提取代碼中的字符串配置

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工具包提取代碼中的字符串配置,基本原理和步驟如下:

  1. 使用xgettext,通過指定參數”-kGetStr”將代碼中的GetStr(“字符串ID”)中的”字符串ID”及前置註釋行提取到client.po文件;
  2. 使用iconv將client.po(UTF8編碼)轉換爲gb18030.po(GB18030編碼),因爲sed在中文命令提示符窗口環境處理UTF8編碼的文件會出錯,所以先將文件轉換爲GB18030編碼;
  3. 使用sed將gb18030.po中的字符串ID提取到msgid.po,用於後期字符串ID配置項的檢查;
  4. 使用sed將gb18030.po中的代碼註釋提取到msgstr.po和msgstr.txt。其中msgstr.po保留了gb18030.po原始行的格式,方便文件比較;msgstr.txt是去掉”#. “的,如果代碼註釋編寫符合規範,稍作修改即可作爲正式資源發佈。

優點

  1. msgid.po文件直接從代碼導出,與程序版本同步,避免了人工處理字符串ID可能出現錯漏、重複和多餘的情況;
  2. 如果代碼中字符串ID的前置註釋符合一定規則,就可以直接從代碼導出msgstr.txt,後期製作只要將它同msgid.po進行比對和翻譯。

參考

gettext
iconv
sed
SED單行腳本快速參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章