/emacs-anki-deck

Generate Anki deck for memorizing Emacs functions

A way of genrating an anki flashcard deck for the definition of every Emacs function.

This is my first project using ChatGPT as a significant coding assistant

This is an org file. It is best viewed with emacs but you can view it in raw mode on github or any text editor. The code runs in emacs with basic org-mode set up (tested with spacemacs).

Generate Anki

First there’s an Anki script to generate a csv of all terms and definitions. This takes me around 10 seconds to run.

(require 'cl-lib)
(require 'csv)
(require 'rx)
(require 's)
(require 'request)

(defun gim/entirely-surrounded-by-parens? (str)
  (s-matches? (rx bol ?\( (0+ anything) ?\) eol) str))

(defun gim/filter-double-hyphen (sym)
  "Return non-nil if the symbol SYM is a function and its name doesn't contain a double hyphen."
  (not (s-contains? "--" (symbol-name sym))))

(defun gim/get-doc-comment (sym)
  "Return the doc comment of the function SYM if it exists."
  (condition-case nil
      (when-let* ((full-doc (documentation sym))
                  (doc (s-trim full-doc)))
        (and (not (s-equals? "Not documented" doc))
             (not (gim/entirely-surrounded-by-parens? doc))
             doc))
    (void-function nil)))

(defun gim/collect-functions-and-docs ()
  "Return a list of pairs (function-name . doc-string) for functions without double hyphens."
  (->> (cl-loop with doc = nil
                for sym being the symbols
                when (fboundp sym)
                when (gim/filter-double-hyphen sym)
                when (setq doc (gim/get-doc-comment sym))
                collect (cons (symbol-name sym) doc))
       (--sort (string< (car it) (car other)))))

(defun gim/csv-quote-field (data)
  (format "\"%s\"" (s-replace-all
                    '(("\"" . "\"\"")
                      ("\n" . "\\n"))
                    data)))


(defun gim/write-terms-and-definitions-to-csv (alist filename)
  "Write the contents of ALIST (terms . doc) to filename"
  (with-temp-buffer
    (-each alist (-lambda ((term . docs))
                    (insert (format "%s, %s\n" (gim/csv-quote-field term) (gim/csv-quote-field docs)))))
    (write-file filename)))

(gim/write-terms-and-definitions-to-csv (gim/collect-functions-and-docs) "output/terms-definitions.csv")

ChatGPT got me starated but the above required about 60 minutes of rewriting and debugging.

Generate Anki Deck

Set up your python venv by running a poetry install (this assumes you have pyenv with poetry installed in it, otherwise setup the poetry venv how you normally would).

(async-shell-command "pyenv exec poetry install")
from csv import reader, QUOTE_ALL
import genanki

deck_id = 4538789202339

def _read_csv(file_path):
    terms = []
    with open(file_path, mode='r') as csvfile:
        rd = reader(csvfile, quotechar='"', delimiter=',', quoting=QUOTE_ALL, skipinitialspace=True)
        for term, definition in rd:
            terms.append((term, definition))
    return terms

def _escape_for_anki(string):
    # This character causes problems when imported into anki. Escape it.
    return string.replace('\x1f', '\\x1f')

def create_anki_deck(terms):
    my_model = genanki.Model(
        deck_id,
        'Terms and Definitions',
        fields=[
            {'name': 'Term'},
            {'name': 'Definition'},
        ],
        templates=[
            {
                'name': 'Term to Definition',
                'qfmt': '{{Term}}',
                'afmt': '{{FrontSide}}<hr id="answer">{{Definition}}',
            },
        ])

    deck = genanki.Deck(
        deck_id,
        'Emacs Functions and Definitions')

    for term, definition in terms:
        note = genanki.Note(
            model=my_model,
            fields=[term, _escape_for_anki(definition)])
        deck.add_note(note)

    genanki.Package(deck).write_to_file('output/emacs-terms-and-definitions.apkg')

csv_file_path = 'output/terms-definitions.csv'
terms = _read_csv(csv_file_path)
create_anki_deck(terms)

Then import into anki (this is on macos)

open /Applications/Anki.app output/emacs-terms-and-definitions.apkg

Future work

Parse through the tutorial or the Mastering Emacs book for functions that are mentioned and order these functions with those first.