This manual is for Inline Anki version 0.3.7.
Copyright (C) 2023-2024 Martin Edström <[email protected]>
You can redistribute this document and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Not yet on (M)ELPA. If you have straight.el, you can install the package with this initfile snippet:
(use-package inline-anki
:straight (inline-anki :type git :host github :repo "meedstrom/inline-anki"))
Alternatively with Doom Emacs, this goes in packages.el
:
(package! inline-anki :recipe (:host github :repo "meedstrom/inline-anki"))
Below, you’ll find a recommended config snippet for Org-mode. It lets you quickly create a #+begin_flashcard
block at point with the C-c , key (org-insert-structure-template
).
(with-eval-after-load 'org
(add-to-list 'org-structure-template-alist '("f" . "flashcard")))
Your only direct interaction with this package is one command that you would run every once in a while (weeks? months? depends on you) to update the Anki database.
To update the Anki database:
- Make sure Anki has the AnkiConnect add-on installed
- Make sure you have
curl
installed - Start Anki
- From your Org file, type
M-x inline-anki-push-notes-in-buffer RET
- Or push from all Org files in the current directory and its subdirectories, by typing
M-x inline-anki-push-notes-in-directory RET
- Or push from all Org files in the current directory and its subdirectories, by typing
You may like to know that:
- When you upload a note, it overwrites that note in Anki. Any edits made inside Anki will be forgotten! The only thing Anki gets to remember about a note is the review schedule.
- As a convenience, if you comment-out a note expression, the next push will tell Anki to suspend all the cards for that note.
- If you later uncomment it, the next push will unsuspend them.
- Note that you can still follow a workflow of suspending cards during your review sessions. I consider it a psychological boon that Anki will forget these suspends on the next push, forcing you to revise all the bad notes you found before you can push again.
- Just remember to look up the suspends inside Anki but edit in the corresponding source Org file.
- There’s a bit of a gimmick: if a note has 3 clozes, and you study it a bit, and later you remove the first cloze, the second and third cloze cards will inherit the scheduling of the first and second. So technically, you can have cards that aren’t scheduled faithfully to the algorithm, and failure statistics may be referring to a cloze card that you’ve removed.
- Up to you whether to care, but in my opinion, it changes nothing in practice.
- No surprise to experienced Anki-users, but the third field’s original scheduling will be attached to an empty card. Remember that you can clean up empty cards with the menu option “Check database…”.
inline-anki-deck
- Default “Default”.
inline-anki-note-type
- Default “Cloze from Outer Space”.
inline-anki-emphasis-type
- Default “_”, can be changed to “*”, “/” or other things you find in
org-emphasis-alist
.
- Default “_”, can be changed to “*”, “/” or other things you find in
inline-anki-send-tags
- Default
nil
. Controls whether or not to put a note’s Org tags in the Anki note tags. Can be an allowlist like("tag1" "tag2")
or a blocklist like(not "tag1" "tag2")
. Valuet
sends all tags. - A benefit with the
nil
value is faster upload if you have hundreds of Org files.
- Default
inline-anki-ignore-file-regexps
- Helps the command
inline-anki-push-notes-in-directory
decide whether or not to visit a file. If that file’s full name matches one of the regular expressions in this list, skip the file.
- Helps the command
inline-anki-fields
- See docstring.
You must not hard-wrap your text (e.g. with M-q, fill-paragraph
) if you want Anki to receive the whole flashcard.
It would be convenient if you could click a link in Anki to open the corresponding Org file in Emacs.
By default, inline-anki-fields
ships an extra field that shows the filename the note came from. With addons such as https://ankiweb.net/shared/info/879473266, it should be possible to jump from Anki to Emacs using emacsclient. Instructions TBD.
If you switch inline-anki-emphasis-type
to bold or italic, remember to edit all the cards you had written!
Tips:
- To search the current buffer for flashcards, type
M-x inline-anki-occur RET
. - To search every file in the directory, type
M-x inline-anki-rgrep RET
.- Then you can edit all at once with wgrep or a keyboard macro, for example.
- The wgrep method won’t cut it for multiline flashcards, as you’ll see, but if you don’t have many of those, you could simply hand-edit each. If you have many, try a keyboard macro.
- Then you can edit all at once with wgrep or a keyboard macro, for example.
There are three flaws which will never go away:
- Flaw 1: Like anki-editor, inline-anki does not let you review inside Emacs. You have to review in your Anki app.
- Flaw 2: Like with anki-editor, your Org files hold the “master copy” of each flashcard: you cannot edit the cards from within Anki. If you tried, such edits would be lost on next sync.
You have to return to your computer and edit there, in Emacs.
- This means you can’t make small corrections on-the-fly while reviewing.
Bit annoying, yes, but two-way sync is a notoriously finicky dev challenge so if such a feature was present, users would run into sync conflicts and nobody wants to deal with that.
- Fortunately, this is less of a problem for us than for regular Anki users, since the flashcards are serving double duty as body text. You will be able to see and refine the text of the flashcard at your leisure, when not reviewing, in contrast with other SRS when you only see it during review.
- This means you can’t make small corrections on-the-fly while reviewing.
- Flaw 3: The note format is constrained – you can’t express every kind of flashcard possible in Anki.
- For me this is a good trade, if that means the flashcards stay in my life. Until now, they never stayed long because Anki was too separated from my notes.
Many traditional features are ABSENT in inline-anki.
- It uses only one deck
- It uses only one note type (cloze)
- It clozes only one deletion at a time
- You cannot set tags on a per-note basis
- The note will still inherit tags from the Org subtree
- Note that Anki tags lose much of their organizational purpose if your notes primarily live in Org files anyway – you’ll be organizing them from within org-node or whichever system you have for browsing Org files, not from within Anki. However, at least two use-cases remain:
- You can display the tags inside cards as a contextual hint, if you code this in the card template
- You can use the tags to set up Custom Study sessions on a filtered subset of notes
- Invaluable since we dump all notes into one deck
- Finally, even if you leave
inline-anki-send-tags
at nil, inline-anki always attaches one tag named after the sync date, in this style: “from-emacs-2023-09-20”- This tag lets you separate inline-anki notes from your “handmade” notes
- This tag lets you see if you have stale inline-anki notes that aren’t being updated (perhaps because you deleted them from the source)
- Note that Anki tags lose much of their organizational purpose if your notes primarily live in Org files anyway – you’ll be organizing them from within org-node or whichever system you have for browsing Org files, not from within Anki. However, at least two use-cases remain:
- The note will still inherit tags from the Org subtree
- You get no indication in Emacs that Anki has flagged a card as “Marked” or “Leech”
- You can still see this in Anki’s own card browser, so you can still sit down and go through them manually every now and then – just like a normal Anki user, with the difference that when you see something that needs to change, you have to open the source file in Emacs and edit there.
- To identify a flashcard, inline-anki looks for one of the following things:
- A magic string at the start of a list item:
@anki
.- When Anki assigns it an ID, this will become a @ glyph followed by a 13-digit number in superscript, such as
@^{1693535436701}
.
- When Anki assigns it an ID, this will become a @ glyph followed by a 13-digit number in superscript, such as
- A magic string at the end of a line:
@anki
OR^{anki}
.- Same as above, except that you can omit the @ glyph.
- Since the
@anki
form is easier to remember and easier to type, I suggest you just always type that and remove the glyph later where you think its absence looks better.
- Since the
- Same as above, except that you can omit the @ glyph.
- A structure template named
#+begin_flashcard
.- When Anki assigns it an ID, it becomes something like
#+begin_flashcard 1693535436702
.
- When Anki assigns it an ID, it becomes something like
- A magic string at the start of a list item:
- Clozes are marked by underline text. If you prefer bold or italic, configure
inline-anki-emphasis-type
.- If necessary, you can write Anki’s own
{{c1::}}
syntax directly. Best I can tell, it’s mainly useful for writing math equations. However that makes the source unreadable/ugly, so you may as well do math in Anki only for now.
- If necessary, you can write Anki’s own
- Can I continue using my [org-drill/org-anki/…] cards?
- Yes! Those packages treat whole Org subtrees as their “data objects”, and this package does not. You can even have an inline-anki card inside an org-anki subtree.