From 684cf7435f446fd8b90fe0bffae74726b3a75f7d Mon Sep 17 00:00:00 2001 From: Leon Rische Date: Tue, 27 Sep 2022 20:23:37 +0200 Subject: Add documentation files --- docs/alternative_applications.org | 16 +++ docs/cache.org | 84 +++++++++++++++ docs/card_types.org | 115 ++++++++++++++++++++ docs/components.org | 66 ++++++++++++ docs/customizing_org-fc.org | 14 +++ docs/dashboard.org | 15 +++ docs/differences_from_other_flashcard_systems.org | 37 +++++++ docs/extensions.org | 36 +++++++ docs/hydra.org | 6 ++ docs/incubator.org | 18 ++++ docs/index.org | 66 ++++++++++++ docs/installation.org | 123 ++++++++++++++++++++++ docs/introduction.org | 53 ++++++++++ docs/marking_headings_as_cards.org | 47 +++++++++ docs/performance.org | 14 +++ docs/repetition_spacing_algorithm.org | 6 ++ docs/review.org | 102 ++++++++++++++++++ docs/review_contexts.org | 65 ++++++++++++ docs/review_history.org | 23 ++++ docs/suspending_cards.org | 27 +++++ docs/use_with_evil-mode.org | 48 +++++++++ 21 files changed, 981 insertions(+) create mode 100644 docs/alternative_applications.org create mode 100644 docs/cache.org create mode 100644 docs/card_types.org create mode 100644 docs/components.org create mode 100644 docs/customizing_org-fc.org create mode 100644 docs/dashboard.org create mode 100644 docs/differences_from_other_flashcard_systems.org create mode 100644 docs/extensions.org create mode 100644 docs/hydra.org create mode 100644 docs/incubator.org create mode 100644 docs/index.org create mode 100644 docs/installation.org create mode 100644 docs/introduction.org create mode 100644 docs/marking_headings_as_cards.org create mode 100644 docs/performance.org create mode 100644 docs/repetition_spacing_algorithm.org create mode 100644 docs/review.org create mode 100644 docs/review_contexts.org create mode 100644 docs/review_history.org create mode 100644 docs/suspending_cards.org create mode 100644 docs/use_with_evil-mode.org diff --git a/docs/alternative_applications.org b/docs/alternative_applications.org new file mode 100644 index 0000000..82c872e --- /dev/null +++ b/docs/alternative_applications.org @@ -0,0 +1,16 @@ +#+TITLE: Alternative Applications +#+DATE: [2020-07-17 Fri 00:25] +#+KEYWORDS: fc + +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 + +While the primary application is learning information using spaced +repetition, at the end, the API should be flexible enough to implement +other kinds of repeating tasks where it is necessary to store data in +addition to the next date. + +Some ideas are collected in the [[file:incubator.org][Incubator]]. diff --git a/docs/cache.org b/docs/cache.org new file mode 100644 index 0000000..234ab9d --- /dev/null +++ b/docs/cache.org @@ -0,0 +1,84 @@ +#+TITLE: Cache +#+DATE: [2020-07-29 Wed 11:58] +#+KEYWORDS: fc + +* Motivation +Even with the AWK based indexer, indexing cards before each review +gets slow if there are a lot of files / cards. + +To work around this, the indexer can be run only one time, +caching the results in a hash table. + +Advises are added to `delete-file' and `rename-file' +remove / update keys from the hash table. + +Changes to existing files & new files are detected with a +~before-save-hook~ on org-mode files. + +During a review many files are changed and saved. To keep this as +fast as possible, instead of re-processing files after each save, +changed files are collected in `org-fc-cache-queue' and reprocessed in +bulk the next time the cache is accessed. + +Assuming only a small subset of the flashcard files is changed between +reviews, this is much faster than building the full index ch time. + +* Activation +Caching can be activated/deactivated with ~M-x org-fc-cache-mode~. + +To activate this mode when Emacs starts, +activate it in your configuration: + +#+begin_src emacs-lisp +(org-fc-cache-mode) +#+end_src +* Performance +** Setup +#+begin_src fish :exports results +echo (org-files | xargs grep ":fc:" | wc -l) " cards" +echo (org-files | wc -l) " files" +org-files | xargs wc -l | tail -n 1 | sed "s/total/lines/g" +#+end_src + +#+RESULTS: +| 18348 | cards | +| 2478 | files | +| 475860 | lines | +** Benchmarks :noexport: +#+begin_src emacs-lisp + (defun my-org-fc-cache-benchmarks () + (list + (list "Dashboard" (benchmark 1 '(org-fc-dashboard 'all))) + (list "Index Cards in Subdirectory" (benchmark 1 '(length (org-fc-index '(:paths "~/org/deft/"))))) + (list "Index Cards with Tag" (benchmark 1 '(length (org-fc-index '(:filter (tag "spanish")))))))) +#+end_src + +#+RESULTS: +: my-org-fc-cache-benchmarks + +** AWK +#+begin_src emacs-lisp :exports results +(let ((org-fc-index-function #'org-fc-awk-filter-index)) + (my-org-fc-cache-benchmarks)) +#+end_src + +#+RESULTS: +| Dashboard | Elapsed time: 3.642393s | +| Index Cards in Subdirectory | Elapsed time: 0.502262s | +| Index Cards with Tag | Elapsed time: 3.266725s (0.244461s in 1 GCs) | +** Cache +#+begin_src emacs-lisp :exports results + (let ((org-fc-index-function #'org-fc-cache-filter-index)) + (cons + (list "Initial Cache Build" (benchmark 1 '(org-fc-cache-build))) + (my-org-fc-cache-benchmarks))) +#+end_src + +#+RESULTS: +| Initial Cache Build | Elapsed time: 2.982310s | +| Dashboard | Elapsed time: 0.673869s | +| Index Cards in Subdirectory | Elapsed time: 0.026792s | +| Index Cards with Tag | Elapsed time: 0.040647s | + +Dashboard performance will be improved once a card's review history is +cached, too. diff --git a/docs/card_types.org b/docs/card_types.org new file mode 100644 index 0000000..004bb17 --- /dev/null +++ b/docs/card_types.org @@ -0,0 +1,115 @@ +#+TITLE: Card Types +#+DATE: [2020-08-01 Sat 10:49] +#+KEYWORDS: fc + +* Normal Cards +During review, the heading is shown with its "Back" subheading +collapsed, when flipping the card, the back heading is shown, +then the user is asked to rate the review performance. + +Positions: =front= +* Text-Input Cards +If the card has a "Back" heading, the first line of its contents is +considered as the expected answer. + +If the card is compact (has no back heading), the first line of its +main content is used instead. + +This allows adding an e.g. explanation to the card. + +Answers can be emphasized (e.g. ~foo~). In that case, only the text +between the emphasis markers is compared to the user input. + +On reviewing the card, the users are prompted to enter their answer, +which is then compared to the expected answer. + +The expected answer is overlayed with " (expected: )", +coloring correct parts in green and incorrect parts in red. + +If the provided answer is shorter than the expected one, a sequence of +=-= (colored in red) is prepended / appended to it. + +This filler character can be customized via ~org-fc-diff-missing-char~. + +Positions: =front= +* Double Cards +Similar to normal cards, but reviewed both in the "Front -> Back" +direction and in the "Back -> Front" direction. + +Positions: =front=, =back= +* Cloze Cards +The cards text contains one or more *holes*. During review, one hole +is hidden while the text of (some) remaining ones is shown. + +Flipping the card reveals the text of the hidden hole, +using ~org-fc-type-cloze-hole-face~ to highlight it. + +Card titles can contain holes, too. + +Positions: =0=, =1=, ... + +Cloze cards can have a number of sub-types. + +** Deletion ~'deletion~ +Only one hole is hidden. +** Enumerations ~'enumeration~ +All holes *behind* the currently review one are hidden, too. + +Useful for memorizing lists where the order of items is important. +** Single ~'single~ +All holes besides the current one are hidden. + +Useful for learning syntax or function names of a programming language +by using a =src= block in the card and marking parts of the code as +holes. +** Context ~'context~ +Holes ~org-fc-type-cloze-context~ (default 1) around the currently +reviewed one are shown. + +Useful for memorizing longer lists where the order of items is important. +** Hole Syntax +Deletions can have the following forms + +- ~{{text}}~ +- ~{{text}@id}~ +- ~{{text}{hint}}~ +- ~{{text}{hint}@id}~ + +~text~ should not contain any "}", +unless it is part of a ~$latex$~ block. +In this case, ~latex~ should not contain any "$". + +Holes *inside* latex blocks are not handled correctly at the moment. +As a workaround, create multiple smaller latex blocks and wrap each in +a hole. +** Image Deletions +Due to an issue with invisible overlays, images inside cloze-holes are +not shown correctly during review if the image link directly follows +the opening ~{{~. + +Adding spaces around the image link fixes this problem, +e.g. ~{{ [[file:my_image.png]] }}~. +** LaTeX in Cloze Deletions +LaTeX code in cloze delections can't contain a ~}}~, +to work around this limitation, insert a space between the braces. + +Example: ~\frac{1}{\sqrt{2} }~ +* Compact Cards +For cards without a "Back" heading, the headline text is considered as +the front, the main text as the back. + +This is useful for cards with a short front text, e.g. when learning +definitions of words. +* Defining Own Card Types +To define a custom card type, +you need to implement three functions: + +- ~(...-init)~ to initialize a heading as a flashcard of this type, + setting up the cards properties & review data. + Should be marked as ~(interactive)~. +- ~(...-setup position)~ to setup ~position~ of the card for review +- ~(...-flip)~ to flip the card +- ~(...-update)~ to update the review data of the card, e.g. if a new + hole is added to a cloze card + +All of these are called with ~(point)~ on the cards heading. diff --git a/docs/components.org b/docs/components.org new file mode 100644 index 0000000..c43b34f --- /dev/null +++ b/docs/components.org @@ -0,0 +1,66 @@ +#+TITLE: Components +#+DATE: [2020-08-27 Thu 11:55] +#+KEYWORDS: fc + +Components of org-fc and the most important functions they expose. + +* Overview +#+begin_src plantuml :file images/components.png +[Index / Query] -* [Dashboard] +[Index / Query] -* [Review] +[Index / Query] -- [AWK] +[Review] -- [Card Types] +[Review] -- [SM2 Spacing Algorithm] +[Card Types] -- [Normal] +[Card Types] -- [Double] +[Card Types] -- [Text Input] +[Card Types] -- [Cloze] +[Text Input] -- [Diff] +#+end_src + +#+RESULTS: +[[file:images/components.png]] + +* ~org-fc-core.el~ +Core functions. +* ~org-fc-index.el~ +Takes care of indexing and filtering cards. + +- ~(org-fc-index context)~ (context is a [[file:review_contexts.org][Review Context]]) +- ~(org-fc-index-positions index)~ +- ~(org-fc-index-shuffled-positions index)~ + +- ~(org-fc-index-compile-filter filter)~, turns ~filter~ into a lambda + function + +** ~org-fc-awk.el~ +AWK based indexer. +* ~org-fc-sm2.el~ +Implementation of the SM2 [[file:repetition_spacing_algorithm.org][Repetition Spacing Algorithm]]. + +- ~(org-fc-sm2-next-parameters ease box interval rating)~ + returns a list ~(next-ease next-box next-interval)~ + +* ~org-fc-review.el~ +Review functionality of org-fc. + +- ~(org-fc-review context)~ where ~context~ is a [[file:review_contexts.org][Review Context]] +- ~(org-fc-demo)~ starts a review of the demo file +* ~org-fc-diff.el~ +Diff functions for (single-line) strings. + +- ~(org-fc-diff got expected)~ + returns a pair ~(got . expected)~ of colored strings. +* ~org-fc-dashboard.el~ +Dashboard for org-fc. + +- ~(org-fc-dashboard context)~ where ~context~ is a [[file:review_contexts.org][Review Context]] +* Card Types +** ~org-fc-type-normal.el~ +Simple front -> back card type. +** ~org-fc-type-double.el~ +Bidirectional card type (front <-> back). +** ~org-fc-type-text-input.el~ +Text input cards. +** ~org-fc-type-cloze.el~ +Card type for cloze deletions. diff --git a/docs/customizing_org-fc.org b/docs/customizing_org-fc.org new file mode 100644 index 0000000..9359d78 --- /dev/null +++ b/docs/customizing_org-fc.org @@ -0,0 +1,14 @@ +#+TITLE: Customizing Org-Fc +#+DATE: [2020-08-05 Wed 15:28] +#+KEYWORDS: fc + +For an overview of customization options, +~M-x customize~ and search for ~org-fc~. + +* 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 diff --git a/docs/dashboard.org b/docs/dashboard.org new file mode 100644 index 0000000..9c7ad54 --- /dev/null +++ b/docs/dashboard.org @@ -0,0 +1,15 @@ +#+TITLE: Dashboard +#+DATE: [2020-08-05 Wed 15:29] +#+KEYWORDS: fc + +~M-x org-fc-dashboard~ shows a buffer with statistics for review +performance and cards / card types. + +[[file:images/dashboard.png]] + +Review performance statistics are calculated based on +the [[file:review_history.org][Review History]]. Only cards with a box >= +~org-fc-stats-review-min-box~ (default: 0) are included. + +Setting this to a higher value (e.g. 2) excludes the first few +"learning" reviews of a card. diff --git a/docs/differences_from_other_flashcard_systems.org b/docs/differences_from_other_flashcard_systems.org new file mode 100644 index 0000000..3567d79 --- /dev/null +++ b/docs/differences_from_other_flashcard_systems.org @@ -0,0 +1,37 @@ +#+TITLE: Differences from Other Flashcard Systems +#+DATE: [2020-07-17 Fri 00:42] +#+KEYWORDS: fc + +There are a few other packages implementing a SRS (spaced repetition +system) 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. + +Thanks to the maintainers and all contributors for their work on these +projects! + +* Other (Open Source) SRS +- [[https://apps.ankiweb.net/][Anki]] +- [[https://mnemosyne-proj.org/][Mnemosyne Project]] + +The [[file:repetition_spacing_algorithm.org][Repetition Spacing Algorithm]] of org-fc is very similar to the one +used in Anki. + +When working with a large collection of mostly text-based items, +it's important to have powerful editing possibilities. + +org-fc is a SRS built into a (the) most powerful text editor. +* Org-Mode +- [[https://gitlab.com/phillord/org-drill/][phillord/org-drill]] +- [[https://github.com/abo-abo/pamparam][abo-abo/pamparam]] + +Among the other org-mode based SRS I've found so far, +org-fc is unique in that each headline can have multiple "positions" +that are reviewed independently from each other. + +This is very useful for cloze deletions. +* Memrise :noexport: +What is does well: +- presenting cards in different directions / contexts +- repeating forgotten cards in different ways diff --git a/docs/extensions.org b/docs/extensions.org new file mode 100644 index 0000000..30dea9c --- /dev/null +++ b/docs/extensions.org @@ -0,0 +1,36 @@ +#+TITLE: Extensions +#+DATE: [2020-07-19 Sun 16:06] +#+KEYWORDS: fc + +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). + +Files are played using the ~mpv~ media player. + +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~ +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: + +#+begin_src emacs-lisp + (require 'org-fc-hydra) + (global-set-key (kbd "C-c f") 'org-fc-hydra/body) +#+end_src diff --git a/docs/hydra.org b/docs/hydra.org new file mode 100644 index 0000000..a2d0311 --- /dev/null +++ b/docs/hydra.org @@ -0,0 +1,6 @@ +#+TITLE: Hydra +#+DATE: [2020-08-05 Wed 15:31] +#+KEYWORDS: fc + +The org-fc hydra provides a quick way of interacting with the +flashcard system. diff --git a/docs/incubator.org b/docs/incubator.org new file mode 100644 index 0000000..bd80791 --- /dev/null +++ b/docs/incubator.org @@ -0,0 +1,18 @@ +#+SETUPFILE: ~/org/setup.org +#+TITLE: Incubator +#+DATE: [2020-07-17 Fri 00:33] +#+KEYWORDS: fc + +* Presentations using org-mode +- Cloze-like cards for revealing points of a list +* Workout Tracker / Timer +One example would be storing one exercise per heading, using the +positions to store one or more sets and logging the number of +repetitions done on each "review". + +- TTS for instructions +- Exercise / Pause Timer +* Mood Tracking +- Store History in table instead of CSV file +* Sharing Support, Merging of Changed Cards +1. strip review data, creation date diff --git a/docs/index.org b/docs/index.org new file mode 100644 index 0000000..0e75ffa --- /dev/null +++ b/docs/index.org @@ -0,0 +1,66 @@ +#+TITLE: Org Flashcards +#+DATE: [2020-07-17 Fri 00:16] +#+KEYWORDS: fc + +- [[https://git.sr.ht/~l3kn/org-fc][Git]] +- [[https://lists.sr.ht/~l3kn/org-fc][Mailing List]] +- [[https://todo.sr.ht/~l3kn/org-fc][Issue Tracker]] + +[[file:images/review.png]] + +* Introduction +Org-fc is a spaced-repetition system for Emacs' org-mode. + +It allows you to mark headlines in a file as "flashcards", turning +pieces of knowledge you want to learn into a question-answer test. + +These cards are reviewed at regular interval. After each review, a +[[file:repetition_spacing_algorithm.org][Repetition Spacing Algorithm]] is used to calculate the next interval +based on how well you remembered the contents of the card. +* Getting Started +Start by [[file:installation.org][installing org-fc]] using the package manager of your choice. + +A file demonstrating all [[file:card_types.org][Card Types]] is included. ~M-x org-fc-demo~ +starts a review of this file. + +To create your own flashcards, create a heading in an org-mode file +and [[file:marking_headings_as_cards.org][mark it as a flashcard]], using either one of the +~org-fc-type-...-init~ commands (e.g. ~org-fc-type-normal-init~) +or the [[file:hydra.org][org-fc Hydra]] (e.g. =C-c f= to open it, =t= to initialize a +new card, =n= to select the normal card type). + +Once you've created a bunch of cards, you can start a [[file:review.org][Review Session]] +with ~M-x org-fc-review~ (=C-c f r= in the hydra). + +~M-x org-fc-dashboard~ (=C-c f m= in the hydra) opens a [[file:dashboard.org][Dashboard]] +with statistics on the flashcards in the system. + +Before reviews and when opening the dashboard, you're asked to select +a [[file:review_contexts.org][Review Context]]. These can be used to group cards to review them +separately from each other, e.g. when learning multiple languages. + +Note 1: The [[file:hydra.org][Hydra]] is not enabled by default, add ~(require +'org-fc-hydra)~ to your configuration to load it. + +Note 2: Make sure to check out [[file:use_with_evil-mode.org][Use with Evil-Mode]] if you're using +evil-mode. + +Note 3: Before starting the review, make sure to add the directory of +your org files to ~org-fc-directories~, e.g. via ~(setq +org-fc-directories '("/my-org-files/"))~ +* Design Goals / Choices +- [[file:differences_from_other_flashcard_systems.org][Differences from Other Flashcard Systems]] +- Good [[file:performance.org][Performance]] + - =awk= is used for quickly finding cards due for review, + instead of relying on the slow org-element parser +- Support for multiple *positions* in a card / heading +- All relevant data kept in org files for easy version control +- Review directly on the source org file for easy editing of cards + during review +* Advanced Topics +- [[file:components.org][Components]] +- [[file:alternative_applications.org][Alternative Applications]] +- [[file:extensions.org][Extensions]] +- [[file:customizing_org-fc.org][Customizing Org-Fc]] +* License +Copyright © Leon Rische and contributors. Distributed under the GNU General Public License, Version 3 diff --git a/docs/installation.org b/docs/installation.org new file mode 100644 index 0000000..59ba39b --- /dev/null +++ b/docs/installation.org @@ -0,0 +1,123 @@ +#+TITLE: Installation +#+DATE: [2020-08-05 Wed 15:31] +#+KEYWORDS: fc + +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 +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~. + +- 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 +** 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 [[https://www.gnu.org/software/gawk/manual/html_node/Installation.html][gawk manual - Installation]]. +** MacOS +On MacOS all dependencies can be installed using [[https://www.macports.org/][macports]] or [[https://brew.sh/][homebrew]]. +=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. + +#+BEGIN_SRC + export PATH="/opt/local/libexec/gnubin:/opt/local/bin:$PATH" +#+END_SRC + +For more information, refer to the documentation of macports / +homebrew. +* Manual Installation +#+begin_src bash + cd ~/src/ + git clone https://git.sr.ht/~l3kn/org-fc +#+end_src + +#+BEGIN_SRC emacs-lisp + (add-to-list 'load-path "~/src/org-fc/") + + (require 'org-fc) + (require 'org-fc-hydra) + + (setq org-fc-directories '("~/org/")) +#+END_SRC +* Setup with [[https://github.com/jwiegley/use-package/][use-package]] +Assuming you've manually cloned the repository. + +#+BEGIN_SRC emacs-lisp :eval no-export + (use-package hydra) + (use-package org-fc + :load-path "~/src/org-fc" + :custom (org-fc-directories '("~/org/")) + :config + (require 'org-fc-hydra)) +#+END_SRC + +Or, using [[https://github.com/raxod502/straight.el/][straight.el]]: + +#+BEGIN_SRC emacs-lisp :eval no-export + (use-package hydra) + (use-package org-fc + :straight + (org-fc + :type git :repo "https://git.sr.ht/~l3kn/org-fc" + :files (:defaults "awk" "demo.org")) + :custom + (org-fc-directories '("~/org/")) + :config + (require 'org-fc-hydra)) +#+END_SRC + +Note that in this case, you don't have to clone the repository. +* Setup with [[https://github.com/raxod502/straight.el/][straight.el]] +#+BEGIN_SRC emacs-lisp :eval no-export + (straight-use-package 'hydra) + (straight-use-package + '(org-fc + :type git :repo "https://git.sr.ht/~l3kn/org-fc" + :files (:defaults "awk" "demo.org") + :custom (org-fc-directories '("~/org/")) + :config + (require 'org-fc-hydra))) +#+END_SRC + +* Setup with [[https://github.com/syl20bnr/spacemacs/][spacemacs]] +You don't need to manually clone the repository, +just put this in your =.spacemacs=: + +#+BEGIN_SRC emacs-lisp :eval no-export + ;; ... + dotspacemacs-additional-packages + '((org-fc + :location (recipe :fetcher git + :url "https://git.sr.ht/~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/")) + ;; ... + ) +#+END_SRC diff --git a/docs/introduction.org b/docs/introduction.org new file mode 100644 index 0000000..c9dc4d9 --- /dev/null +++ b/docs/introduction.org @@ -0,0 +1,53 @@ +#+TITLE: Introduction +#+DATE: [2020-07-17 Fri 01:07] +#+FILETAGS: :fc-demo: +#+KEYWORDS: fc + +* Welcome to org-fc :suspended:fc: +:PROPERTIES: +:FC_CREATED: 2020-07-16T23:14:28Z +:FC_TYPE: normal +:ID: 78877a24-22f3-4996-8fc1-544204cda0b0 +:END: +:REVIEW_DATA: +| position | ease | box | interval | due | +|----------+------+-----+----------+----------------------| +| front | 2.5 | 0 | 0 | 2020-07-16T23:14:28Z | +:END: +This is an interactive introduction into org-fc, +using org-fc. + +You're currently (re)viewing the front of a flashcard. +To "flip" it, revealing the contents of its "Back" heading, +press the enter key. + +You can quit the review at any time by pressing "q". +** Back +This is the back side of the flashcard. + +You can now rate how well you remembered the information on the back +side of the card. +* The "normal" Card Type :suspended:fc: +:PROPERTIES: +:FC_CREATED: 2020-07-16T23:20:50Z +:FC_TYPE: normal +:ID: 8f01a1c9-c842-48b8-9952-ca1c38875703 +:END: +:REVIEW_DATA: +| position | ease | box | interval | due | +|----------+------+-----+----------+----------------------| +| front | 2.5 | 0 | 0 | 2020-07-16T23:20:50Z | +:END: +Let's try that again! + +What are the two sides of a "normal" flashcard +like the one you have just seen? +** Back +- front (i.e. question) +- back (i.e. answer) +* WAITING Use inline-evaluation for key bindings :noexport: +:PROPERTIES: +:ID: 5f3f2a87-d7b9-409c-af97-691643f07b4d +:END: +- Requires inline-evaluation / insertion of lisp code +- Similar to org (export) macros diff --git a/docs/marking_headings_as_cards.org b/docs/marking_headings_as_cards.org new file mode 100644 index 0000000..c6ba5d2 --- /dev/null +++ b/docs/marking_headings_as_cards.org @@ -0,0 +1,47 @@ +#+TITLE: Marking Headings As Cards +#+DATE: [2020-08-07 Fri 14:34] +#+KEYWORDS: fc + +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. + +#+BEGIN_EXAMPLE + :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: +#+END_EXAMPLE + +The [[file:review_history.org][Review History]] is stored in a TSV 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 +creating statistics for how many cards were created in the last day / +week / month. + +#+BEGIN_EXAMPLE + :PROPERTIES: + :ID: 4ffe66a7-7b5c-4811-bd3e-02b5c0862f55 + :FC_TYPE: normal + :FC_CREATED: 2019-10-11T14:08:32 + :END: +#+END_EXAMPLE + +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. diff --git a/docs/performance.org b/docs/performance.org new file mode 100644 index 0000000..3d2df8a --- /dev/null +++ b/docs/performance.org @@ -0,0 +1,14 @@ +#+TITLE: Performance +#+DATE: [2020-07-19 Sun 16:01] +#+KEYWORDS: fc + +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 a 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. diff --git a/docs/repetition_spacing_algorithm.org b/docs/repetition_spacing_algorithm.org new file mode 100644 index 0000000..aaa4356 --- /dev/null +++ b/docs/repetition_spacing_algorithm.org @@ -0,0 +1,6 @@ +#+TITLE: Repetition Spacing Algorithm +#+DATE: [2020-07-17 Fri 00:46] +#+KEYWORDS: fc + +This package uses a modified version of the [[https://www.supermemo.com/en/archives1990-2015/english/ol/sm2][SuperMemo - SM2 Algorithm]] +algorithm, based on the one used by [[https://apps.ankiweb.net/docs/manual.html#what-algorithm][Anki]]. diff --git a/docs/review.org b/docs/review.org new file mode 100644 index 0000000..74a39d3 --- /dev/null +++ b/docs/review.org @@ -0,0 +1,102 @@ +#+TITLE: Review +#+DATE: [2020-08-05 Wed 15:29] +#+KEYWORDS: fc + +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~. + +[[file:review_contexts.org][Review Contexts]] can be used to only review cards of a set tag or type, +e.g. when using org-fc to learn different foreign languages where +mixing them in one review session would lead to confusion. + +Each time a card is rated, an entry is added to the [[file:review_histord.org][Review History]]. + +Cards can be excluded from review without deleting them +by [[file:suspending_cards.org][suspending them]]. + +* 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 + +#+begin_src plantuml :file images/review_loop.png +"Review next Card" -> if "Another card due?" then + -->[true] "Open file of card\nNarrow\nSet up\nflip-mode" + --> if "Action" then + -->[flip] "Flip Card\nrate-mode" + --> if "Action" then + -->[again] "Append Card" + --> "Update Review Data" + else + -->[hard / good / easy] "Update Review Data" + --> "Review next Card" + else + -->[suspend] "Suspend Card" + --> "Review next Card" + else + ->[edit] "Edit Card" + --> "Open file of card\nNarrow\nSet up\nflip-mode" + else + -->[quit] "Quit Review" + endif + else + -->[quit] "Quit Review" + endif +else + -->[false] "Quit Review" +endif +#+end_src + +#+RESULTS: +[[file:images/review_loop.png]] + +#+begin_src plantuml :file images/review_sequence.png +actor User +collections Card +database Index + +User -> Index: Start Review +Index -> Card: Jump to next due card +Card -> Card: Narrow to card heading +Card -> Card: Set up card +User -> Card: Flip card +User -> Card: Rate card +Card -> Index: Update review data +Index -> Card: Jump to next due card +... Repeat ... +#+end_src + +By default failed cards (rated again) are appended to the current +review session. This can be disabled with ~(setq +org-fc-append-failed-cards nil)~. + +#+RESULTS: +[[file:images/review_sequence.png]] + +* 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 | diff --git a/docs/review_contexts.org b/docs/review_contexts.org new file mode 100644 index 0000000..9b737fb --- /dev/null +++ b/docs/review_contexts.org @@ -0,0 +1,65 @@ +#+TITLE: Review Contexts +#+DATE: [2020-08-01 Sat 10:41] +#+KEYWORDS: fc + +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": +#+begin_src emacs-lisp + (add-to-list 'org-fc-custom-contexts + '(double-math-cards . (:filter (and (type double) (tag "math"))))) +#+end_src + +All cards in that don't have one of the tags "foo" and "bar": +#+begin_src emacs-lisp + (add-to-list 'org-fc-custom-contexts + '(no-foo-bar-cards . (:filter (not (or (tag "foo") (tag "bar")))))) +#+end_src + +All cards in =~/combinatorics/= or =~/number_theory.org=: +#+begin_src emacs-lisp + (add-to-list 'org-fc-custom-contexts + '(math-cards . (:paths ("~/combinatorics/" "~/number_theory.org")))) +#+end_src + +All cards in =~/combinatorics/= with tag "theorem": +#+begin_src emacs-lisp + (add-to-list 'org-fc-custom-contexts + '(combinatorics-theorems . + (:paths "~/combinatorics/" :filter (tag "theorem")))) +#+end_src + +All double cards in the current buffer: +#+begin_src emacs-lisp + (add-to-list 'org-fc-custom-contexts + '(current-double . + (:paths buffer :filter (type double)))) +#+end_src +* Note +Because parsing of tags is done in AWK, tag filters don't work for +tags defined in the =#+FILETAGS:= of a =#+SETUP_FILE:=. diff --git a/docs/review_history.org b/docs/review_history.org new file mode 100644 index 0000000..84d7861 --- /dev/null +++ b/docs/review_history.org @@ -0,0 +1,23 @@ +#+TITLE: Review History +#+DATE: [2020-08-01 Sat 10:47] +#+KEYWORDS: fc + +The review history is stored in a tsv file, to avoid cluttering org +files. This makes it easy to calculate review statistics. + +Columns: +1. Date in ISO8601 format, second precision +2. Filename +3. Card ID +4. Position +5. Ease (before review) +6. Box (before review) +7. Interval (before review) +8. Rating +9. Seconds spent reviewing the card +10. [[file:repetition_spacing_algorithm.org][Repetition Spacing Algorithm]] used + +More advanced review algorithms might need to use the review history +of a card. In this case, the card ID + position should be used to look +up the review history, as the filename can change when moving cards +from file to file. diff --git a/docs/suspending_cards.org b/docs/suspending_cards.org new file mode 100644 index 0000000..0fd4d82 --- /dev/null +++ b/docs/suspending_cards.org @@ -0,0 +1,27 @@ +#+TITLE: Suspending Cards +#+DATE: [2020-08-01 Sat 10:55] +#+KEYWORDS: fc + +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. diff --git a/docs/use_with_evil-mode.org b/docs/use_with_evil-mode.org new file mode 100644 index 0000000..154eb23 --- /dev/null +++ b/docs/use_with_evil-mode.org @@ -0,0 +1,48 @@ +#+TITLE: Use with Evil-Mode +#+DATE: [2020-07-19 Sun 16:03] +#+KEYWORDS: fc + +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. + +#+begin_src 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) +#+end_src + +* Using general.el for Keybindings +#+begin_src emacs-lisp + (general-define-key + :definer 'minor-mode + :states 'normal + :keymaps 'org-fc-review-flip-mode + "RET" 'org-fc-review-flip + "n" 'org-fc-review-flip + "s" 'org-fc-review-suspend-card + "q" 'org-fc-review-quit) + + (general-define-key + :definer 'minor-mode + :states 'normal + :keymaps 'org-fc-review-rate-mode + "a" 'org-fc-review-rate-again + "h" 'org-fc-review-rate-hard + "g" 'org-fc-review-rate-good + "e" 'org-fc-review-rate-easy + "s" 'org-fc-review-suspend-card + "q" 'org-fc-review-quit) +#+end_src -- cgit v1.2.3