ScrapboxでAnkiの問題を作る手法検討
とりあえず作業場を作成。中身は後ほど書きますtakker.icon
期待mtane0412.iconはるひ.iconmrsekut.iconwogikaze.iconmiyamonz.iconstar_field.iconbsahd.icon
Ankiの元になったSuperMemoの作者は「文章を読みながら抜書きして行って最終的にクイズに変える」というやり方をしているnishio.icon これをAnkiに放り込めばいい
まあそう単純にはいかないけど
2024-10-15 scrapbox上でSRSを作る方針に変更している apkgの構造を解析して、同じものを作るコードを書こうとするのが非常に煩雑 メディア埋め込みをうまく処理できない
AnkiにScrapboxのデータを入力するのではなく、scrapbox上でAnkiする
UIにもめどがついた
scrapboxの画面をそのまま問題解答画面にすればいい
わざわざ解説などをAnki向けに書き直さずに済むのが大きい
解答中は問題だけ表示し、解答後に周囲の文章も表示すれば、それがそのまま問題の解説になる
ネーミングセンスのなさ()
jsrにpublishする予定なので@takker/がついている
ScrapXXXは今後使わない予定です
cosenseに付随する名前にする
でもScrapAnkiもよさそうだなあ
学習側のplatform
Scrapboxで問題データを作り、Ankiにimportする
このページではこの方法を検討する
これはパス
理論上は可能
区切り文字は何でもいい
利点
UserScriptなしでAnkiデータを作れる
限界
凝ったことはしにくい
(UserScriptなしだと)HTMLで凝った問題を作りにくい
HTMLを書いたコードブロックと、圧縮してtableに入れ込んだものを同時に管理しているtakker.icon
例
table:anki
PC-2022F-小テスト2 <table><caption>セメント化学で使われる記法</caption><thead><tr><th>化合物名</th><th>化学式</th><th>略記法</th></tr></thead><tbody><tr><td>{{c1::Calcium Oxide}}</td><td>{{c1::\(\rm CaO\)}}</td><td>{{c2::\(\rm C\)}}</td></tr><tr><td>{{c1::Silicon Dioxide}}</td><td>{{c1::\(\rm SiO_2\)}}</td><td>{{c2::\(\rm S\)}}</td></tr><tr><td>{{c1::Aluminium(III) Oxide}}</td><td>{{c1::\(\rm {Al}_2O_3\)}}</td><td>{{c2::\(\rm A\)}}</td></tr><tr><td>{{c1::Iron(III) Oxide}}</td><td>{{c1::\(\rm {Fe}_2O_3\)}}</td><td>{{c2::\(\rm F\)}}</td></tr><tr><td>{{c1::Water}}</td><td>{{c1::\(\rm H_2O\)}}</td><td>{{c2::\(\rm H\)}}</td></tr></tbody></table>
PC-2022F-小テスト2 <table><caption>クリンカ鉱物の記法</caption><thead><tr><th>鉱物名</th><th>化学式</th><th>略記法</th></tr></thead><tbody><tr><td>{{c1::Alite}}</td><td>{{c1::\(\rm 3CaO\cdot SiO_2\)}}</td><td>{{c2::\(\rm C_3S\)}}</td></tr><tr><td>{{c1::Belite}}</td><td>{{c1::\(\rm 2CaO\cdot SiO_2\)}}</td><td>{{c2::\(\rm C_2S\)}}</td></tr><tr><td>{{c1::Aluminate}}</td><td>{{c1::\(\rm 3CaO\cdot{Al}_2O_3\)}}</td><td>{{c2::\(\rm C_3A\)}}</td></tr><tr><td>{{c1::Ferrite}}</td><td>{{c1::\(\rm 4CaO\cdot{Al}_2O_3\cdot{Fe}_2O_3\)}}</td><td>{{c2::\(\rm C_4AF\)}}</td></tr></tbody></table>
code:1.html
<table>
<caption>セメント化学で使われる記法</caption>
<thead>
<tr>
<th>化合物名</th>
<th>化学式</th>
<th>略記法</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{c1::Calcium Oxide}}</td>
<td>{{c1::\(\rm CaO\)}}</td>
<td>{{c2::\(\rm C\)}}</td>
</tr>
<tr>
<td>{{c1::Silicon Dioxide}}</td>
<td>{{c1::\(\rm SiO_2\)}}</td>
<td>{{c2::\(\rm S\)}}</td>
</tr>
<tr>
<td>{{c1::Aluminium(III) Oxide}}</td>
<td>{{c1::\(\rm {Al}_2O_3\)}}</td>
<td>{{c2::\(\rm A\)}}</td>
</tr>
<tr>
<td>{{c1::Iron(III) Oxide}}</td>
<td>{{c1::\(\rm {Fe}_2O_3\)}}</td>
<td>{{c2::\(\rm F\)}}</td>
</tr>
<tr>
<td>{{c1::Water}}</td>
<td>{{c1::\(\rm H_2O\)}}</td>
<td>{{c2::\(\rm H\)}}</td>
</tr>
</tbody>
</table>
code:2.html
<table>
<caption>クリンカ鉱物の記法</caption>
<thead>
<tr>
<th>鉱物名</th>
<th>化学式</th>
<th>略記法</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{c1::Alite}}</td>
<td>{{c1::\(\rm 3CaO\cdot SiO_2\)}}</td>
<td>{{c2::\(\rm C_3S\)}}</td>
</tr>
<tr>
<td>{{c1::Belite}}</td>
<td>{{c1::\(\rm 2CaO\cdot SiO_2\)}}</td>
<td>{{c2::\(\rm C_2S\)}}</td>
</tr>
<tr>
<td>{{c1::Aluminate}}</td>
<td>{{c1::\(\rm 3CaO\cdot{Al}_2O_3\)}}</td>
<td>{{c2::\(\rm C_3A\)}}</td>
</tr>
<tr>
<td>{{c1::Ferrite}}</td>
<td>{{c1::\(\rm 4CaO\cdot{Al}_2O_3\cdot{Fe}_2O_3\)}}</td>
<td>{{c2::\(\rm C_4AF\)}}</td>
</tr>
</tbody>
</table>
非常に管理がめんどくさい
HTMLを圧縮するのがめんどくさい
script使えば楽にはなるが……
手動で同期させるのがめんどくさい
タグ付けが面倒
問題の同一性を担保しにくい
何らかのIDを問題ごとに割り振るのが現実的だが、そのIDを作るのが面倒
インポート方法がややこしい
deck, card type, 列と対応させるfield、上書き設定などをすべてインポートするユーザが設定しなければならない
問題作成者側で設定できない
学習記録を含めて記録できるAnkiのデータ形式
学習記録を削ったものが共有デッキとして公開されている 利点
deckやcard typeの設定まで含めてexportできる
限界
apkg形式にデータを変換するprogramが存在しない
技術的には可能なので作りたいtakker.icon
sql.jsを使えばscrapboxのUserScript上でsqlite DBを操作できる すでに動作確認済み
javascript port ankiで検索して見つけた
takker.iconの調査不足だった……
ま、まあ、実装前に発見できたからいいか
実装は、takker.iconが考えたのとほぼ同じ
dbを調査する手間が省けた
server向けに設定されていて使いづらそうなので、refactoringする
明日書き換える
データ作成方針
UserScript無し(現行)
上述した限界があるのでやめたい
UserScript併用
Scrapbox projectをまるごとexportして、そのまま一つのapkgファイルに変換する、なんて使い方ができる
変換処理をbookmarkletにしておけば、ボタンひとつでいつでも最新の問題データを取得できて便利
RSS pluginの仕組みを組み合わせれば、自動更新も可能かもしれない
ほしいもの
簡単に問題をCRUDする
Dはいらんかも
CとUが楽にできればいい
HTMLは書きたくない
やること
どの方法を使うにしても決める必要のあること
scrapbox上でのAnkiデータの表現方法
どの塊を一つの問題とみなす?
card typeは単一にする?カスタムできるようにする?
取り組む問題を絞り込むため、最初はcloze問題に固定することにするtakker.icon
問題の同一性を担保する方法
scriptで適当なIDを振るのが現実的
IDの
桁数
見やすくしたいので、短いIDにしたい
/[0-9a-zA-Z]/を使えば、14桁くらいでも衝突しないか?
Math.random()でIDを作っているだけ
/[0-9a-zA-Z]{14}/で1回/秒 生成すると、生成開始から16000年目以降に1%の確率で1回衝突が起きる
これだけ確率が低ければ、衝突しないと考えていいだろう
生成に利用する情報
完全ランダムでもあまり衝突しなさそう
↑より衝突確率は無視できるほど小さいので、このままで行く
行IDは使わない
編集で容易に書き換わってしまうから
どの時点で振る?
apkgへexportするとき
idのない問題に新しいidを降り、websocket経由で書き込む
ユーザー側からみると楽だが、書き込み位置の調整などをまじめに組もうとするとかなり面倒
idのない問題を無視し、IDを振るようユーザーに警告を出す
ユーザーは別途IDを作るUserScriptを使って、手作業で振っていく
問題データに必要な情報
穴埋め箇所が指定された文章
例:{{c1::Aluminate}}は,水和熱が{{c2::大::大/中/小}}、短期強度への貢献は{{c2::大::大/中/小}}、長期強度への貢献は{{c2::小::大/中/小}}である
穴埋め問題の作成支援scriptはもう作ってあるtakker.icon
タグ
カスタム学習しやすくするために作る
どういうルールでタグ付けするかが難しい
ID
問題データ更新用
同じIDの問題を上書きさせる
この3つで十分そうだなtakker.icon
問題数とページ数の関係
1ページ1問題
利点
問題の範囲が明確
1ページ全てを一つの問題として変換すればいい
限界
ページが細かくなって使いづらくなりそうtakker.icon
1ページn問題
これが妥当そう
問題の境界を何で分けるか
先行研究では、どれも特定の文字列で分割している
まあこの方法で分ければいいだろう
nページ1問題
これは問題を大きく作りすぎ
別のページのデータを参照して問題を作る場合がある?
そのうちやる
cad typeを記述するページを作る
表、裏、CSSをそれぞれ指定した名前のコードブロックに書き込んでおく
問題を記述した箇所に、特定の書式でそのページへのリンクを貼ると、そのcard typeを適用するよう設定する アイコン記法で書けばいいだろうtakker.icon
これ以上は、目に見えるものを作りながら考えたほうがいいな
とりあえずなんかscript組むか。
問題の作り方