Writing Anki flashcards on the reMarkable 2

In my opinion, the reMarkable 2 is a great device for distraction-free reading/writing tasks. To make use of spaced repetition learning, I wanted to be able to write flashcards on it and then have them show up in Anki.

The idea

Each page of the notebook looks like this:

The flashcard template with two rectangles labeled 'front' and 'back'.
Template for flashcard creation

Then you can fill out both “sides” of a card on a single page. The front will show up as a question in Anki, the back as the answer. So far so easy. It is possible to include media files in Anki cards.

Implementation

My requirements were two-fold:

  1. The vector images must be preserved, no rendering into blurry PNGs.
  2. The image should be saved as space-efficiently as possible.

The second point is more difficult to achieve. Cropping an SVG is a non-trivial task, because the extent of primitives on the canvas is hard to tell and overlapping primitives would have to be clipped. This would have been a lot of complexity to include in such a simple project.

The solution turned out to be quite simple and in hindsight it is obvious. Instead of trying to crop the image during deck creation, simply include its entirety as media file in the package and select the viewport at runtime with HTML. This is best done by nesting the SVG inside yet another <svg> tag and setting the viewport accordingly. Sadly, Anki does not recognize images that are included inside <svg>s, so after tinkering around with CSS for a bit I created a stylesheet that crops the image through relative positioning with negative left and top values.

One nice thing I encountered is the fact that both notebooks and pages on the reMarkable have UUIDs. By transforming them into 64-bit integers for use in the Anki database, they are directly mapped, meaning edits to pages get picked up correctly.

Thanks to two great libraries, genanki_rs and lines_are_rusty, I was able to implement the whole thing in a day or two!

Automating it

The following script is what I use to synchronize the cards. It uses rmapi to find all notebooks named Flashcards and creates an Anki deck named after the folder they are contained in. Finally, it uses the AnkiConnect API to import the package into Anki itself.

#!/bin/zsh
if [[ ! -d notebooks ]]; then
    mkdir notebooks
fi
files=$(rmapi find Studium Flashcards \
        | grep -F '[f]' | cut -d' ' -f2- > index.txt)

IFS=$'\n'
cd notebooks
for file in $(<../index.txt); do
    name=$(echo $file | awk -F/ '{print $(NF-1)}')
    rmapi get $file 
    mv Flashcards.zip $name.zip
done
cd ..
./AnkiSync --name-from-filename flashcards.apkg notebooks/*.zip
curl -X POST -d '{"action": "importPackage", "version": 6, "params": {"path": "'$(pwd)'/flashcards.apkg"}}' \
    http://localhost:8765/

I’ll admit that this solution is not as clean as it could be. It requires manually running the script for new cards to get picked up. Ideally, this would be a webservice that connects the reMarkable API to the Anki API and updates your Anki Decks as soon as you edit your notebook.

I made a second version of the script that syncs the notebooks with SSH over USB instead, so that I can update without uploading it to a cloud server first.

Two screenshots displaying a handwritten flashcard on the difference between translation and transversions of nucleotide sequences
An example flashcard as displayed in the AnkiDroid app

Conclusion

The setup works quite well. I can easily write flashcards during a lecture and revise them on my phone or laptop later on.

The code for rm2anki is available on GitHub.

Comments

To add a comment, write an email with this link.