stag-enterprises

sourcing flashcards from silverbullet to anki

this is my setup of writing flashcards in silverbullet and using obsidiantoanki to import them to anki

how did i get here

A while back i used quizlet for my flashcards, but that quickly proved to be rather terrible idea. for those blissfully unaware of what they've done to their platform, nearly everything is paywalled, there are ridiculous amounts of ads, etcetera.

The next choice, quite obvious after a few searches, was anki. it also had fsrs. tl;dr, you rate each card after you review it, and the easier you rate a card, the less often it's shown to you. this way you can easily study large amounts of cards, something quizlet didn't have.

During all this, i had also moved to silverbullet for my note-taking. it's end-user programming capabilities are quite something, but it's probably not everyones cup of tea. it also stores all it's data in markdown files.

the setup

Silverbullet has a git plugin, so if i just hook it up to github, i can run something every time i update my notes. cool! to get the stuff from the markdown files into anki, i used obsidiantoanki. this needed an anki instance running ankiconnect. to get that, i ran anki inside a vnc instance and installed ankiconnect, so i could have an always-available ankiconnect server. finally, i used anki's built-in sync service so that i would get the latest cards on my local devices.

That's a lot of text, here's a diagram

Quite a bit of moving parts. let's take a closer look

silverbullet

This is easy. it's just the git plugin, set to auto-commit every day.

gh actions & obsidiantoanki

This was an absolute ass to configure. obsidiantoanki is somewhat abandoned by now, and it was a pain to get working. also, the documentation is just absolutely terrible.

To get this working I created an .anki dir in my silverbullet repo and put the script with it's 2 data files with it. then, i naively tried to create a workflow which would run the script. it didn't work

First github actions complained about not having a requirements.txt alright, fine, so i added .anki/requirements.txt. then it complained about some tty, looking through the source code, it turns out you SHOULDN'T install gooey, otherwise it breaks in ci.

Then, it complained about some method not existing in yadda yadda yadda i forgot at this point. turns out the python version i was using was too recent (it told me to use the latest version), so i set actions/setup-python to version 3.7. then there was no python 3.7 download for ubuntu 24, so i had to set that to 22. that also involved looking through the source of actions/setup-python.

Next, you would think it should be working by now, but no, because for some reason all the http requests the script was making were 403-ing. after about 20 minutes of debugging i figured it out it was my vpn. after a bit more of debugging, it turns out my vpn didn't like urllib.requests's user agent. changing the user agent in the script fixed this. quite stupid really.

Finally it decides to work -- or not, because the regex patterns were not working. i had forgotten to set Regex = True, this was probably on me. i'm still blaming it on the non-existant documentation though.

the configuration

for anyone else trying to use this script, here's what u need to get it to work.

  1. python 3.7
  2. these packages: Markdown==3.2.2, importlib-metadata<5.0
  3. a file named obsidian_to_anki_data.json with {} contents
  4. a file named obsidian_to_anki_config.ini (described below)
  5. be warned, it generates a log file named obsidian_to_anki_log.log, i put this in my gitignore

the configuration

[Custom Regexps]
Basic = ((?:[^\n][\n]?)+) #card ?\n*((?:\n(?:^.{1,3}$|^.{4}(?<!<!--).*))+)
Basic (and reversed card) = 
Basic (optional reversed card) = 
Basic (type in the answer) = 
Cloze = 
Image Occlusion = 

[Syntax]
Target Deck Line = __set:deck__
File Tags Line = __set:tags__

[Obsidian]
Vault name = 
Add file link = False

[Defaults]
Tag = Obsidian_to_Anki
Deck = Default
CurlyCloze = True
GUI = False
Regex = True
ID Comments = True
Anki Path = 
Anki Profile = 

anki vnc

This wasn't too bad to configure. i forked an existing repo, mlcivilengineer/anki-desktop-docker, patched it a little with some dependency issues, bumped the anki version, and it mostly just seems to work.

if you want to use this for yourself, get the container at quay.io/stag/anki:latest. make sure you set --security-opt seccomp=unconfined in your docker config, this fucked me over for a few days and i could not figure out what was the problem.

after you start the container, just go to addons and install ankiconnect like normal. you'll probably want to expose or publish port 8765, however you have your server setup.

the result

i can write flashcards like this:

__set:deck__: Deck Name

Card front #card
Card back

The advantage of this syntax is that in silverbullet it becomes a tag, so all my flashcards are paragraphs with the card tag. this makes using it with silverbullet's object system very nice!


email me: yx [at] stag.lol

love/hate comments: send them above

normal comments: send them below

Thoughts? Leave a comment