Elilif / emacs-anki-helper

Manage your Anki cards in Emacs.
30 stars 3 forks source link
anki emacs-package

anki-editor requires the use of dedicated header lines to mark the front and back sides of the cards. This first leads to the inability to quickly convert existing notes into cards, requiring manual conversion; secondly, the created cards can only be used by anki-editor and cannot be integrated into existing workflows, requiring a dedicated file to store them.

org-anki solves the above shortcomings well. It uses the headline as the front side and its content as the back side. But org-anki has its own drawbacks: ** Speed Taking [[examples/headings.org]] as an example, the time comparison for synchronizing and deleting all cards (422 in total) between org-anki and anki-helper is as follows:

| | (benchmark 1 '(xxx-sync-all)) | (benchmark 1 '(xxx-delete-all)) | |-------------+-----------------------------------+-----------------------------------| | org-anki | 123.855104s (35.423518s in 5 GCs) | 150.862886s (21.709634s in 8 GCs) | | anki-helper | 0.410945s | 0.098308s | ** Customizability Another issue with the org-anki is that it only applies to entries and does not provide an API for adding custom card-making functions. One advantage of having one card per entry is that it can save card information, such as card ID and whether it has been modified, making it convenient for future modifications. Another advantage is that different operations can be performed on different entries. However, some types of cards do not require this type of additional information, such as vocabulary cards. I only need to collect new words and then synchronize them with Anki, with very few modifications afterwards. Obviously, having one entry per word is quite wasteful.

The org-anki supports only two ways of filling fields: one is using the title line as the front side of the card and the content as the back side; the other is using subheadings to differentiate fields. The latter approach is similar to anki-editor. The problem here is that everyone has different habits and custom templates can be very diverse, so it is necessary to provide a set of flexible APIs to facilitate users in creating their own field filling functions. ** Support for media file The PR for image processing of org-anki has not been merged yet, and other multimedia content is also not supported.

anki-helper supports including images and audio file links in cards. These original files will be copied to the media folder of Anki. ** Respect original text For Cloze type cards, the usual practice is to use the format ~{{c1:xxx}}~, but this will disrupt the original content and is not conducive to other operations. This is actually a kind of exclusivity.

Anki-helper uses the built-in rich text markup of org-mode as the indicator for cloze deletion. Assuming we have the following text:

+begin_example

,Canberra was founded in 1913.

+end_example

will be converted into the following format while exporting to Anki:

+begin_example

{{c1::Canberra}} was founded in {{c2::1913}}.

+end_example

Note: Following cloze deletions are not supported for now.

+begin_example

{{c1::Canberra}} was founded in {{c1::1913}}.

+end_example

  1. ~anki-helper-default-note-type~

    Default note type.

  2. ~anki-helper-default-deck~

    Default deck name.

  3. ~anki-helper-default-tags~

    Default note tags.

  4. ~anki-helper-default-match~

    A tags/property/todo match as it is used in the agenda tags view.

    Only headlines that are matched by this query will be considered during the iteration. See [[https://orgmode.org/manual/Matching-tags-and-properties.html][Matching tags and properties (The Org Manual)]] .

    This variable will be used if none is set on the org item nor as global property.

  5. ~anki-helper-skip-function~

    Function used to skip entries.

  6. ~anki-helper-inherit-tags~

    Inherit tags, set to nil to turn off.

  7. ~anki-helper-media-directory~

    Default Anki media directory.

  8. ~anki-helper-note-types~

    Default fields for note types. *** file-local variables

  9. ~#+ANKI_DECK:~
  10. ~#+ANKI_MATCH:~
  11. ~#+ANKI_NOTE_TYPE:~
  12. ~#+ANKI_TAGS:~

The above keywords correspond to their respective global variables.

For instance, suppose you have the following org file:

+begin_example

+ANKI_DECK: Default

+ANKI_MATCH: TODO="TODO"|+DATE="today"

+ANKI_NOTE_TYPE: Basic

+ANKI_TAGS: test

, test note 1 back side , TODO test note 2 back side , test note 3 :PROPERTIES: :DATE: today :END: back side , test note 4 back side

+end_example

Then ~anki-helper-entry-sync-all~ will only create notes for =test note 2= and =test note 3= *** Properties

  1. ~ANKI_NOTE_TYPE~
  2. ~ANKI_DECK~

Each entry can have its own properties. The priority of the variables mentioned above is ~Properties > file-local variables > global variables~. ** Cards that are entries A series of functions are provided by default to operate on cards of the entry type (more operations will be added later): *** Functions

  1. ~anki-helper-entry-sync~

    Turn the entry under the cursor into a card, if it is already a card, ignore it.

  2. ~anki-helper-entry-sync-all~

    Create cards for all entries in the current buffer that meet the condition, and ignore those that are already cards.

  3. ~anki-helper-entry-delete~

    Delete the entry under the cursor if it is a card and meets the condition.

  4. ~anki-helper-entry-delete-all~

    Delete all cards in the current buffer that meet the specified condition.

  5. ~anki-helper-entry-update~

    Update the entry under the cursor if it is a card and is modified.

  6. ~anki-helper-entry-update-all~

    Update all cards in the current buffer that are modified.

  7. ~anki-helper-entry-browse~

    Browse entry at point on Anki's browser dialog with searching nid.

** Card that are not entries. anki-helper provides several APIs:

  1. ~anki-helper-request~
  2. ~anki-helper-create-note~
  3. ~anki-helper-create-notes~

Please refer to the function documentation for specific usage details.

As an example, you can refer to the functions =anki-helper-set-front-region= and =anki-helper-make-two-sided-card=, which provide an interactive card-making method:

[[examples/make-card-interactively.gif]] ** Misc

  1. ~anki-helper-find-notes~

    Invokes the Card Browser dialog and searches for a given QUERY.

~anki-helper-fields-get-alist~ sets two basic filed-filling functions:

  1. ~anki-helper-fields-get-alist~

    This function is used for the "Bacis" note type of Anki, which use the raw value of the headline as the front and the content of the entry as the back.

  2. ~anki-helper-fields-get-cloze~

    This functions is used for the "Cloze" note type of Anki, which use the content of the entry to fill the "Text" field and use the raw value of the headline to fill the "Back Extra" field. ** Modify callback functions See ~anki-helper-callback-alist~ for details.