Ankiでカード上部にタグに応じた絵文字を表示する

hero_image
2023-10-01
2023-10-09

はじめに

Ankiは私の暗記能力の大きな支えとなっているアプリだ。

このアプリのおかげで私は暗記系の試験を無理なく合格できてきたと言っても過言ではないくらいお世話になっている。

今回はそのAnkiについての簡単なカスタマイズとして、カードの上部にタグに応じた絵文字を表示する方法を書く。

完成するとこのような表示になる。

sample for display tagged emojis at the top of the card in anki

この絵文字は同じようなトリガーだが別の分野について暗記をする際の判別と頭の切り替えに役立つ。例えば現在時刻を取得するSQLがMySQLだとSELECT NOW();なのに対してPostgreSQLはSELECT CURRENT_TIMESTAMP;とか。

それと単純に視覚的に楽しい。

先に断っておくと、この方法はカードのテンプレートを編集する都合上、PCの環境が無い方は申し訳ないが試せない。

手順

今回は例として、穴埋め(Cloze)形式のノートタイプを使用する。基本(Basic)形式を使う場合でも既定のHTMLに追加で少々書き加えるだけなので、その場合は適宜読み替えてほしい。

1. 新規ノートタイプを作成する

ノートの管理画面から追加する。

画面の通りに操作するだけなので特に説明することはないが、ノートの名前は例えばCloze with Tag's EmojiとかベースになっているノートタイプにWith句で今回のカスタマイズ内容を付け加えた形が見やすいと私は思う。

2. カードのテンプレートを編集する

カードを追加する画面などで Cards... を押して編集画面を開く。

ここからはカードの表示の元となっているHTML, CSSを編集する。

以下ではFront Template, Back Template, Stylingの順にサンプルのコードを貼るが、Templateの二つについては同じ内容を追加するだけになっている。一応、コピーすればそのまま使えるようにどちらとも全体を貼るが、既存部分以外は重複していることをご留意いただきたい。

まずFront Template

  • 既存のコードの上に<div id="emoji-container"></div>という絵文字を表示するための領域を追加する。
  • そして既存のコードの下に<script>...</script>というタグに対応する絵文字を上記の領域に追加して表示するスクリプトを追加する。
  • 肝心のtag: 'emoji'については// tag: 'emoji'とある部分のtag1: ...を編集して行う。例えば追加したいタグがbeerで対応させたい絵文字が🍺ならbeer: '🍺',とする。

なお、スクリプトの細かい内容については後の開発者向けの項目で説明するので、ただ使うだけの人は気にしないでいい。

<div id="emoji-container"></div>
{{cloze:Text}}
<script>
(() => {
  const tags = '{{ Tags }}'.split(' ');
  const emojiMap = {
    // tag: 'emoji'
    tag1: '😀',
    tag2: '😎',
  };

  const container = document.getElementById('emoji-container');

  tags.forEach(tag => {
    if (emojiMap[tag]) {
      const div = document.createElement('div');
      div.textContent = emojiMap[tag];
      container.appendChild(div);
    }
  });
})();
</script>

次にBack Template

先に言った通り、追加部分は同じ。

<div id="emoji-container"></div>
{{cloze:Text}}<br>
{{Back Extra}}
<script>
(() => {
  const tags = '{{ Tags }}'.split(' ');
  const emojiMap = {
  // tag: 'emoji'
    tag1: '😀',
    tag2: '😎',
  };

  const container = document.getElementById('emoji-container');

  tags.forEach(tag => {
    if (emojiMap[tag]) {
      const div = document.createElement('div');
      div.textContent = emojiMap[tag];
      container.appendChild(div);
    }
  });
})();
</script>

最後にStyling

これは既存ものの最後に以下のものを追加するだけでいい。

#emoji-container {
    display: flex;
    justify-content: space-around;
    margin-bottom: 0.5em;
}

ちなみに既存の部分を修正することで、文字の中央寄せを左寄せにすることもできる。

さて、ここまでやってSaveを押せばもう使えるようになっている。

あとは絵文字を表示したいタグがあれば、先ほどの// tag: 'emoji'の部分に追加なり編集をすればOKである。

おまけ: 開発者向け

  • 即時実行関数(IIFE)を使用している理由:定数・変数のスコープを限定することで、カード裏返し時の再実行による定数・変数の再宣言エラーを防止するため。また一般論として、グローバルスコープをむやみに汚染しないため。
  • tagsが空である場合の例外処理がない理由: forEach()は配列の要素数分だけコールバック関数を呼び出すため、空の場合は呼び出さないだけでエラーを出さずに終了するため。

おわりに

私は日頃からJavaScriptを使っているので、いざ絵文字を追加するとなったときにコードを編集するのには何ら抵抗がないのだが、普通の一般ユーザーからそうではないのかなと今回これを書いていて思った。

ちなみにJavaScriptではなく以下のようにCSSの疑似要素を使う方法もあるが、こちらは複数ある場合に融通が効かないのでお勧めしない。

#tag1::before {
  content: '😀';
}
© 2023 ryomazone.dev