ScrapboxでAnkiの問題を作る手法検討
とりあえず作業場を作成。中身は後ほど書きますtakker.icon
他の人のアイデアもほしいので、個人projectではなく井戸端でやってみる
期待mtane0412.iconはるひ.iconmrsekut.iconwogikaze.iconmiyamonz.iconstar_field.iconbsahd.icon
Ankiの元になったSuperMemoの作者は「文章を読みながら抜書きして行って最終的にクイズに変える」というやり方をしているnishio.icon
/nishio/incremental reading
ReadwiseのMastely機能もそれだはるひ.icon
アクティブ読書で文章から箇条書きに直すと抜書きっぽくなるtakker.icon
これをAnkiに放り込めばいい
まあそう単純にはいかないけど
2024-10-15 scrapbox上でSRSを作る方針に変更している
apkgの構造を解析して、同じものを作るコードを書こうとするのが非常に煩雑
メディア埋め込みをうまく処理できない
AnkiにScrapboxのデータを入力するのではなく、scrapbox上でAnkiする
間隔反復法を実装するのが障壁だったが、FSRSで解決した
UIにもめどがついた
scrapboxの画面をそのまま問題解答画面にすればいい
わざわざ解説などをAnki向けに書き直さずに済むのが大きい
解答中は問題だけ表示し、解答後に周囲の文章も表示すれば、それがそのまま問題の解説になる
名前は...ScrapAnkiとか?bsahd.icon
暫定で@takker/cosense-srsにしましたtakker.icon
ネーミングセンスのなさ()
jsrにpublishする予定なので@takker/がついている
ScrapXXXは今後使わない予定です
cosenseに付随する名前にする
でもScrapAnkiもよさそうだなあ
学習側のplatform
Scrapboxで問題データを作り、Ankiにimportする
このページではこの方法を検討する
Scrapbox上でAnkiを実装する
これはパス
理論上は可能
SM2 algorithmとUIを実装すればいい
ScrapboxでAnkiの問題を作る手法検討#633225e7aff09e0000a16e0bをスムーズにやりたいときは、究極これに取り組むのが一番拡張性高そう
Ankiに直接インポートできる形式は以下の通り
Anki用CSVファイル
区切り文字は何でもいい
利点
UserScriptなしでAnkiデータを作れる
CSVで読み込めるので、table記法との相性がいい
限界
凝ったことはしにくい
(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、上書き設定などをすべてインポートするユーザが設定しなければならない
問題作成者側で設定できない
apkg
学習記録を含めて記録できるAnkiのデータ形式
学習記録を削ったものが共有デッキとして公開されている
実態は圧縮されたsqlite DB
利点
deckやcard typeの設定まで含めてexportできる
限界
apkg形式にデータを変換するprogramが存在しない
技術的には可能なので作りたいtakker.icon
sql.jsを使えばscrapboxのUserScript上でsqlite DBを操作できる
すでに動作確認済み
あ り ま し た
https://github.com/repeat-space/anki-apkg-export
javascript port ankiで検索して見つけた
takker.iconの調査不足だった……
ま、まあ、実装前に発見できたからいいか
実装は、takker.iconが考えたのとほぼ同じ
dbを調査する手間が省けた
server向けに設定されていて使いづらそうなので、refactoringする
https://github.com/takker99/deno-anki
明日書き換える
データ作成方針
Anki用CSVファイルを使う
UserScript無し(現行)
上述した限界があるのでやめたい
UserScript併用
apkgを使う
Scrapbox projectをまるごとexportして、そのまま一つのapkgファイルに変換する、なんて使い方ができる
変換処理をbookmarkletにしておけば、ボタンひとつでいつでも最新の問題データを取得できて便利
RSS pluginの仕組みを組み合わせれば、自動更新も可能かもしれない
ほしいもの
簡単に問題をCRUDする
2021/11/23#619c4b9119827000004256b1
Dはいらんかも
CとUが楽にできればいい
目安はHelpfeel記法を書くくらいの労力ですませたい
HTMLは書きたくない
やること
どの方法を使うにしても決める必要のあること
scrapbox上でのAnkiデータの表現方法
どの塊を一つの問題とみなす?
card typeは単一にする?カスタムできるようにする?
取り組む問題を絞り込むため、最初はcloze問題に固定することにするtakker.icon
問題の同一性を担保する方法
scriptで適当なIDを振るのが現実的
IDの
桁数
見やすくしたいので、短いIDにしたい
/[0-9a-zA-Z]/を使えば、14桁くらいでも衝突しないか?
/shokai/短いIDの生成
Nano IDで作れるっぽい
https://github.com/ai/nanoid/
https://esm.sh/nanoid@4.0.0/non-secure
Math.random()でIDを作っているだけ
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
/takker/Ankiの穴埋めを作るPopupMenu
タグ
カスタム学習しやすくするために作る
どういうルールでタグ付けするかが難しい
ID
問題データ更新用
同じIDの問題を上書きさせる
この3つで十分そうだなtakker.icon
問題数とページ数の関係
1ページ1問題
利点
問題の範囲が明確
1ページ全てを一つの問題として変換すればいい
限界
ページが細かくなって使いづらくなりそうtakker.icon
1ページ当たりの情報量は問題あたりの情報量よりずっと多い
1ページn問題
これが妥当そう
問題の境界を何で分けるか
先行研究では、どれも特定の文字列で分割している
[/icons/hr.icon]/daiiz/Scrapboxでレポートを書きたい
/hata6502/draft 記法
まあこの方法で分ければいいだろう
インライン問題方式を実験してみる
nページ1問題
これは問題を大きく作りすぎ
知識を構造化する20のルールで分割する
別のページのデータを参照して問題を作る場合がある?
そのうちやる
適用するcard type (Anki)の設定方法
cad typeを記述するページを作る
表、裏、CSSをそれぞれ指定した名前のコードブロックに書き込んでおく
問題を記述した箇所に、特定の書式でそのページへのリンクを貼ると、そのcard typeを適用するよう設定する
アイコン記法で書けばいいだろうtakker.icon
これ以上は、目に見えるものを作りながら考えたほうがいいな
とりあえずなんかscript組むか。
問題の作り方
知識を構造化する20のルールを参照