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).
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.
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
Parse through the tutorial or the Mastering Emacs book for functions that are mentioned and order these functions with those first.