EmacsからAnkiに単語登録したい
Ankiという単語帳アプリがあり、学習時の暗記に利用している。
Ankiを取り上げた記事は、はてなブックマークで何度もホッテントリに上がっていて使いたい気にさせられる。以下にいくつかAnkiのホッテントリを挙げる。
復習のタイミングを変えるだけで記憶の定着度は4倍になる 読書猿Classic: between / beyond readers
決して後退しない学習ーAnkiを使うとどうして一生忘れないのか? 読書猿Classic: between / beyond readers
暗記学習をサポートする学習ソフト、その名も『Anki』(無料) | ライフハッカー[日本版]
高校の授業で反復練習ソフトウェアを使ってみた結果、こうなった - GIGAZINE
(他のホッテントリ→タイトル 「Anki」 を検索 - はてなブックマーク)
スマートフォンアプリも出ているため、PCで入力しておけば、スマホでいつでもどこでも単語帳学習をすることができ大変便利である。
そこでEmacsからAnkiに単語を登録できるようなlispがあれば便利だと思い探してみたところ、登録する単語帳をEmacsから、しかもorg-modeの書式を使って入力できるという、まさに願ったり叶ったりな機能を持つanki-editorというツールを見つけた。
GitHub - louietan/anki-editor: Emacs minor mode for making Anki cards with Org
インストールは上記GitHubページの手順にならえばできるが、使用法やエラーについて日本語の情報が全く見当たらなかったので、わずかばかりだが分かったことをメモしておく。
anki-editorの使い方などのメモ
対応するEmacsのバージョン
Emacs25以降。手元の環境はEmacs26.3で動作を確認した。
バージョン0.3.0を使用する
最新のバージョン0.3.3はエラーが出てしまい、カードがAnkiに送信できない(下の方に記載)。バージョン0.3.0はカードの送信は問題なくできるので、そちらをMELPAでダウンロードしたanki-editor.elと差し替える。
単語(カード)の登録方法
以下のようなorgファイルを作成して「M-x anki-editor-push-notes」すると、「Default」のデッキにBasicタイプのカードが登録される。下の様式で複数の項目を作れば、作っただけ一度に登録することができる。
「:ANKI_NOTE_TYPE:」を「cloze」にすれば穴埋めタイプのカードとして登録される。
「:ANKI_DECK:」には登録する先のデッキを指定する。
「Front」「Back」はノートタイプのフィールド名やフィールドの数と一致させる。例えばフィールド名が「表面」と「裏面」になっているならそう変更し、「裏の裏」というフィールドがあるなら、「裏の裏」の見出し項目(「** 裏の裏」)を追加する。そうしないと「cannot create note because it is empty」のエラーが出る。
* 適当なカード :PROPERTIES: :ANKI_DECK: Default :ANKI_NOTE_TYPE: Basic :END: ** Front ほげとは何か ** Back 意味を持たない文字列 #+BEGIN_EXPORT html <img src="hoge.jpg"> #+END_EXPORT
- 詳しく
org-modeで使える書式が使用でき、カードはhtmlに変換されてAnkiに登録される。
上記の例では画像を貼り付けているが、画像はユーザーディレクトリ(linuxでは~/.local/share/Anki2/ユーザー名/)の「collection.media」に置いておけば拾って表示してくれる。
公式サイトのexamples.orgの例にあるように、org-modeの書式を使って「#+BEGIN_EXPORT」でhtmlを記述できたり、「#+BEGIN_SRC」でプログラムのソースコードが記述できたりする。
latexはそのまま書けば[latex]〜[/latex]で囲まれてAnkiに出力される。latexの箇所は画像として表示される(dvipngコマンドが必要)。カードを表示するタイミングでその都度latexのコンパイル→dvipngで画像出力がされていて、画像をどこか専用のディレクトリに保存しているわけではないので、スマホではlatexの箇所は表示されない(latexソースコードでの表示になる)。
カードは更新が可能
一旦カードを送信すると、「:PROPERTIES:」に「:ANKI_NOTE_ID:」という項目ができ、さらにカードを編集して送信すると、Anki側でもカードが更新される。ただしAnkiのブラウザを閉じておかないと更新されない。
改行を反映させたい
入力した内容をAnkiに送ったところ改行が反映されていない。改行を反映するには空行を入れるか、「M-;」してから以下を入力してEnterするか、予め.emacsに書いておく。
その後にM-x anki-editor-push-notesすると改行が反映されるようになる。
(setq org-export-preserve-breaks t)(org-mode , export , how to 'force' newline on lines between paragraphs? - Emacs Stack Exchange)
キーバインド
「a-pu」はそのままをタイプすればよい。
キーバインド | M-x | 意味 |
M-x a-pu RET | anki-editor-push-notes | カードをAnkiに送信 |
M-x an-i RET | anki-editor-insert-note | カード(orgのツリー)を追加 |
M-x a-cl-r RET | anki-editor-cloze-region | リージョンから穴埋め問題を作成 |
バージョン0.3.0では「anki-editor-insert-note」と「anki-editor-cloze-region」はエラーが出て使用できなかった。
anki-editorはカードの登録専用
anki-editorはAnkiにカードを登録できるが、Ankiからカードを読み込む機能はない。
GitHubのIssueで、Ankiからの読み込み機能を追加して欲しいとの要望が出ていたが、作者からは一旦HTMLにしたのをorgに戻すのは難しい、という感じの返答になっていた。
上記リンク先の要望の下の方に、Ankiから読み込む機能を作成したというコメントが付いているので、その手順にならって取り込んだファイルからHTMLタグを取り除いて、手作業でorgの書式に直せば一応実現は可能。
「#+PROPERTY: ANKI_DECK Default」をファイル先頭に書いても「:ANKI_DECK:」を指定しないと送信されない
公式では「#+PROPERTY: ANKI_DECK Default」をファイル先頭に書いておけば、登録するカードごとに「:ANKI_DECK:」を指定する必要はない、と書かれていたが、なぜかデッキが指定されていない旨のエラーが出て送信ができなかった(0.3.3でも同様)。
バージョン0.3.3で発生したエラーについて
最新のバージョン0.3.3を使用した際に発生した不具合をメモとして残しておく。使用したEmacsのバージョンは「GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.18.9) of 2019-12-24」
重複したカードは上書きされない
内容の重複したカードを送信すると「:PROPERTIES:」内の「:ANKI_FAILURE_REASON:」に「Symbol’s function definition is void: err」というエラーが出てしまい、インポート時のように上書き保存はされない。つまり、org-mode側で単語帳を管理しておく、という使い方はできない(デッキからカードを全部消して再度anki-editorから送信すれば別だが、学習履歴が消えてしまう)。
→バージョン0.3.3のバグ?と思われる。
「:ANKI_FAILURE_REASON: Symbol’s function definition is void: err」について
「:ANKI_DECK:」に指定するデッキの名前が間違っていたり、ブラウザを開いたときに表示されている「ソートフィールド」が重複したカードを送信すると表示されるエラーだが、あまりにもそのままのエラー表示で、あたかもインストールの不具合のようであり紛らわしい。
→バージョン0.3.0では、それらのときには対応するエラーメッセージが正しく表示されていたので、内部的なエラー表示と思われる。
「:ANKI_FAILURE_REASON: Wrong type argument: listp, 」について
カードをAnkiに送信する際になぜか表示されるが、単語は問題なく登録されている。気にしないことにする。
感想
これで晴れてEmacsの、しかもorg-modeから単語登録ができるようになり、学習も捗るようになるだろう(願わくば)。
実際には、このインストール作業の試行錯誤で大部時間を浪費してしまったのだが…。