自動ローカライズスクリプトが完成！（Xcode, Macのみ）

こんにちは。[フエルマネー](https://apps.apple.com/jp/app/id6446435231)開発者です。

長らくハマっていたフエルマネーのアップデートが、先日やっと完成しました。

フエルマネーは今のところ日本語と英語のみ対応ですが、先日12時間くらいで作った新アプリは、ついでに中国語やスペイン語も入れてみました。（ちっちゃいアプリだったので）

しかし、この翻訳作業は骨が折れます。

今回は、英語のStringファイルを作ったら、各国のstringsファイルを自動生成してくれる神スクリプトを作りましたので紹介します。

使用する言語はGoogle Apps ScriptとShell Scriptです。
超簡単なコードをコピペするだけで完成しますのでぜひ試してみてください。

# Google Apps ScriptでGoogle翻訳
何はともあれ、翻訳をしなくては始まりません。

これまでは、ブラウザを開いてGoogle翻訳またはDeepLにアクセスし、一語ずつ翻訳してはコピペを繰り返していました。

まずこれが面倒です。

ということで翻訳結果を返してくれるAPIを作りました。
今の時代、こんな簡単にAPIが作れます。（以下の手順）

1. [Google Apps Script](https://script.google.com/home)にアクセス
2. プロジェクト名とファイル名を適当に変更
3. 以下のスクリプトを記述
```
function doGet(e) {
    var text = e.parameter.text;
    var lang = e.parameter.lang;
    var translated = LanguageApp.translate(text, "en", lang);
    var body;
    if (translated) {
      body = {
        code: 200,
        text: translated
      };
    } else {
      body = {
        code: 400,
        text: "Bad Request"
      };
    }
    var response = ContentService.createTextOutput();
    response.setMimeType(ContentService.MimeType.JSON);
    response.setContent(JSON.stringify(body));
    return response;
}
```
4.デプロイ→新しいデプロイ→(アクセスできるユーザー:全員)→デプロイ

生成されたURL(https: //script.google.com/macros/s/{長い文字列}/exec)をコピーしておきます。

これで、このURLに以下のクエリを含めてアクセスすれば、翻訳されたtextを含むJSONが返ってきます。
- text={翻訳するテキスト}
- lang={翻訳先言語の略記}

# Shell Scriptでstringsファイルを生成
さて、翻訳する基盤は完成したのでこれを実際にSwift(SwiftUI)で使用するstringsファイルに適合させていきます。

僕はMacを使っているので、Shell Scriptを採用しました。（手っ取り早いと思ったので）

テキストエディタでもなんでも良いので、適当にshファイルを作ります。（例えば「Localize.sh」）

以下のスクリプトを記述します。
```shell:Localize.sh
#!/bin/bash

function LOCALIZE()
{
res=""
while read line
do
  if [[ ${line} =~ ^(.*)=\ \"(.*)\"\;$ ]]; then
    corrected=$(echo ${BASH_REMATCH[2]} | sed 's/%@/A/g')
    encoded=$(echo ${corrected} | nkf -WwMQ | sed -e 's/=$//g' | tr = % | tr -d '\n')
    url="https://script.google.com/macros/s/{長い文字列}/exec?text=${encoded}&lang=$1"
    response=$(curl -L ${url})
    echo ${response}
    trans=$(echo ${response} | jq ".text" -r)
    new="${BASH_REMATCH[1]}= \"${trans}\";"
    res="${res}\n${new}"
  else
    echo ${line}
    res="${res}\n${line}"
  fi

done < ./Localizable.strings

mkdir Localized/$1.lproj
echo "$res" > Localized/$1.lproj/Localizable.strings
}

mkdir Localized
LOCALIZE es
LOCALIZE ja
LOCALIZE ko
LOCALIZE zh-Hans
mkdir Localized/en.lproj
mv Localizable.strings Localized/en.lproj/Localizable.strings
```

簡単に説明します。

前提として、実行時のディレクトリに、英語で記述された「Localizable.strings」が1つあることが前提です。これを元に、各言語のstringsファイルを生成します。

```shell
function LOCALIZE()
```
↑
まずは、LOCALIZEという関数を定義しています。
この関数は、引数に言語を指定するとその言語のstringsファイルを自動生成するという一連の流れを行います。

```shell
if [[ ${line} =~ ^(.*)=\ \"(.*)\"\;$ ]]; then
```
↑
stringsファイルの標準的な書き方に合わせて、内容を正規表現で抽出します。
以下の書き方を前提としています。
```:Localized.strings
"Hello" = "Hello, World!";
```
=まで(左辺)は、空白がいくらあっても問題ありません。
ただし、右辺は正規表現的に制約があり、=の次は「空白1文字」、「"内容"」、「;」、「改行」と続く必要があります。

上記のフォーマットに則っていない行、すなわちコメント行や空白行に関しては、何も変換しません。

```shell
url="https://script.google.com/macros/s/{長い文字列}/exec?text=${encoded}&lang=$1"
```
↑
ここに、先ほどGoogle Apps Scriptで生成したURLを適用してください。
実際にアクセスして翻訳データを取得していきます。

```shell
done < ./Localizable.strings
```
↑
前述した通り、実行時のディレクトリ内に英語版の「Localizable.strings」を用意しておいてください。

```shell
mkdir Localized
LOCALIZE es
LOCALIZE ja
LOCALIZE ko
LOCALIZE zh-Hans
mkdir Localized/en.lproj
mv Localizable.strings Localized/en.lproj/Localizable.strings
```
↑
LOCALIZE関数の外側です。
最初にLocalizedというディレクトリを生成して、その中に翻訳ファイルたちを入れていきます。
今回はスペイン語、日本語、韓国語、中国語の順に実行します。
最後に、元ファイルである英語版も適切なディレクトリに移動します。

# 最後にもう一個
準備があと少しだけありました。
前項のshを実行するには、「nkf」と「jq」のインストールが必要です。
nkf: URLエンコードのため
jq: JSON解読のため

僕は以下のようにインストールしました。
```
$ brew install jq
$ brew install nkf
```

# 実践！
準備は整いました。それでは実際に実行してみましょう。
今回はわかりやすいようデスクトップで行います。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518353/6b4e79c9-4970-39a6-f63b-2eca9a0317db.png)
↑
このファイルをローカライズしていきます。
```
$ cd Desktop/
$ sh Localize.sh 
```
以下のディレクトリが生成され、1行ずつ翻訳されていき、しばらくすると元ファイルが消えます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518353/b5bc07df-ed6e-c4e4-a815-e87c26c9a63c.png)
中身を見てみると、各言語のファイルが生成されていることが確認できますね。
このファイル構造は、Xcodeでstringsを生成した時と同じようになっているので、このままプロジェクトにぶっ込むだけでローカライズが完了します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518353/a4224399-bae3-6973-1343-1d1798974693.png)
ファイルの内容も、しっかりと翻訳されていることがわかります。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518353/ccc0eaa8-9973-bba2-f8cc-f4939c271edf.png)
一つ言い忘れていました。翻訳の精度を上げるために、stringsファイルの「%@」を「A」に置き換えて翻訳しています。これを「%@」に戻す処理はしていないので、自分で文脈を考えて「%@」に戻してください。

# まとめ
以上です。見て分かる通り、自分のためだけに即興で作ったものですので、もっとこだわりたい人は勝手にカスタマイズしていただければと思います。
これらのコードを使用して起こった問題については、僕は責任を負いませんので、デスクトップなど安全な場所で動作確認をしてから進めてくださいね。

以上、ローカライズを圧倒的に楽にするスクリプトでした！