pixivとl10n/i18n
DESCRIPTION
2014年6月にpixiv社内勉強会で発表したTRANSCRIPT
![Page 1: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/1.jpg)
pixivとL10N/i18nうさみけんた@tadsan
2014-06-06 pixiv社内勉強会
![Page 2: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/2.jpg)
お前誰よ
![Page 3: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/3.jpg)
お前誰よ
• うさみけんた a.k.a Zonu.EXE(ぞ)
• 2012年に自宅警備職を廃業いたしました
• 時代の波に乗れてなくてEmacsとVimで開発…
• 仕事では地味なボトルネックを殺して回ったり
• プログラミング言語すきです
• Swingの良いとこどり感は良いですね
![Page 4: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/4.jpg)
scripter = ->(*args){ ->{ puts args.join("\n") } }title = ->(text) { "『#{text}』\n" }paragraph = ->(*args){ args.join("\n") + "\n" }chara = ->(name) { ->(text){ "#{name}「#{text}」"} }ryu = chara[:リュウ]; tak = chara[:たかし]script = scripter[title[:俺より強い奴に、会いに行く], paragraph[:ピンポーン, ryu[:こんにちは], tak[:はいどなた]], paragraph[ryu[:いまちょっといいですか], tak[:これから出かけます]], paragraph[ryu[:午後出勤ですか?], tak[:はい]], paragraph[ryu[:強そうですね], tak[:なにがですか]], paragraph[ryu[:態度が]], paragraph[:リュウは、自分より強そうな奴に、会いにいったのだった。 完]]script[]
クロージャを使ったDSL
![Page 5: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/5.jpg)
はじめに
![Page 6: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/6.jpg)
用語説明L10N: Localization (ろーからいぜーしょん) i18n : Internationalization (いんたーなしょならいぜーしょん)
L10N: Localization (ろーからいぜーしょん) (えるじゅーえぬ) !
(いんたーなしょならいぜーしょん) (あいじゅーはちえぬ)
詳しくはWikipediaでもお読みください http://en.wikipedia.org/wiki/Internationalization_and_localization http://ja.wikipedia.org/wiki/%E5%9B%BD%E9%9A%9B%E5%8C%96%E3%81%A8%E5%9C%B0%E5%9F%9F%E5%8C%96
L10N: Localization (ろーからいぜーしょん) (えるじゅーえぬ) → 地域化 !
(いんたーなしょならいぜーしょん) (あいじゅーはちえぬ) → 国際化
![Page 7: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/7.jpg)
pixivとi18n
![Page 8: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/8.jpg)
![Page 9: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/9.jpg)
![Page 10: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/10.jpg)
pixivの文言数: およそ2000*9言語
![Page 11: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/11.jpg)
日本語 英語
フランス語 韓国語
ロシア語 タイ語
簡体字中国語 繁体字中国語 スペイン語
![Page 12: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/12.jpg)
![Page 13: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/13.jpg)
文字セット 文字の方向性
文言 数値書式(小数点,桁区切りなど)
日時書式(年月日/暦) 日時情報の時差
通貨情報
Unicode BiDiは考慮しない 各文言を翻訳 サポートしない 対応 JST JPY
![Page 14: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/14.jpg)
実装方法
![Page 15: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/15.jpg)
かなり適当
![Page 16: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/16.jpg)
よくある実装
自然言語文を言語リソースに分割する !• よくある多言語化の実現方法はこれ • 実装例… ありすぎて枚挙に暇がない! • GNU gettext • rails-i18n
![Page 17: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/17.jpg)
現在のpixiv
![Page 18: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/18.jpg)
<form><legend>%!IDまたはパスワードを忘れてしまった%</legend><dl> <dt>%!忘れた内容% %!(ほげほげ)%</dt> <dd><ul><li>%!pixiv IDを忘れた%</li> <li>%!パスワードを忘れた%</li></ul></dd> <dt>%!メールアドレス%</dt> <dd><input name="mail_address" type="text" /></dd></dl><p>%!※忘れてしまったものを選択し、登録メールアドレスを入力して送信してください。%</p><p>%!メールアドレスがご不明な場合は<a href="/support.php">サポート窓口</a>までご連絡ください。%</p><button type="submit">%!送信%</button></form>
テンプレート
![Page 19: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/19.jpg)
<form><legend>%!IDまたはパスワードを忘れてしまった%</legend><dl> <dt>%!忘れた内容% %!(ほげほげ)%</dt> <dd><ul><li>%!pixiv IDを忘れた%</li> <li>%!パスワードを忘れた%</li></ul></dd> <dt>%!メールアドレス%</dt> <dd><input name="mail_address" type="text" /></dd></dl><p>%!※忘れてしまったものを選択し、登録メールアドレスを入力して送信してください。%</p><p>%!メールアドレスがご不明な場合は<a href="/support.php">サポート窓口</a>までご連絡ください。%</p><button type="submit">%!送信%</button></form>
テンプレート
![Page 20: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/20.jpg)
Smarty prefilter!
![Page 21: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/21.jpg)
return array(...'IDまたはパスワードを忘れてしまった'=>'Forgot your pixiv ID or password?''忘れた内容' => 'Which did you forget?','pixiv IDを忘れた' => 'Forgot pixiv ID','パスワードを忘れた' => 'Forgot password','メールアドレス' => 'E-mail address','※忘れてしまったものを選択し、…'=>'Select an option, enter your register…''メールアドレスがご不明な場合…' =>'For mail address issues, please conta…''送信' => 'Submit',...);
Lang/en.php
![Page 22: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/22.jpg)
%!IDまたはパスワードを忘れてしまった%%!忘れた内容%%!pixiv IDを忘れた%%!パスワードを忘れた%%!メールアドレス%%!※忘れてしまったものを選択し、…%%!メールアドレスがご不明な場合…%%!送信%%!(ほげほげ)%
置換・Forgot your pixiv ID or password?・Which did you forget?・Forgot pixiv ID・Forgot password・E-mail address ・Select an option, enter your register…・For mail address issues, please conta…・Submit・(ほげほげ) ←配列にないので同じ文字列が返る
![Page 23: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/23.jpg)
<form><legend>Forgot your pixiv ID or password?</legend><dl> <dt>Which did you forget? (ほげほげ)</dt> <dd><ul><li>Forgot pixiv ID</li> <li>Forgot password</li></ul></dd> <dt>E-mail address</dt> <dd><input name="mail_address" type="text" /></dd></dl><p>Select an option, enter your registered email address, and click “Send”.</p><p>For mail address issues, please contact use through our <a href="/support.php">support center</a>.</p><button type="submit">%!Submit%</button></form>
置換後
![Page 24: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/24.jpg)
単純置換では困るパターン
![Page 25: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/25.jpg)
![Page 26: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/26.jpg)
日時の国際化
![Page 27: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/27.jpg)
![Page 28: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/28.jpg)
長らくメンテナンスされてなかったが、最近rails-i18nの定義を流用して各言語対応した
![Page 29: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/29.jpg)
タグ翻訳 (Attack on Titan)
![Page 30: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/30.jpg)
![Page 31: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/31.jpg)
日本語以外で入力された 文字列がよしなに正規化される!
![Page 32: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/32.jpg)
実装方法
![Page 33: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/33.jpg)
return array(...'attack on titan' => '進撃の巨人', // en'avance de dikxion' => '進撃の巨人', // es'ผ่าพิภพไททัน' => '進撃の巨人', // th'进击的巨⼈人' => '進撃の巨人', // zh'進擊的巨人' => '進撃の巨人', // zw-tw'진격의 거인' => '進撃の巨人', // ko...);
CorrectTag.php
超原始的
![Page 34: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/34.jpg)
特徴実装は超単純 利用者の入力を正規化して配列からとるだけ 実行時のパフォーマンスも良好
![Page 35: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/35.jpg)
!
!
そもそもタグに利用される語彙と翻訳の概念のミスマッチを人間が吸収する必要があり、メンテナンスコストが過剰に高い。
欠点連想配列のキーである性質上、完全一致する必要があり、表記揺れに極端に弱い。
![Page 36: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/36.jpg)
翻訳者が歴史的経緯を知らない場合
![Page 37: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/37.jpg)
間違ってるわけではないが正しくもない
![Page 38: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/38.jpg)
例: 偽春菜問題
![Page 39: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/39.jpg)
(「偽春菜」はソフトウェアの正式名称ではないが、中国語圏では「伺か」などを「偽春菜」と呼称する)
!
↑この説明も正確じゃない
![Page 40: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/40.jpg)
// 翻訳者によって方針が一貫しない'aoharu railway' => '青春鉄道', // en'aoharu tetsudo' => '青春鉄道', // fr!// 日本語の長音表記'heisuke toudou' => '藤堂平助', // en'heisuke tōdō' => '藤堂平助', // es
![Page 41: pixivとl10n/i18n](https://reader033.vdocuments.site/reader033/viewer/2022052909/55999e341a28ab9e658b45df/html5/thumbnails/41.jpg)
まとめ: pixivはインテリジェントな機構で国際化されてるわけではない!!1