Ankiにspreadsheetから英単語帳データを取り込む。(OCR,GAS使用)

こんにちは、今回はAnkiに効率的にSpreadsheetからデータを取り込む際、データを効率的に入力する方法について紹介しようと思います。 ~~自己流なので、もっと効率的な方法あったら教えてください~~ 
今回使用させていただいた単語帳は[distinction1,2](https://www.atsueigo.shop/items/12914669)です。選んだ理由としては、語彙がアクティブボキャブラリーよりなので、Ankiに取り込んで瞬間英作をしていくと良さげだったのと、1,2巻合わせて800語なので初めてAnkiにデータを取り込む身としてはリスクが軽そうだったからです。

英検の単語帳とかTOEFLの単語帳はパッシブボキャブラリーも多いので、
紙媒体で１周して既知の単語を弾く→未知の単語のみAnkiのUI上で追加処理の流れでも良いのかなと思います。そもそも紙媒体で完結させてもよさそうですが。

未知の単語が何割ほどあるか、単語帳がOCR(後述)しやすいかどうか、など__Ankiに単語を取り込むコストとメリットを天秤にかけて__効率的にやっていきましょう。

著作権を考慮し、単語はぼかしを入れております。

## 1.単語の番号を割り振る。

<img width="100" alt="スクリーンショット 2020-03-16 21.37.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435662/b25d5b7e-641a-5d0d-5b42-edd6bc28a874.png">

列にd1-1,d1-2,d1-3とか入れてドラッグで引き伸ばします。セルの最後の文字(数字？)がインクリメントされてたらspreadsheet君は「あ！インクリメントするのね」と判断してくれます。

## 2.単語をぶち込む。
これなんですが、新規の単語帳を取り込むときは多分[OCR](https://ja.wikipedia.org/wiki/%E5%85%89%E5%AD%A6%E6%96%87%E5%AD%97%E8%AA%8D%E8%AD%98)を使ったほうが早いです。
僕は[CamScanner](https://apps.apple.com/jp/app/camscanner-%E6%96%87%E6%9B%B8%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3-%E3%83%95%E3%82%A1%E3%83%83%E3%82%AF%E3%82%B9/id388627783)を使いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435662/32bb2d6b-76b5-0298-ff91-0dba7ed69fb8.png)
こんな感じのUI。画像にちょっと見えるように、OCRで一気に単語データが取り込めそうなページを見つけたので
単語とその英訳は簡単に全文を取得することができました。普通の単語帳は単語のインデックスは末尾についていることが多いですが、訳が一覧になってることは少ないのでどうするか考えものですね。。
ただ、OCRも精度100%では無いので、spreadsheetにパースする際に目grepして頑張ります。
コツとしては
- iとlのミスが多い 
- □などの記号はOCRの画角から外すように。OCRの画角には文書しか入れない。
くらいです。
取り込む際、GASで処理をしたら良かったなと思うのですが、この時はGASの発想がなく、結局マンパワーでゴリ押しました…(ドラマの１話、２話程度を見終わるくらいには時間を使ってしまった。)
完成はこのような形。
<img width="510" alt="スクリーンショット_2020-03-16_21_44_34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435662/1cb30c5c-0936-a1ec-d364-6c95741d9615.png">
B列に単語と熟語、C列にその英訳を入れました。

## 3.補足事項を取り込む
Distinctionはそれぞれの単語、熟語に対して例文や語源などの補足事項が大量に含まれていたので、一見わかりづらいものについては簡単な例文(He's ~~とかのレベル。 どういう文脈でどんな文構成で使われるのか分かるように。)をマンパワーで追加しました。こればっかりはしょうがないと思いますし、この過程で単語帳を一周できるので別に良いと思います。ちなみに800語で7~10時間くらいかかりました。
他の単語帳についても良さげな例文があれば載っけていくと良いと思います。

## 4.音声情報を取り込む
音声を入れます。

大体の単語帳は音声データがmp3形式であるので、それを
Windowsなら　`%APPDATA%\Anki2`
Macなら `/Users/{ユーザー名}/Library/Application Support/Anki2/ユーザー１/collection.media`
に入れたら良いです。
__ここで注意__なんですけど、音声の名前はインクリメント部分以外統一されているものにしてください。(例:001A.mp3 00001_wasshoi.mp3など)
自分は00001{音声の種類}_d1.mp3, 00001{音声の種類}_d2.mp3を採用しました。

distinctionの音声データは
001A Sunday.mp3
001B.mp3
001C.mp3
001D.mp3
のような形だったので、自分は全て
00001A_d1.mp3
00001B_d1.mp3
00001C_d1.mp3
00001D_d1.mp3
みたいな感じに直しました。コマンドラインでgrep A | mv ....みたいなコマンドを叩いても良いんですがMacでは[一括でファイル名を変更できる](https://pc-karuma.net/mac-rename-files/)ようなのでそうしました。
変換前のファイル名でもできんこっちゃ無いですけど、単語データをOCRで取り込んで100%綴りやスペースがあっている確証がない以上あまりお勧めしません。

次にスプレッドシートの操作です。
Ankiの音声の紐付けは`[sound:hogehoge.mp3]`をカードに記述する事で行います。なので、__文字列の途中の数字をインクリメントさせる__必要があります。

と言う事で、ここで初めてGASを叩きます。__単語に割り振られている番号と、スプレッドシートの列の番号は一致させるようにしてください。__具体例を言うと、00001A_d1.mp3で言われている単語は1列目に配置するように。違う場合は下のコードを参考に修正してください。

```JavaScript
const ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  //console.log(ss.getName()); //名前確認
  
  for(let i = 1; i <= 400; i++) {
    var num = ( '00000' + i ).slice( -5 ); //0埋め
    sheet.getRange(i, 5).setValue("[sound:"+ num + "A_d1.mp3]"); //(i,5)はi行５列め
  }
```
詳しい挙動はメソッドのドキュメントか、Googleで検索しましょう。

これをRunすると、サクッと音声データのタグが入りましたね。
<img width="1142" alt="スクリーンショット 2020-03-16 23.15.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435662/7efb5321-8186-40f7-a97c-4b2100222003.png">

インデックスや数値をいじくって音声データを全て入れたら終わりです。
あとは他のサイトでも沢山紹介されているように、tsvなりcsvにしてAnkiに取り込みましょう。

参考：
https://rfs.jp/sb/javascript/js-lab/zeropadding.html
https://uxmilk.jp/25841
https://tonari-it.com/gas-setvalue/