Ankiで暗記ペンを実現する方法Ⅱ 拡張仕様編 | 学習メモ。

学習メモ。

長男(開成→東大理1[2016現役・専願]→東大大学院情報理工学系研究科→大手外資系IT企業)、長女(桜蔭→東大文1[2020現役・専願・TLP仏語]→東大大学院人文社会系研究科)の生活,中学・大学受験。暗記はAnkiが9割。リスニングは英語アニメが10割。

Ankiで暗記ペンを実現する方法【目次】 Ⅰ 基本仕様編
Ⅱ 拡張仕様編

  1.はじめに

  2.暗記ペン形式(拡張仕様)の動作

    (1) 選択式暗記ペン

    (2) 文字列追加/文字列除去

    (3) 合わせ技

  3.暗記ペン形式(拡張仕様)の実装方法

    (1) フィールドへのタグ付け

    (2) スタイル(CSS)の設定

    (3) JavaScriptの設定

  4.サンプルデッキのダウンロード

  5.おわりに

 

1.はじめに

  当ブログでは、中学受験、大学受験、大学での語学学習のために、分散学習システム Ankiを大いに役立てている。

  先に公開した「Ankiで暗記ペン形式を実現する方法Ⅰ 基本仕様編」では、問題文中に複数の穴埋め箇所がある教材をAnkiデッキ化するのに最適な、暗記ペン形式の基本仕様を提示した。

  このⅡ拡張仕様編では、Ⅰ基本仕様に対し、(1)選択式暗記ペン、(2)文字列追加/文字列除去という2つの機能を新たに追加する。これにより、暗記ペン形式によるAnkiの活用場面が、より洗練された形で広がることを期待している。

 

  Ankiソフトウェア(Windows・Mac)・AnkiWeb(Safari/Chrome/Firefox/IE 10以降)・AnkiMobile (iOS)・AnkiDroid (Android)での正常動作を確認している。

 

2.暗記ペン形式(拡張仕様)の動作

 

(1) 選択式暗記ペン

  問題文に埋め込まれた選択肢の中から正解を選択するタイプの問題を暗記ペン形式に対応させるための拡張仕様である(問題文の後ろに選択肢を示すよくあるタイプの問題は、暗記ペン形式になじまない。従来の形式で足りる)。

  次のように動作する。

  • マークの上に選択肢となる文字列が表示される。
  • マークを解除すると、正解が赤文字で強調され、錯乱肢(誤答の肢)には打ち消し線が引かれる。

【動作デモ1】

  中学受験用理科教材『理科コアプラス』を暗記ペン形式(選択式暗記ペン)にしたものである。上の画像をクリックすれば、新しいウインドウが開き実際にマーク部分の動作を確認できる

 

(2) 文字列追加/文字列除去

  暗記ペン形式(基本仕様)では、マークの幅はマーク解除時の正解文字列の幅と一致する。通常はそれで十分であるが、次のような場合には、マークの幅と正解文字列の幅を一致させないのが望ましい。

 

a. 正解にカッコ書きなどによる注記が付されているが、マーク表示の段階では注記の分の幅をとりたくない場合。

b. マークの幅により正解の文字数が予想されてヒントになるのを避けたい場合。

c. マークが列挙されているなどの理由からマークの幅を整然とそろえたい場合。

 

  そこで、次のような拡張仕様を用意した。

  a.に対しては、マークを解除時に、マークに隠れていた正解文字列にさらに注記を追加して表示する(文字列追加機能)。
  b.に対しては、実際の正解文字列よりマーク幅を広く表示したい場合は文字列除去機能、実際の正解文字列よりマーク幅を狭く表示したい場合は文字列追加機能を適用する。こうして正解文字列の幅とは独立にマークの幅を自由に設定できる。

  c.に対しては、b.と同様に、文字列追加文字列除去を組み合わせてマーク幅を調整する。

 

【動作デモ2】

  中学受験用社会教材『社会コアプラス』を暗記ペン形式(拡張仕様[文字列追加]を使用)にしたものである。a.の例である。上の画像をクリックすれば、新しいウインドウが開き実際にマーク部分の動作を確認できる

  • マーク表示の段階では「(厩戸皇子)」という別名を示す注記の分の幅がとられていない。
  • マーク解除時には、マーク下に隠れていた正解文字列「聖徳太子」にさらに「(厩戸皇子)」という注記を追加して表示する。
  • これがもし基本仕様のままだと、「聖徳太子(厩戸皇子)」という長い正解文字列の幅と一致する長いマーク表示となり、あまりスマートでない(「こんな長い名前の人物いたっけ?」と不可解に思われたり、「これって別名があるから長いんでしょ。ということは聖徳太子が正解だ」と無用のヒントとなったりする)。

【動作デモ3】

  動作デモ1と同じく、『理科コアプラス』を暗記ペン形式(拡張仕様[文字列追加/文字列除去]を使用)にしたものである。正解の文字数が予想されてヒントとなるのを避けるという意味ではb.の例であり、マークを整然と並べるという意味ではc.の例でもある。上の画像をクリックすれば、新しいウインドウが開き、実際にマーク部分の動作を確認できる

 

(3) 合わせ技

  (1)選択式暗記ペンのマーク上に文字列(選択肢)を表示する仕組みと(2)文字列追加文字列除去機能を組み合わせることで、トリッキーだが直感的な動作が可能である。

【動作デモ4】

  上の画像をクリックすれば、新しいウインドウが開き、、実際にマーク部分の動作を確認できる

  • マーク上にマーク番号(「 ① 」等)を表示している(選択式暗記ペンの選択肢表示を便宜的に使用)。マーク番号は複数のマーク間で正解が共通であることを示すのに有用である。
  • マーク上のマーク番号(「 ① 」等)をマーク解除時に除去し(文字列除去機能)、代わりに正解文字列(「恒星」等)を追加する(文字列追加機能)。

 

3.暗記ペン形式(拡張仕様)の実装方法

  Ankiデッキに暗記ペン形式(拡張仕様)を実装するための作業は、おおまかには、以下の3段階で構成される。
(1)フィールドへのタグ付け

  Ⅰ基本仕様編3(1)のタグに加え、必要に応じ拡張仕様のために次のタグを付す。

  • 選択式暗記ペンについては、選択式暗記ペン形式のマーク範囲を示すタグ錯乱肢であることを示すタグを付す。裏面でも、錯乱肢であることを示すタグ(裏面用)を付す。
  • 文字列追加/文字列除去については、文字列追加を示すタグ文字列除去を示すタグを付す。

(2)スタイル(CSS)の設定

  Ⅰ基本仕様編3(2)のスタイルの設定に対し、拡張仕様のために次の表示を実現するスタイルを追加する。作業としては、後述の文字列を基本仕様時のスタイルに上書きする形で貼り付ければ、必要な内容が追加されていることになる。

  • 選択式暗記ペンについては、マーク解除時の錯乱肢のための打ち消し線を引く。裏面でも同様とする。
  • 文字列除去については、マーク解除時に対象の文字列を除去する。

(3)JavaScriptの設定

  Ⅰ基本仕様編3(3)のJavaScriptの設定に対し、拡張仕様の動作を実現する記述を追加する。作業としては、後述の文字列を基本仕様時のテンプレートに上書きする形で貼り付ければ、必要な内容が追加されていることになる。個々の記述の意味は省略する。


  以下に具体的な設定内容を示す。

 

(1) フィールドへのタグ付け

  Ankiでのタグ付けは、フィールド内で直接行うことはできない。ノート編集画面の各フィールド右上の「< >」マークからHTMLエディタに切り替えて行う(もちろん、Excelなどでタブ区切りテキストを作成し、それをAnkiに読み込んでデッキ化する方法を使うこともできる。その場合はExcelなどでタグ付け作業することになる)。

 

ア.選択式暗記ペン

 

  動作デモ1表面の問題文フィールドの内容

コップに入れた氷水の氷がとけると、水面の高さは<span class="choice" onclick="cloze(this.id);"><span class="wrong">高くなる</span> <span class="wrong">低くなる</span> 変わらない</span>

  1. マーク部分に選択式暗記ペンのマーク範囲を示すchoiceクラスのタグを付す。
  2. 錯乱肢(誤答の肢)に<span class="wrong"></span>タグを付す。例のように錯乱肢が複数ある場合はそれぞれについて同様にする。なお、裏面の錯乱肢に<span class="wrongans"></span>タグを付す。
  3. 選択式であることが明確になるように、選択式暗記ペンのマークを{ }で囲む(選択式暗記ペンの動作にとって必須ではない)。

イ.文字列追加/文字列除去

 

  動作デモ2表面の問題文フィールドの内容

  ※簡略化のため、ここではルビにかかわるタグは除去してあるが、ルビがあっても適切に動作することは動作デモのとおりである。

593年に<span class="cloze" onclick="cloze(this.id);">推古</span>天皇の摂政となった<span class="cloze" onclick="cloze(this.id);">聖徳太子<span class="add">(厩戸皇子)</span></span>は、<span class="cloze" onclick="cloze(this.id);">蘇我馬子</span>の協力を得て、<span class="cloze" onclick="cloze(this.id);">天皇</span>を中心とする国づくりをめざし政治をすすめました。

  1. マーク部分にマーク範囲を示すclozeクラスのタグを付す(基本仕様)。
  2. マーク解除時に正解文字列に追加して表示させたい文字列に<span class="add"></span>タグを付す(このタグマーク範囲を示すタグの内側になければならない)

  動作デモ3表面の問題文フィールドの内容

下図は、夏の大三角が天頂付近に高く上がったようすを見上げてかき写したスケッチです。A~Cそれぞれがふくまれる星座の名前と、1等星A~Cの名前を答えなさい。<br>A <span class="cloze" onclick="cloze(this.id);">はくち<span class="add">ょう</span></span>座・<span class="cloze" onclick="cloze(this.id);">デネブ</span> <br>B <span class="cloze" onclick="cloze(this.id);">わし<span class="remove"> </span></span>座・<span class="cloze" onclick="cloze(this.id);">アルタ<span class="add">イル</span></span> <br>C <span class="cloze" onclick="cloze(this.id);">こと<span class="remove"> </span></span>座・<span class="cloze" onclick="cloze(this.id);">ベガ<span class="remove"> </span></span>

  1. マーク部分にマーク範囲を示すclozeクラスのタグを付す(基本仕様)。
  2. マーク解除時に正解文字列から除去したい文字列に<span class="remove"></span>タグを付す(このタグマーク範囲を示すタグの内側になければならない)。ここではマークの幅を確保するための調整に使用したダミーの全角スペースをマーク解除時に正解文字列から除去している。
  3. マーク解除時に正解文字列に追加して表示させたい文字列に<span class="add"></span>タグを付す(このタグマーク範囲を示すタグの内側になければならない)

ウ.合わせ技

 

  動作デモ4表面の問題文フィールドの内容

自ら光を出してかがやいている星を<span class="choice" onclick="cloze(this.id);"><span class="add">恒星</span><span class="remove"> ① </span></span><span class="choice" onclick="cloze(this.id);"><span class="add">恒星</span><span class="remove"> ① </span></span>のまわりを公転している星を<span class="choice" onclick="cloze(this.id);"><span class="add">惑星</span><span class="remove"> ② </span></span><span class="choice" onclick="cloze(this.id);"><span class="add">惑星</span><span class="remove"> ② </span></span>のまわりを公転している星を<span class="choice" onclick="cloze(this.id);"><span class="add">衛星</span><span class="remove"> ③ </span></span>といいます。
  1. マーク部分にマーク範囲を示すタグを付す。基本仕様ではマーク範囲を示すのはclozeクラスであるが、ここではマーク上にマーク番号(「 ① 」等)を表示するために、便宜上、選択式暗記ペンのマーク範囲を示すchoiceクラスとする。
  2. マーク解除時に正解文字列から除去したい文字列(「 ① 」等)に<span class="remove"></span>タグを付す(このタグは選択式暗記ペンのマーク範囲を示すタグの内側になければならない)。
  3. マーク解除時に正解文字列に追加して表示させたい正解文字列(「恒星」等)に<span class="add"></span>タグを付す(このタグは選択式暗記ペンのマーク範囲を示すタグの内側になければならない)

  以上のような複雑なタグ付けを手作業で行うのはかなり面倒である。あらかじめタグではなく簡略な符号で対象の文字列をくくるなどしておいて最後に所定のタグへ一括置換すれば楽ができる。

  私自身は、Ankiデッキ用のデータ入力やタブ区切りテキスト出力作業をもっぱらFileMaker Pro上で行っており。この種のタグ付け作業は、次の自作カスタム関数により自動処理している。
 FileMaker Pro用カスタム関数 Cloze

概要

与えられたテキストを次のようにタグ付けする。

  • {{」「}}」でくくられた、マーク表示したい文字列にclozeクラスタグを付す。ただし、「{{」「}}」の前後がさらに「」「」(全角)でくくられている場合はchoiceクラスタグを付す。
  • <|」「|>」でくくられた、錯乱肢の文字列にwrongクラスタグを付す。
  • [[」「]]」でくくられた、マーク解除時に正解文字列に追加したい文字列にaddクラスタグを付す。
  • <<」「>>」でくくられた、マーク解除時に正解文字列から除去したい文字列にremoveクラスタグを付す。
構文 Cloze (テキスト)
引数 テキスト(タイプ:テキスト) タグ付けしたい文字列を含むテキスト。
例1 Cloze ("コップに入れた氷水の氷がとけると、水面の高さは{{<|高くなる|> <|低くなる|> 変わらない}}。")
結果1 コップに入れた氷水の氷がとけると、水面の高さは<span class="choice" onclick="cloze(this.id);"><span class="wrong">高くなる</span> <span class="wrong">低くなる</span> 変わらない</span>
例2 Cloze ("下図は、夏の大三角が天頂付近に高く上がったようすを見上げてかき写したスケッチです。A~Cそれぞれがふくまれる星座の名前と、1等星A~Cの名前を答えなさい。<br>A {{はくち[[ょう]]}}座・{{デネブ}} <br>B {{わし<< >>}}座・{{アルタ[[イル]]}} <br>C {{こと<< >>}}座・{{ベガ<< >>}}")
結果2 下図は、夏の大三角が天頂付近に高く上がったようすを見上げてかき写したスケッチです。A~Cそれぞれがふくまれる星座の名前と、1等星A~Cの名前を答えなさい。<br>A <span class="cloze" onclick="cloze(this.id);">はくち<span class="add">ょう</span></span>座・<span class="cloze" onclick="cloze(this.id);">デネブ</span> <br>B <span class="cloze" onclick="cloze(this.id);">わし<span class="remove"> </span></span>座・<span class="cloze" onclick="cloze(this.id);">アルタ<span class="add">イル</span></span> <br>C <span class="cloze" onclick="cloze(this.id);">こと<span class="remove"> </span></span>座・<span class="cloze" onclick="cloze(this.id);">ベガ<span class="remove"> </span></span>

Substitute ( テキスト ; ["{{{" ; "{<span class=\"choice\" onclick=\"cloze(this.id);\">" ];[ "{{" ; "<span class=\"cloze\" onclick=\"cloze(this.id);\">" ];[ "}}" ; "</span>" ];[ "]]" ; "</span>" ];[ ">>" ; "</span>" ];

[ "|>" ; "</span>" ];[ "[[" ; "<span class=\"add\">"] ;[ "<<" ; "<span class=\"remove\">" ] ;[ "<|" ; "<span class=\"wrong\">" ])

 

(2) スタイル(CSS)の設定

  テンプレート編集画面の「スタイル」に以下の文字列をペーストする。すでにⅠ基本仕様編3(2)でスタイルの設定をしている場合は、それと置き換える(以下の設定にはⅠ基本仕様の内容もすべて含んでいる)。

/* 暗記ペン */

.cloze, .choice {

  color: transparent;

  background-color: #f68385; /* マーク色 */

  cursor: pointer;

  -webkit-user-select: none; /* Anki PC・Mac / AnkiMobile / AnkiDroid / Chrome / Safari */

  -moz-user-select: none; /* Firefox */

  -ms-user-select: none; /* IE 10+ */

  box-shadow: 0 3px 2px #777;

}

.choice {

  color: black; /* 選択肢文字色 */

}

.wrongans {

  color: black; /* 錯乱肢裏面文字色 */

  text-decoration: line-through;

}

.cloze rt {

  visibility: hidden;

}

ruby {

  position: relative;

}

ruby rt {

  position: relative;

}

.add {

  display: none;

}

.hot {

  color: red; /* 裏面正解文字色 */

}

  /* マーク色 */の左の#f68385の部分は、好みで変更してよい(HTMLカラーコード参照)。ただし、(3)JavaScriptの設定のマーク色とも統一すること。

 

(3) JavaScriptの設定

  テンプレート編集画面の「表面のテンプレート」に以下の文字列をペーストする(裏面にもマークを設定したい場合には「裏面のテンプレート」でも同様にする)。すでにⅠ基本仕様編3(3)でテンプレートの設定をしている場合は、それと内容を置き換える(以下の設定にはⅠ基本仕様の内容もすべて含んでいる)。

<script type = "text/javascript">

if (window.addEventListener) {

  window.addEventListener('load', load);

} else if (window.attachEvent) {

  window.attachEvent('onload', load);

}

window.onload = load();

function load() {

  var tags = document.getElementsByTagName("span");

  var count = 0;

  for (var i = 0; i < tags.length; i++) {

    if (tags[i].className == "cloze" || tags[i].className == "choice")

    tags[i].id = "c" + (++count).toString();

  }

}

 

function cloze(id) {

  var e = document.getElementById(id);

  var rt = e.getElementsByTagName("rt");

  var num = rt.length;

  var wrong = e.getElementsByClassName("wrong");

  var wrongnum = wrong.length;

  var add = e.getElementsByClassName("add");

  var addnum = add.length;

  var rem = e.getElementsByClassName("remove");

  var remnum = rem.length;

  if (e.style.backgroundColor == "transparent") {

    e.style.backgroundColor = "#f68385"; // マーク色

    e.style.boxShadow = "0 3px 2px #777";

    e.style.visibility = "visible";

      if (e.className == "choice") {

        e.style.color = "black";

      } else {

        e.style.color = "transparent";

        for (var count = 0; count < num; count++) {

          rt[count].style.visibility = "hidden";

        }

      }

      for (var count = 0; count < wrongnum; count++) {

        wrong[count].style.textDecoration = "none";

      }

      for (var count = 0; count < addnum; count++) {

        add[count].style.display = "none";

      }

      for (var count = 0; count < remnum; count++) {

        rem[count].style.display = "inline";

      }

  } else {

    e.style.backgroundColor = "transparent";

    e.style.boxShadow = "0 0px 0px #777";

    e.style.color = "red"; // 正解文字色

    e.style.visibility = "visible";

    for (var count = 0; count < wrongnum; count++) {

      wrong[count].style.textDecoration = "line-through";

      wrong[count].style.color = "black"; // 錯乱肢文字色

    }

    for (var count = 0; count < num; count++) {

      rt[count].style.visibility = "visible";

    }

    for (var count = 0; count < addnum; count++) {

      add[count].style.display = "inline";

    }

    for (var count = 0; count < remnum; count++) {

      rem[count].style.display = "none";

    }

  }

}

</script>

「// 正解文字色」の左のカラー指定(HTMLカラーコード参照)で、マーク解除時の正解文字列の色を任意に設定できる。

 

4.サンプルデッキのダウンロード

  動作デモ1~4を含む公開用サンプルAnkiデッキを提供する。以下からダウンロードし、Ankiに読み込めば使用できる。あくまで動作確認用サンプルであり、教材としての実用性はない
暗記ペン拡張仕様サンプル.apkg
を 今すぐダウンロード

 

5.おわりに

  以上、Ⅰ基本仕様に対し新たに2つの機能を加えるⅡ拡張仕様を紹介した。

  このⅡ拡張仕様編で示した(2)スタイル(CSS)の設定、(3)JavaScriptの設定には、Ⅰ基本仕様編の内容を大は小を兼ねる形ですべて含んでいる。したがって、今後Ⅱ拡張仕様のための(1)フィールドへのタグ付けをするか未定の場合でも、とりあえず、Ⅱ拡張仕様の(2)スタイル(CSS)の設定、(3)JavaScriptの設定を採用しておいてかまわない。

  これに対し、Ⅱ拡張仕様を使う予定が全くなく少しでもシンプルに暗記ペン形式を使いたい場合には、Ⅰ基本仕様を採用するのがよい。

  説明がわかりにくい箇所の指摘や、やってみたがうまくいかないなどのご相談があれば、メッセージいただきたい。

 

更新履歴


2016年5月14日

  • 初出。

2016年5月16日

  • 2.暗記ペン形式(拡張仕様)の動作に、(3)合わせ技、動作デモ4を追加。

2016年5月18日

  • window.onloadに加え、あらたにwindow.addEventListenerでIDを付与する方式を併用することで、AnkiDroidでもJavaScriptによるID付与が可能となり、事前のタグ付けの際にIDを付与する必要がなくなった。

2016年10月23日

  • サンプル表示に使用していたDropboxのPublicフォルダレンダリング停止に伴い、サンプルの置き場を変更。

2024年4月19日

  • Ankiの最新版の表示・用語に合わせて説明を調整。