diff options
author | Leon Rische <leon.rische@me.com> | 2020-07-16 00:50:37 +0200 |
---|---|---|
committer | Leon Rische <leon.rische@me.com> | 2020-07-16 00:50:37 +0200 |
commit | 810d52f12fd58020530478a9bccc066e10549839 (patch) | |
tree | 69e9b9773c13ec6e1085da23bdc0c17e977e9bdc | |
parent | b7d401bfd00c3bc41798ba4b8bbf6d87eb69bde5 (diff) |
Add markdown readme
-rw-r--r-- | README.md | 542 |
1 files changed, 542 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..d67a491 --- /dev/null +++ b/README.md @@ -0,0 +1,542 @@ +Org Flashcards +============== + +Spaced-repetition system for use with Emacs org-mode. + +![Review Demo](images/review.png) + +Org-fc has been tested with org-mode version 9.3.6 and gawk version +5.1.0. You can check your versions with `M-x org-version` and `gawk -V`. + +Introduction +------------ + +In the most abstract sense, this package deals with + +1. Attaching timestamped review information to headlines +2. Querying all headings where reviews are due +3. Reviewing due **positions** of headings + +As mentioned in step 3, a heading can have multiple **positions**, e.g. +to implement cloze-deletions where multiple items are reviewed +independently from each other. + +In the reviewing step, display functions can be registered by card type. +This allows easy addition of user-defined card types without having to +think about storing and updating review data. + +Review functions are called with point on the headline of the card that +should be reviewed and get passed a single argument, the position to be +reviewed. + +They are expected to return either `'quit` to end the review or one of +`'again`, `'hard`, `'good`, `'ease`, to rate the card. + +See also: + +- [Alternative Applications](doc/alternative_applications.org) +- [Incremental Reading](doc/incremental_reading.org) (todo) + +Design Goals / Choices +---------------------- + +1. Use of `awk` for quickly finding cards due for review +2. Support for multiple **positions** in a card / heading +3. All relevant data kept in org files for easy version control +4. Review directly on the source org file for easy editing of cards + during review + +See [Design Choices](doc/design_choices.org) for more information. + +Prior Art +--------- + +There are a few other packages for implementing a SRS based on org-mode. + +Below, I\'ve listed a the ones I\'ve found so far that are actively +maintained and implement a lot of useful functionality. + +- [phillord/org-drill](https://gitlab.com/phillord/org-drill/) +- [abo-abo/pamparam](https://github.com/abo-abo/pamparam) + +Other (open source) flashcard / spaced repetition software: + +- [Anki](https://apps.ankiweb.net/) +- [Mnemosyne Project](https://mnemosyne-proj.org/) + +Thanks to the maintainers and all contributors for their work on these +packages! + +Performance +----------- + +All user-facing commands (especially during review) should be as fast as +possible (\<300ms). + +Using the `awk` indexer, searching 2500 org files (\~200k lines in +total) for due flashcards takes around \~500ms on my laptop (Thinkpad +L470, SSD). + +Using the lisp indexer based on `org-map-entries`, searching a single +6500 line file with 333 flashcards takes \~1000ms, indexing the same +file with `awk` takes around \~50ms. + +Getting Started +--------------- + +Before using this package, `org-fc-directories` should be set to the +directory to search for org files containing flashcards. + +The file used to store the review history can be customized with +`org-fc-review-history-file` and defaults to +`/path/to/config/org-fc-reviews.tsv`. + +This package is not (yet) available on MELPA / ELPA, to install it, +clone the repository (e.g. to `src/org-fc/`) and follow the setup +instructions. + +### Dependencies + +- The `gawk` extension of `awk` for extracting review data from `.org` + files +- `find` for finding all org files in the `org-fc-directories` +- `xargs` for processing files in parallel + +1. Linux / UNIX + + `find` and `xargs` should be included in most distributions, `gawk` + can be installed from source or using your package manager of + choice. + + Examples: + + - `pacman -S gawk` (Arch Linux) + - `apt-get install gawk` (Ubuntu, Debian, ...) + - `yum install gawk` (CentOS) + + For more information, see [gawk manual - + Installation](https://www.gnu.org/software/gawk/manual/html_node/Installation.html). + +2. MacOS + + On MacOS all dependencies can be installed using + [macports](https://www.macports.org/) or + [homebrew](https://brew.sh/). `find` and `xargs` are part of the + `findutils` package. + + - `port install gawk findutils` + - `brew install gawk findutils` + + You might have to adjust your `$PATH` to make sure Emacs can find + all relevant binaries. + + ``` {.bash} + export PATH="/opt/local/libexec/gnubin:/opt/local/bin:$PATH" + ``` + + For more information, refer to the documentation of macports / + homebrew. + +### Setup with [use-package](https://github.com/jwiegley/use-package/) + +``` {.commonlisp org-language="emacs-lisp"} +(use-package hydra) +(use-package org-fc + :load-path "~/src/org-fc" + :custom (org-fc-directories '("~/org/")) + :config + (require 'org-fc-hydra)) +``` + +Or, using [straight.el](https://github.com/raxod502/straight.el/): + +``` {.commonlisp org-language="emacs-lisp"} +(use-package hydra) +(use-package org-fc + :straight + (org-fc + :type git :host github :repo "l3kn/org-fc" + :files (:defaults "awk" "demo.org")) + :custom + (org-fc-directories '("~/org/")) + :config + (require 'org-fc-hydra)) +``` + +Note that in this case, you don\'t have to clone the repository. + +### Setup with [straight.el](https://github.com/raxod502/straight.el/) + +``` {.commonlisp org-language="emacs-lisp"} +(straight-use-package 'hydra) +(straight-use-package + '(org-fc + :type git :host github :repo "l3kn/org-fc" + :files (:defaults "awk" "demo.org") + :custom (org-fc-directories '("~/org/")) + :config + (require 'org-fc-hydra))) +``` + +### Setup with [spacemacs](https://github.com/syl20bnr/spacemacs/) + +You don\'t need to manually clone the repository, just put this in your +`.spacemacs`: + +``` {.commonlisp org-language="emacs-lisp"} +;; ... +dotspacemacs-additional-packages +'((org-fc + :location (recipe :fetcher github + :repo "l3kn/org-fc" + :files (:defaults "awk" "demo.org")))) +;; ... +(defun dotspacemacs/user-config () + ;; ... + ;; Org-fc + (use-package hydra) + (require 'org-fc-hydra) + (setq org-fc-directories '("~/org/")) + ;; ... + ) +``` + +### Minimal Setup + +Assuming [abo-abo/hydra](https://github.com/abo-abo/hydra) is already +loaded. + +``` {.commonlisp org-language="emacs-lisp"} +(add-to-list 'load-path "~/src/org-fc/") +(setq org-fc-directories '("~/org/")) +``` + +### Demo Mode + +A file demonstrating all card types is included. `M-x org-fc-demo` +starts a review of this file. + +Card Types +---------- + +This package comes with a few predefined card types. They are documented +in [Card Types](doc/card_types.org). + +[demo.org](demo.org) includes examples for each of these types. + +Marking Headlines as Cards +-------------------------- + +A **card** is an org-mode headline with a `:fc:` tag attached to it. +Each card can have multiple **positions** reviewed independently from +each other, e.g. one for each hole of a cloze card. + +Review data (ease, interval in days, box, due date) is stored in a table +in a drawer inside the card. + +``` {.org} +:REVIEW_DATA: +| position | ease | box | interval | due | +|----------+------+-----+----------+------------------------| +| 2 | 2.65 | 6 | 107.13 | 2020-04-07T01:01:00 | +| 1 | 2.65 | 6 | 128.19 | 2020-04-29T06:44:00 | +| 0 | 2.95 | 6 | 131.57 | 2020-04-30T18:03:00 | +:END: +``` + +Review results are appended to a csv file to avoid cluttering the org +files. + +Each card needs at least two properties, an **unique** `:ID:` and a +`:FC_TYPE:`. In addition to that, the date a card was created (i.e. the +headline was marked as a flashcard) is stored to allow making statistics +for how many cards were created in the last day / week / month. + +``` {.org} +:PROPERTIES: +:ID: 4ffe66a7-7b5c-4811-bd3e-02b5c0862f55 +:FC_TYPE: normal +:FC_CREATED: 2019-10-11T14:08:32 +:END: +``` + +Card types (should) implement a `org-fc-type-...-init` command that +initializes these properties and sets up the review data drawer + +All timestamps created and used by org-flashcards use ISO8601 format +with second precision and without a timezone (timezone UTC0). + +This prevents flashcard due dates from showing up in the org-agenda and +allows filtering for due cards by string-comparing a timestamp with one +of the current time. + +(Un)suspending Cards +-------------------- + +Cards can be suspended (excluded from review) by adding a `suspended` +tag, either by hand or using the `org-fc-suspend-card` command. + +The `suspended` tag is inherited, so all cards in a subtree can be +suspended by adding the tag to the parent heading, and all cards in a +file can be suspended by adding `#+FILETAGS: suspended` at the start. + +Cards can be unsuspended using the `org-fc-unsuspend-card` command or by +manually removing the `suspended` tag. + +It might be preferable to suspend multiple cards by adding the +`suspended` tag to each one, so they remain suspended when moved to +another headline or file. + +In this case, you can use the following commands: + +- `org-fc-suspend-tree`, `org-fc-unsuspend-tree` for suspending all + cards in a subtree +- `org-fc-suspend-buffer`, `org-fc-unsuspend-buffer` for suspending + all cards in the current buffer + +Note that these commands don\'t affect filetags or tags of parent +headlines. + +Spacing Algorithm +----------------- + +This package uses a modified version of the SM2 spacing algorithm, based +on the one used by Anki. + +See also: + +- [Custom Spacing Algorithms](doc/custom_spacing_algorithms.org) + (todo) +- [Anki Manual - + Algorithm](https://apps.ankiweb.net/docs/manual.html#what-algorithm) +- [SuperMemo - SM2 + Algorithm](https://www.supermemo.com/en/archives1990-2015/english/ol/sm2) + +Review +------ + +A review session can be started with `M-x org-fc-review`. Due cards are +reviewed in random order. + +If a card was rated \"again\", it will be reviewed again at the end of +the current review session. This can be disabled by setting +`org-fc-append-failed-cards` to `nil`. + +### Review Process + +1. Open file of card +2. Narrow to heading +3. Set up card for review +4. Activate `org-fc-flip-mode` +5. Flip the card (user) +6. Switch to `org-fc-rate-mode` +7. Rate the card (user) +8. Repeat process with next due card + +### Flip Mode + + Key Binding + ----- -------------------------- + RET flip card + n flip card + s suspend card + p pause review for editing + q quit review + +### Rate Mode + + Key Binding + ----- -------------------------- + a rate again + h rate hard + g rate good + e rate easy + s suspend card + p pause review for editing + q quit review + +### See Also + +- [Review Internals](doc/review_internals.org) +- [Review History](doc/review_history.org) + +Use with `evil-mode` +-------------------- + +The key bindings used by the review modes of org-fc conflict with some +of the bindings used by evil mode. + +As a workaround, you can add minor mode keymaps for each of the +evil-mode states you\'re using org-fc with. + +``` {.commonlisp org-language="emacs-lisp"} +(evil-define-minor-mode-key '(normal insert emacs) 'org-fc-review-flip-mode + (kbd "RET") 'org-fc-review-flip + (kbd "n") 'org-fc-review-flip + (kbd "s") 'org-fc-review-suspend-card + (kbd "q") 'org-fc-review-quit) + +(evil-define-minor-mode-key '(normal insert emacs) 'org-fc-review-rate-mode + (kbd "a") 'org-fc-review-rate-again + (kbd "h") 'org-fc-review-rate-hard + (kbd "g") 'org-fc-review-rate-good + (kbd "e") 'org-fc-review-rate-easy + (kbd "s") 'org-fc-review-suspend-card + (kbd "q") 'org-fc-review-quit) +``` + +Review Contexts +--------------- + +By default, two contexts are defined: + +all +: all cards in `org-fc-directories` + +buffer +: all cards in the current buffer + +New contexts can be defined by adding them to the alist +`org-fc-custom-contexts`. + +Contexts have the form `(:paths paths :filter filter)`. + +- `:paths` (optional) either a list of paths, a single path or + `'buffer` for the current buffer. Paths don\'t have to be included + in the `org-fc-directories`. Defaults to `org-fc-directories`. +- `:filter` (optional), a card filter defaulting to a filter that + matches all cards. + +Filters can be combinations of the following expressions: + +- `(and ex1 ex2 ...)` +- `(or ex1 ex2 ...)` +- `(not ex)` +- `(tag "tag")` +- `(type card-type) or (type "card-type")` + +### Examples + +All double cards with tag \"math\": + +``` {.commonlisp org-language="emacs-lisp"} +(add-to-list 'org-fc-custom-contexts + '(double-math-cards . (:filter (and (type double) (tag "math"))))) +``` + +All cards in that don\'t have one of the tags \"foo\" and \"bar\": + +``` {.commonlisp org-language="emacs-lisp"} +(add-to-list 'org-fc-custom-contexts + '(no-foo-bar-cards . (:filter (not (or (tag "foo") (tag "bar")))))) +``` + +All cards in `~/combinatorics/` or `~/number_theory.org`: + +``` {.commonlisp org-language="emacs-lisp"} +(add-to-list 'org-fc-custom-contexts + '(math-cards . (:paths ("~/combinatorics/" "~/number_theory.org")))) +``` + +All cards in `~/combinatorics/` with tag \"theorem\": + +``` {.commonlisp org-language="emacs-lisp"} +(add-to-list 'org-fc-custom-contexts + '(combinatorics-theorems . + (:paths "~/combinatorics/" :filter (tag "theorem")))) +``` + +All double cards in the current buffer: + +``` {.commonlisp org-language="emacs-lisp"} +(add-to-list 'org-fc-custom-contexts + '(current-double . + (:paths buffer :filter (type double)))) +``` + +### Note + +Because parsing of tags is done in AWK, tag filters don\'t work for tags +defined in the `#+FILETAGS:` of a `#+SETUP_FILE:`. + +Dashboard / Statistics +---------------------- + +`org-fc-dashboard` shows a buffer with statistics for review performance +and cards / card types. + +![](images/stats.png) + +Only cards with a box \>= `org-fc-stats-review-min-box` (default: 0) are +included in the review statistics. + +Setting this to a higher value (e.g. 2) excludes the first few +\"learning\" reviews of a card. + +See also: + +- [Review History](doc/review_history.org) +- [Advanced Statistics](doc/advanced_statistics.org) (todo) + +Hooks +----- + +- `org-fc-before-setup-hook` Runs before a card is set up for review +- `org-fc-after-setup-hook` Runs after a card is set up for review +- `org-fc-after-review-hook` Runs when the review ends / is quit + +Extensions +---------- + +Org-fc comes with a number of extensions that are not enabled by +default. + +### `org-fc-audio` + +Can be enabled with `(require 'org-fc-audio)`. + +Adds audio attachments for cards that are played during review, either +before or after a card is set up. (This distinction is relevant for +text-input cards). + +Commands: + +- `org-fc-audio-set-before` +- `org-fc-audio-set-after` + +### `org-fc-keymap-hint` + +Can be enabled with `(require 'org-fc-keymap-hint)`. + +Shows a list of available key bindings during the review, to recreate +the look & feel of the previous hydra-based implementation. + +- `[RET] flip [q] quit [s] suspend-card` +- `[a] rate-again [h] rate-hard [g] rate-good [e] rate-easy [s] suspend-card [q] quit` + +### `org-fc-hydra` + +[file:org-fc-hydra.el](org-fc-hydra.el) defines a hydra for accessing +commonly used org-fc commands and for marking headlines as flashcards. + +It can be loaded and bound to a hotkey like this: + +``` {.commonlisp org-language="emacs-lisp"} +(require 'org-fc-hydra) +(global-set-key (kbd "C-c f") 'org-fc-hydra/body) +``` + +[Changelog](Changelog.org) +-------------------------- + +Other Documentation +------------------- + +- [Internals](doc/internals.org) +- [Sharing Decks](doc/sharing_decks.org) (todo) + +License +------- + +Copyright © Leon Rische and contributors. Distributed under the GNU +General Public License, Version 3 |