org-mode-incremental-reading icon indicating copy to clipboard operation
org-mode-incremental-reading copied to clipboard

SuperMemo inspired incremental reading for org-mode and Anki

#+title: Incremental Reading + Anki for org-mode

Incremental Reading is a feature of SuperMemo (the beginning of Spaced Repetition Software) where you breakdown an article into small parts and then use that to learn/memorize the contents.

Anki is an open-source software for Spaced Repetition where you create flashcards and then learn them.

There is already a package to connect org-mode to Anki and create flashcards based on a specific tree structure. The package is called ~anki-editor~.

However, not all notes follow that tree structure. Also, instead of separating the notes from the flashcards, it would be better to create a block right below the notes that would then be sent to Anki. This way you won't ever forget to update the flashcards when you update the notes.

This is an example of how the flashcards work:

#+BEGIN_SRC org ,#+title: Return Over Investment

Return Over Investment or ~ROI~ is a measure of how well is the investment of a company going.

  • Tags ::
    • [[id:e1c36403-ba59-45e7-915f-9dd354271ae2][Accounting]]

The ROI is made up of two [[id:c53ffe1e-e390-482f-8f13-e857faf58d38][Metric]]:

  • Net profit over a period of time,
  • Cost of investment

:ANKI-CARD: ,#+ATTR_ID: 1631303347034 ,#+ATTR_DECK: Test ,#+ATTR_TYPE: Cloze ,#+ATTR_TAGS: incremental-reading emacs ,#+BEGIN_ANKI org ,#+ATTR_FIELD: Text ,#+BEGIN_FIELD {{c1::Return Over Investment or ~ROI~::Formula}} is a measure of how well the investment of a company is going. ,#+END_FIELD ,#+END_ANKI :END:

,* Common formula

$$ROI = \frac{(G - C)}{C}$$

In this formula, ~G~ represents the financial gains you expect from the project, and ~C~ represents the up front and ongoing costs of your investment in the project.

:ANKI-CARD: ,#+ATTR_ID: 1631303346989 ,#+ATTR_DECK: Test ,#+ATTR_TYPE: Basic ,#+ATTR_TAGS: incremental-reading emacs ,#+BEGIN_ANKI org ,#+ATTR_FIELD: Front ,#+BEGIN_FIELD Return Over Investment formula ,#+END_FIELD

,#+ATTR_FIELD: Back ,#+BEGIN_FIELD $$ROI = \frac{(G - C)}{C}$$

In this formula, ~G~ represents the financial gains you expect from the project, and ~C~ represents the up front and ongoing costs of your investment in the project. ,#+END_FIELD ,#+END_ANKI :END: #+END_SRC

The template of an Anki card is the following:

#+BEGIN_SRC :ANKI-CARD: ,#+ATTR_DECK: Test ,#+ATTR_TYPE: Cloze ,#+ATTR_TAGS: incremental-reading emacs ,#+BEGIN_ANKI org ,#+ATTR_FIELD: Text ,#+BEGIN_FIELD ,#+END_FIELD

,#+ATTR_FIELD: Back Extra ,#+BEGIN_FIELD ,#+END_FIELD ,#+END_ANKI :END: #+END_SRC

This way all the cards will be in the same place of the notes and can easily be updated and sent to Anki to learn.

  • Installation

To install this back-end, clone this repo into your packages or private folder in your ~~/.emacs.d~ directory. Or use your package manager. For example, ~straight.el~:

#+BEGIN_SRC emacs-lisp (straight-use-package '(org-mode-incremental-reading :type git :host github :repo "vascoferreira25/org-mode-incremental-reading")) #+END_SRC

In case your package manager doesn't install dependencies, also install the following packages:

  • ~anki-editor~
  • ~request~

To configure org-protocol (for going back to the context immediately when reviewing anki cards), you should:

  1. Follow the guide to setup your ~org-protocol~ in [[https://orgmode.org/worg/org-contrib/org-protocol.html#org636b514][org-protocol.el]].

  2. Add the following code into your ~.emacs~. (Thanks [[https://org-roam.discourse.group/t/org-roam-and-anki/589/4][@telotortium]])

    #+begin_src emacs-lisp ;; org-protocol support for opening a file - needed for ‘my-anki-editor-backlink’. (add-to-list 'org-protocol-protocol-alist '("org-open-file" :protocol "open-file" :function org-protocol-open-file)) (defun org-protocol-open-file (fname) "Process an org-protocol://open-file?url= style URL with FNAME. Change a filename by mapping URLs to local filenames as set in `org-protocol-project-alist'. The location for a browser's bookmark should look like this: javascript:location.href = \='org-protocol://open-file?url=\=' + \ encodeURIComponent(location.href)" ;; As we enter this function for a match on our protocol, the return value ;; defaults to nil. (let ((f (org-protocol-sanitize-uri (plist-get (org-protocol-parse-parameters fname nil '(:file)) :file)))) f)) #+end_src

Start ~incremental-reading-mode~ when opening an org file by using hooks (This was sugested by @czqhurricnae):

#+begin_src (add-hook 'org-mode-hook #'incremental-reading-mode) (add-hook 'incremental-reading-mode-hook #'anki-editor-mode) #+end_src

  • How to use

In the case you don't want to use hooks to start ~incremental-reading~ upon opening an org file, load ~incremental-reading-mode~.

These are the steps to add/update/extract cards from org-mode into Anki:

  1. Go to your notes and either use snippets to create a block or use the ~incremental-reading-extract-basic~ or ~incremental-reading-extract-cloze~ to extract the text and turn it into a card.
    • Set the ~incremental-reading-default-deck~ and ~incremental-reading-default-tags~ so you won't need to change them after extracting your notes.
    • For ~cloze~ cards don't forget to create a cloze with ~anki-editor-cloze-region~.
  2. Open Anki and make sure you have the ~anki-connect~ add-on.
  3. Use the function ~incremental-reading-parse-cards~.

Note 1: almost always, the first time you try to parse the cards after loading Emacs, it will fail. Try again and it will work. If a ~#+ATTR_ID: nil~ appears, remove it and try again. A ~nil~ id usually appears when something wrong happened when trying to send the data to anki.

Note 2: sometimes errors occur when sending attachments (images and files) to Anki. When that happens, remove the image, parse the cards, add the image again and parse.

Note 3: If you are using a language other than english, then you also need to use the correct language in the names of the card types and fields. For example, in french, the card template should look like this:

#+begin_src ,#+ATTR_DECK: Test ,#+ATTR_TYPE: Généralités (deux sens) ,#+ATTR_TAGS: incremental-reading emacs ,#+BEGIN_ANKI org ,#+ATTR_FIELD: Recto ,#+BEGIN_FIELD Recto text ,#+END_FIELD

,#+ATTR_FIELD: Verso ,#+BEGIN_FIELD Verso text ,#+END_FIELD ,#+END_ANKI #+end_src

Note 4: a link to the original context in your Emacs will be automatically appended into the anki card, which will only work when you are using anki cards in the computer you made it as it is where you have Emacs and the file. This is how it looks:

[[./img/example_source.png]]

  • How does it look like?

In this image you can see how the card looks like when using an overlay to hide extra info of the card.

[[./img/overlay.png]]

With and without overlay:

[[./img/overlay2.gif]]

[[./img/example_1.png]]

[[./img/example_2.png]]

[[./img/example_3.png]]

[[./img/example_4.png]]

[[./img/example_5.png]]

[[./img/example_6.png]]

  • Thank you for your contributions
  • [[https://github.com/colawithsauce][colawithsauce]]
  • [[https://github.com/czqhurricnae][czqhurricnae]]