emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/org-drill a222b4dfb4 022/251: Many changes:


From: ELPA Syncer
Subject: [nongnu] elpa/org-drill a222b4dfb4 022/251: Many changes:
Date: Mon, 17 Jan 2022 18:58:57 -0500 (EST)

branch: elpa/org-drill
commit a222b4dfb486991960e9c12e3df90d518c81801a
Author: eeeickythump <devnull@localhost>
Commit: eeeickythump <devnull@localhost>

    Many changes:
    - Item drill data is stored in a clearer format, each value has its own 
property, the old 'org-learn'
      LEARN_DATA property has been dropped. Items that contain LEARN_DATA are 
silently rolled over to
      the new format.
    - For SM5, matrix of optimal factors is now correctly *global* rather than 
per-item, and is saved
      between drill sessions as an emacs customization variable.
    - We store interval data as floating point numbers rather than rounding to 
the nearest integer.
    - New experimental algorithm: 'simple8', based on SuperMemo SM8.
    - New options:
      - org-drill-forgetting-index: define the percentage of items that it is 
"acceptable" to fail.
        A warning message is shown after the drill session if more items than 
this were failed.
      - org-drill-learn-fraction: governs how fast time intervals increase with 
each successful
        repetition of an item.
      - org-drill-adjust-intervals-for-early-and-late-repetitions-p: if true, 
alter next scheduled date
        if an item is reviewed earlier or later than it was supposed to be.
    - Almost all variables have been declared safe for file-local reassignment.
    - We now ignore org-learn-always-reschedule, regarding it as always true.
    - Post-session report now shows a count of dormant items (those not yet due 
for review).
---
 README.html  | 682 +++++++++++++++++++++++++++++++++++++-------------------
 README.org   | 340 +++++++++++++++++++---------
 org-drill.el | 719 +++++++++++++++++++++++++++++++++++++++++++----------------
 3 files changed, 1211 insertions(+), 530 deletions(-)

diff --git a/README.html b/README.html
index 7f46d5b914..5561788659 100755
--- a/README.html
+++ b/README.html
@@ -7,7 +7,7 @@ lang="en" xml:lang="en">
 <title>Org-Drill</title>
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
 <meta name="generator" content="Org-mode"/>
-<meta name="generated" content="2011-04-04 10:18:44 "/>
+<meta name="generated" content="2011-04-08 16:00:36 "/>
 <meta name="author" content="Paul Sexton"/>
 <meta name="description" content=""/>
 <meta name="keywords" content=""/>
@@ -89,7 +89,7 @@ lang="en" xml:lang="en">
 <div id="text-table-of-contents">
 <ul>
 <li><a href="#sec-1">Synopsis </a></li>
-<li><a href="#sec-2">Installation and Customisation </a></li>
+<li><a href="#sec-2">Installation </a></li>
 <li><a href="#sec-3">Demonstration </a></li>
 <li><a href="#sec-4">Writing the questions </a>
 <ul>
@@ -98,15 +98,28 @@ lang="en" xml:lang="en">
 <li><a href="#sec-4_3">Two-sided cards </a></li>
 <li><a href="#sec-4_4">Multi-sided cards </a></li>
 <li><a href="#sec-4_5">Multi-cloze cards </a></li>
-<li><a href="#sec-4_6">User-defined topic types </a></li>
-<li><a href="#sec-4_7">Comments </a></li>
+<li><a href="#sec-4_6">User-defined card types </a></li>
 </ul>
 </li>
 <li><a href="#sec-5">Running the drill session </a></li>
-<li><a href="#sec-6">Leeches </a></li>
-<li><a href="#sec-7">Cram mode </a></li>
-<li><a href="#sec-8">Incremental reading </a></li>
-<li><a href="#sec-9">Still to do </a></li>
+<li><a href="#sec-6">Cram mode </a></li>
+<li><a href="#sec-7">Leeches </a></li>
+<li><a href="#sec-8">Customisation </a>
+<ul>
+<li><a href="#sec-8_1">Appearance of items during drill sessions </a></li>
+<li><a href="#sec-8_2">Duration of drill sessions </a></li>
+<li><a href="#sec-8_3">Spaced repetition algorithm </a>
+<ul>
+<li><a href="#sec-8_3_1">Choice of algorithm </a></li>
+<li><a href="#sec-8_3_2">Random variation of repetition intervals </a></li>
+<li><a href="#sec-8_3_3">Adjustment for early or late review of items </a></li>
+<li><a href="#sec-8_3_4">Adjusting item difficulty globally </a></li>
+</ul>
+</li>
+<li><a href="#sec-8_4">Per-file customisation settings </a></li>
+</ul>
+</li>
+<li><a href="#sec-9">Incremental reading </a></li>
 </ul>
 </div>
 </div>
@@ -138,7 +151,7 @@ For more on the spaced repetition algorithm, and examples 
of other programs
 that use it, see:
 </p><ul>
 <li>
-<a href="http://supermemo.com/index.htm";>SuperMemo</a> (the SM5 algorithm is 
discussed <a href="http://www.supermemo.com/english/ol/sm5.htm";>here</a>)
+<a href="http://supermemo.com/index.htm";>SuperMemo</a> (see descriptions of 
the SM2, SM5 and SM8 algorithms)
 </li>
 <li>
 <a href="http://ichi2.net/anki/";>Anki</a>
@@ -155,7 +168,7 @@ that use it, see:
 </div>
 
 <div id="outline-container-2" class="outline-2">
-<h2 id="sec-2">Installation and Customisation </h2>
+<h2 id="sec-2">Installation </h2>
 <div class="outline-text-2" id="text-2">
 
 
@@ -172,85 +185,6 @@ Put the following in your <code>.emacs</code>. You will 
also need to make sure t
 
 
 
-<p>
-I also recommend the following, so that items are always eventually retested,
-even when you remember them well.
-</p>
-
-
-
-<pre class="example">(setq org-learn-always-reschedule t)
-</pre>
-
-
-
-<p>
-If you want cloze-deleted text to show up in a special font within Org mode
-buffers, also add:
-</p>
-
-
-
-<pre class="example">(setq org-drill-use-visible-cloze-face-p t)
-</pre>
-
-
-
-<p>
-Item headings may contain information that "gives away" the answer to the item,
-either in the heading text or in tags. If you want item headings to be made
-invisible while each item is being tested, add:
-</p>
-
-
-
-<pre class="example">(setq org-drill-hide-item-headings-p t)
-</pre>
-
-
-
-<p>
-Org-Drill supports two different spaced repetition algorithms &ndash; SM5 (the
-default, implemented by <code>org-learn</code>) and SM2. SM2 is an earlier 
algorithm which
-remains very popular &ndash; Anki and Mnemosyne, two of the most popular spaced
-repetition programs, use SM2.
-</p>
-<p>
-If you want Org-Drill to use the SM2 algorithm, put the following in your
-<code>.emacs</code>:
-</p>
-
-
-
-<pre class="example">(setq org-drill-spaced-repetition-algorithm 'sm2)
-</pre>
-
-
-
-<p>
-The intervals generated by the SM2 and SM5 algorithms are pretty
-deterministic. If you tend to add items in large, infrequent batches, the lack
-of variation in interval scheduling can lead to the problem of "lumpiness" --
-one day a large batch of items are due for review, the next there is almost
-nothing, a few days later another big pile of items is due.
-</p>
-<p>
-This problem can be ameliorated by adding some random "noise" to the interval
-scheduling algorithm. The author of SuperMemo actually recommends this approach
-for the SM5 algorithm, and Org-Drill's implementation uses <a 
href="http://www.supermemo.com/english/ol/sm5.htm";>his code</a>.
-</p>
-<p>
-To enable random "noise" for item intervals, set the variable
-<code>org-drill-add-random-noise-to-intervals-p</code> to true by putting the 
following in
-your <code>.emacs</code>:
-</p>
-
-
-
-<pre class="example">(setq org-drill-add-random-noise-to-intervals-p t)
-</pre>
-
-
 
 
 </div>
@@ -284,8 +218,9 @@ drill topics are written.
 
 <p>
 Org-Drill uses org mode topics as 'drill items'. To be used as a drill item,
-the topic must have a tag that matches <code>org-drill-question-tag</code>. 
This is
-<code>:drill:</code> by default. Any other org topics will be ignored.
+the topic must have a tag that matches the value of
+<code>org-drill-question-tag</code>. This is <code>:drill:</code> by default. 
Any other org topics
+will be ignored.
 </p>
 <p>
 You don't need to schedule the topics initially.  However 
<code>org-drill</code> <b>will</b>
@@ -295,16 +230,40 @@ memorisation.
 </p>
 <p>
 How should 'drill topics' be structured? Any org topic is a legal drill topic
-&ndash; it will simply be shown with subheadings collapsed. After pressing a
-key, any hidden subheadings will be revealed, and you will be asked to rate
-your "recall" of the item.
+&ndash; it will simply be shown with all subheadings collapsed, so thta only 
the
+material beneath the main item heading is visible. After pressing a key, any
+hidden subheadings will be revealed, and you will be asked to rate your
+"recall" of the item.
 </p>
 <p>
 This will be adequate for some items, but usually you will want to write items
 where you have more control over what information is hidden from the user for
-recall purposes.
+recall purposes. For this reason, some other card types are defined, including:
+</p><ul>
+<li>
+<a href="#sec-4_3">Two-sided cards</a>
+</li>
+<li>
+<a href="#sec-4_4">Multi-sided cards</a>
+</li>
+<li>
+<a href="#Multicloze--cards">Multicloze cards</a>
+</li>
+<li>
+<a href="#sec-4_6">User-defined card types</a>
+</li>
+</ul>
+
+
+<p>
+<b>A note about comments:</b> In org mode, comment lines start with '#'. The 
rest of
+the line is ignored by Org (apart from some special cases). You may sometimes
+want to put material in comments which you do not want to see when you are
+being tested on the item. For this reason, comments are always rendered
+invisible while items are being tested.
 </p>
 
+
 </div>
 
 <div id="outline-container-4_1" class="outline-3">
@@ -312,6 +271,7 @@ recall purposes.
 <div class="outline-text-3" id="text-4_1">
 
 
+
 <p>
 The simplest drill topic has no special structure. When such a topic is
 presented during a drill session, any subheadings are "collapsed" with their
@@ -321,11 +281,11 @@ heading, and the answer within a subheading. For example:
 
 
 
-<pre class="example">* Item                                   :drill:
-What is the capital city of Estonia?
+<pre class="src src-org"><span style="color: #f0ffff; background-color: 
#4169e1; font-weight: bold;">* Item                                   
</span><span style="color: #66cdaa; background-color: #4169e1; font-weight: 
bold;">:drill:</span><span style="color: #f0ffff; background-color: #4169e1; 
font-weight: bold;">
+</span>What is the capital city of Estonia?
 
-** The Answer
-Tallinn.
+<span style="color: #4876ff; background-color: #000080; font-weight: bold;">** 
The Answer
+</span>Tallinn.
 </pre>
 
 
@@ -344,6 +304,7 @@ be visible, but the contents of the subheading ("The 
Answer") will be hidden.
 <div class="outline-text-3" id="text-4_2">
 
 
+
 <p>
 Cloze deletion can be used in any drill topic regardless of whether it is
 otherwise 'simple', or is one of the specialised topic types discussed
@@ -356,8 +317,9 @@ example:
 
 
 
-<pre class="example">* Item                                   :drill:
-The capital city of Estonia is [Tallinn].
+
+<pre class="src src-org"><span style="color: #f0ffff; background-color: 
#4169e1; font-weight: bold;">* Item                                   
</span><span style="color: #66cdaa; background-color: #4169e1; font-weight: 
bold;">:drill:</span><span style="color: #f0ffff; background-color: #4169e1; 
font-weight: bold;">
+</span>The capital city of Estonia is <span style="color: 
#ab82ff;">[Tallinn]</span>.
 </pre>
 
 
@@ -388,8 +350,8 @@ Example:
 
 
 
-<pre class="example">Type 1 hypersensitivity reactions are mediated by 
[immunoglobulin E|molecule]
-and [mast cells|cell type].
+<pre class="src src-org">Type 1 hypersensitivity reactions are mediated by 
<span style="color: #ab82ff;">[immunoglobulin E</span><span style="color: 
#483d8b;">|molecule</span><span style="color: #ab82ff;">]</span>
+and <span style="color: #ab82ff;">[mast cells</span><span style="color: 
#483d8b;">|cell type</span><span style="color: #ab82ff;">]</span>.
 </pre>
 
 
@@ -411,7 +373,7 @@ and <font style="background-color: blue;" color="cyan">
 </div>
 
 <div id="outline-container-4_3" class="outline-3">
-<h3 id="sec-4_3">Two-sided cards </h3>
+<h3 id="sec-4_3"><a name="Two-sided--cards" 
id="Two-sided--cards"></a>Two-sided cards </h3>
 <div class="outline-text-3" id="text-4_3">
 
 
@@ -436,21 +398,21 @@ review.
 
 
 
-<pre class="example">* Noun                                               
:drill:
-    :PROPERTIES:
-    :DRILL_CARD_TYPE: twosided
-    :END:
+<pre class="src src-org"><span style="color: #f0ffff; background-color: 
#4169e1; font-weight: bold;">* Noun                                             
  </span><span style="color: #66cdaa; background-color: #4169e1; font-weight: 
bold;">:drill:</span><span style="color: #f0ffff; background-color: #4169e1; 
font-weight: bold;">
+</span><span style="color: #8b4789;">    :PROPERTIES:</span>
+    <span style="color: #8b4789;">:DRILL_CARD_TYPE:</span> <span style="color: 
#006400;">twosided</span>
+<span style="color: #8b4789;">    :END:</span>
 
 Translate this word.
 
-** Spanish
-la mujer
+<span style="color: #4876ff; background-color: #000080; font-weight: bold;">** 
Spanish
+</span>la mujer
 
-** English
-the woman
+<span style="color: #4876ff; background-color: #000080; font-weight: bold;">** 
English
+</span>the woman
 
-** Example sentence
-¿Quién fue esa mujer?
+<span style="color: #4876ff; background-color: #000080; font-weight: bold;">** 
Example sentence
+</span>&#191;Qui&#233;n fue esa mujer?
 Who was that woman?
 </pre>
 
@@ -468,10 +430,11 @@ not one of the first two 'sides' of the topic.
 </div>
 
 <div id="outline-container-4_4" class="outline-3">
-<h3 id="sec-4_4">Multi-sided cards </h3>
+<h3 id="sec-4_4"><a name="Multi-sided--cards" 
id="Multi-sided--cards"></a>Multi-sided cards </h3>
 <div class="outline-text-3" id="text-4_4">
 
 
+
 <p>
 The <code>multisided</code> card type is similar to <code>twosided</code>, 
except that any
 subheading has a chance of being presented during the topic review. One
@@ -480,21 +443,21 @@ subheading is always shown and all others are always 
hidden.
 
 
 
-<pre class="example">* Noun                                               
:drill:
-    :PROPERTIES:
-    :DRILL_CARD_TYPE: multisided
-    :END:
+<pre class="src src-org"><span style="color: #f0ffff; background-color: 
#4169e1; font-weight: bold;">* Noun                                             
  </span><span style="color: #66cdaa; background-color: #4169e1; font-weight: 
bold;">:drill:</span><span style="color: #f0ffff; background-color: #4169e1; 
font-weight: bold;">
+</span><span style="color: #8b4789;">    :PROPERTIES:</span>
+    <span style="color: #8b4789;">:DRILL_CARD_TYPE:</span> <span style="color: 
#006400;">multisided</span>
+<span style="color: #8b4789;">    :END:</span>
 
 Translate.
 
-** Spanish
-la mesa
+<span style="color: #4876ff; background-color: #000080; font-weight: bold;">** 
Spanish
+</span>la mesa
 
-** English
-the table
+<span style="color: #4876ff; background-color: #000080; font-weight: bold;">** 
English
+</span>the table
 
-** Picture
-[[file:table.jpg][PICTURE]]
+<span style="color: #4876ff; background-color: #000080; font-weight: bold;">** 
Picture
+</span><span style="color: #00bfff; text-decoration: underline;">PICTURE</span>
 </pre>
 
 
@@ -503,43 +466,47 @@ the table
 The user will be shown the main text and either 'la mujer', <i>or</i> 'the 
woman',
 <i>or</i> a picture of a table.
 </p>
+
 </div>
 
 </div>
 
 <div id="outline-container-4_5" class="outline-3">
-<h3 id="sec-4_5">Multi-cloze cards </h3>
+<h3 id="sec-4_5"><a name="Multi-cloze--cards" 
id="Multi-cloze--cards"></a>Multi-cloze cards </h3>
 <div class="outline-text-3" id="text-4_5">
 
 
+
 <p>
 Often, you will wish to create cards out of sentences that express several
 facts, such as the following:
 </p>
-<blockquote>
 
-<p>The capital city of New Zealand is Wellington, which is located in the
+
+
+<pre class="src src-org">The capital city of New Zealand is Wellington, which 
is located in the
 South Island and has a population of about 400,000.
-</p>
-</blockquote>
+</pre>
+
 
 
 <p>
 There is more than one fact in this statement &ndash; you could create a single
 'simple' card with all the facts marked as cloze text, like so:
 </p>
-<blockquote>
 
-<p>The capital city of [New Zealand] is [Wellington], which is located in
-[the South Island] and has a population of about [400,000].
-</p>
-</blockquote>
+
+
+<pre class="src src-org">The capital city of <span style="color: 
#ab82ff;">[New Zealand]</span> is <span style="color: 
#ab82ff;">[Wellington]</span>, which is located in
+the <span style="color: #ab82ff;">[North</span><span style="color: 
#483d8b;">|North/South</span><span style="color: #ab82ff;">]</span> Island and 
has a population of about <span style="color: #ab82ff;">[400,000]</span>.
+</pre>
+
 
 
 <p>
 But this card will be difficult to remember. If you get just one of the 4
 hidden facts wrong, you will fail the card. A card like this is likely to
-become a <a href="#sec-6">leech</a>.
+become a <a href="#sec-7">leech</a>.
 </p>
 <p>
 A better way to express all these facts using 'simple' cards is to create
@@ -549,29 +516,29 @@ like this:
 
 
 
-<pre class="example">* Fact
-The capital city of [New Zealand] is Wellington, which has a population of
+<pre class="src src-org"><span style="color: #f0ffff; background-color: 
#4169e1; font-weight: bold;">* Fact
+</span>The capital city of <span style="color: #ab82ff;">[New Zealand]</span> 
is Wellington, which has a population of
 about 400,000.
 
-* Fact
-The capital city of New Zealand is [Wellington], which has a population of
+<span style="color: #f0ffff; background-color: #4169e1; font-weight: bold;">* 
Fact
+</span>The capital city of New Zealand is <span style="color: 
#ab82ff;">[Wellington]</span>, which has a population of
 about 400,000.
 
-* Fact
-The capital city of New Zealand is Wellington, which has a population of
-about [400,000].
+<span style="color: #f0ffff; background-color: #4169e1; font-weight: bold;">* 
Fact
+</span>The capital city of New Zealand is Wellington, which has a population of
+about <span style="color: #ab82ff;">[400,000]</span>.
 
-* Fact
-The capital city of [New Zealand] is Wellington, which is located in the
-the South Island.
+<span style="color: #f0ffff; background-color: #4169e1; font-weight: bold;">* 
Fact
+</span>The capital city of <span style="color: #ab82ff;">[New Zealand]</span> 
is Wellington, which is located in the
+the North Island.
 
-* Fact
-The capital city of New Zealand is [Wellington], which is located in
-the South Island.
+<span style="color: #f0ffff; background-color: #4169e1; font-weight: bold;">* 
Fact
+</span>The capital city of New Zealand is <span style="color: 
#ab82ff;">[Wellington]</span>, which is located in
+the North Island.
 
-* Fact
-The capital city of New Zealand is Wellington, which is located in
-[the South Island].
+<span style="color: #f0ffff; background-color: #4169e1; font-weight: bold;">* 
Fact
+</span>The capital city of New Zealand is Wellington, which is located in
+the <span style="color: #ab82ff;">[North</span><span style="color: 
#483d8b;">|North/South</span><span style="color: #ab82ff;">]</span> Island.
 </pre>
 
 
@@ -592,28 +559,30 @@ will be hidden.
 
 
 
-<pre class="example">* Fact
-  :PROPERTIES:
-  :DRILL_CARD_TYPE: multicloze
-  :END:
+<pre class="src src-org"><span style="color: #f0ffff; background-color: 
#4169e1; font-weight: bold;">* Fact
+</span><span style="color: #8b4789;">  :PROPERTIES:</span>
+  <span style="color: #8b4789;">:DRILL_CARD_TYPE:</span> <span style="color: 
#006400;">multicloze</span>
+<span style="color: #8b4789;">  :END:</span>
 
-The capital city of [New Zealand] is [Wellington], which is located in
-[the South Island] and has a population of about [400,000].
+The capital city of <span style="color: #ab82ff;">[New Zealand]</span> is 
<span style="color: #ab82ff;">[Wellington]</span>, which is located in
+the <span style="color: #ab82ff;">[North</span><span style="color: 
#483d8b;">|North/South</span><span style="color: #ab82ff;">]</span> Island and 
has a population of about <span style="color: #ab82ff;">[400,000]</span>.
 </pre>
 
 
 
+
 </div>
 
 </div>
 
 <div id="outline-container-4_6" class="outline-3">
-<h3 id="sec-4_6">User-defined topic types </h3>
+<h3 id="sec-4_6"><a name="User-defined--card--types" 
id="User-defined--card--types"></a>User-defined card types </h3>
 <div class="outline-text-3" id="text-4_6">
 
 
+
 <p>
-Finally, you can write your own elisp functions to define new kinds of
+Finally, you can write your own emacs lisp functions to define new kinds of
 topics. Any new topic type will need to be added to
 <code>org-drill-card-type-alist</code>, and cards using that topic type will 
need to have
 it as the value of their <code>DRILL_CARD_TYPE</code> property. For an 
example, see the
@@ -623,23 +592,8 @@ function <code>org-drill-present-spanish-verb</code>, 
which defines the new topi
 <p>
 See the file <a href="spanish.html">spanish.org</a> for a full set of example 
material.
 </p>
-</div>
-
-</div>
-
-<div id="outline-container-4_7" class="outline-3">
-<h3 id="sec-4_7">Comments </h3>
-<div class="outline-text-3" id="text-4_7">
 
 
-<p>
-In org mode, comment lines start with '#'. The rest of the line is ignored by
-Org (apart from some special cases). You may sometimes want to put material in
-comments which you do not want to see when you are being tested on the
-item. For this reason, comments are always rendered invisible while items are
-being tested.
-</p>
-
 </div>
 </div>
 
@@ -717,10 +671,31 @@ answer, or 'e' to finish the drill and jump to the 
current topic for editing
 </div>
 
 <div id="outline-container-6" class="outline-2">
-<h2 id="sec-6"><a name="leeches" id="leeches"></a>Leeches </h2>
+<h2 id="sec-6">Cram mode </h2>
 <div class="outline-text-2" id="text-6">
 
 
+
+<p>
+There are some situations, such as before an exam, where you will want to
+revise all of your cards regardless of when they are next due for review.
+</p>
+<p>
+To do this, run a <i>cram session</i> with the <code>org-drill-cram</code> 
command (<code>M-x org-drill-cram RET</code>). This works the same as a normal 
drill session, except
+that all items are considered due for review unless you reviewed them within
+the last 12 hours (you can change the number of hours by customising the
+variable <code>org-drill-cram-hours</code>).
+</p>
+
+</div>
+
+</div>
+
+<div id="outline-container-7" class="outline-2">
+<h2 id="sec-7"><a name="leeches" id="leeches"></a>Leeches </h2>
+<div class="outline-text-2" id="text-7">
+
+
 <p>
 From the Anki website, <a 
href="http://ichi2.net/anki/wiki/Leeches";>http://ichi2.net/anki/wiki/Leeches</a>:
 </p>
@@ -771,30 +746,297 @@ See <a 
href="http://www.supermemo.com/help/leech.htm";>the SuperMemo website</a>
 
 </div>
 
-<div id="outline-container-7" class="outline-2">
-<h2 id="sec-7">Cram mode </h2>
-<div class="outline-text-2" id="text-7">
+<div id="outline-container-8" class="outline-2">
+<h2 id="sec-8">Customisation </h2>
+<div class="outline-text-2" id="text-8">
 
 
 
 <p>
-There are some situations, such as before an exam, where you will want to
-revise all of your cards regardless of when they are next due for review.
+Org-Drill has several settings which you change using
+<code>M-x customize-group org-drill &lt;RET&gt;</code>. Alternatively you can 
change these
+settings by adding elisp code to your configuration file (<code>.emacs</code>).
 </p>
+
+
+</div>
+
+<div id="outline-container-8_1" class="outline-3">
+<h3 id="sec-8_1">Appearance of items during drill sessions </h3>
+<div class="outline-text-3" id="text-8_1">
+
+
+
 <p>
-To do this, run a <i>cram session</i> with the <code>org-drill-cram</code> 
command (<code>M-x org-drill-cram RET</code>). This works the same as a normal 
drill session, except
-that all items are considered due for review unless you reviewed them within
-the last 12 hours (you can change the number of hours by customising the
-variable <code>org-drill-cram-hours</code>).
+If you want cloze-deleted text to show up in a special font within Org mode
+buffers, add this to your .emacs:
+</p>
+
+
+
+<pre class="example">(setq org-drill-use-visible-cloze-face-p t)
+</pre>
+
+
+
+<p>
+Item headings may contain information that "gives away" the answer to the item,
+either in the heading text or in tags. If you want item headings to be made
+invisible while each item is being tested, add:
 </p>
 
+
+
+<pre class="example">(setq org-drill-hide-item-headings-p t)
+</pre>
+
+
+
+
 </div>
 
 </div>
 
-<div id="outline-container-8" class="outline-2">
-<h2 id="sec-8">Incremental reading </h2>
-<div class="outline-text-2" id="text-8">
+<div id="outline-container-8_2" class="outline-3">
+<h3 id="sec-8_2">Duration of drill sessions </h3>
+<div class="outline-text-3" id="text-8_2">
+
+
+
+<p>
+By default, a drill session will end when either 30 items have been
+successfully reviewed, or 20 minutes have passed. To change this behaviour, use
+the following settings.
+</p>
+
+
+
+<pre class="example">(setq org-drill-maximum-items-per-session 40)
+(setq org-drill-maximum-duration 30)   ; 30 minutes
+</pre>
+
+
+
+<p>
+If either of these variables is set to nil, then item count or elapsed time
+will not count as reasons to end the session. If both variables are nil, the
+session will not end until <i>all</i> outstanding items have been reviewed.
+</p>
+
+</div>
+
+</div>
+
+<div id="outline-container-8_3" class="outline-3">
+<h3 id="sec-8_3">Spaced repetition algorithm </h3>
+<div class="outline-text-3" id="text-8_3">
+
+
+
+
+</div>
+
+<div id="outline-container-8_3_1" class="outline-4">
+<h4 id="sec-8_3_1">Choice of algorithm </h4>
+<div class="outline-text-4" id="text-8_3_1">
+
+
+
+<p>
+Org-Drill supports three different spaced repetition algorithms, all based on
+SuperMemo algorithms. These are:
+</p><dl>
+<dt><a href="http://www.supermemo.com/english/ol/sm2.htm";>SM2</a></dt><dd>
+an early algorithm, used in SuperMemo 2.0 (1988), which remains very
+popular &ndash; Anki and Mnemosyne, two of the most popular spaced repetition
+programs, use SM2. This algorithm stores an 'ease factor' for each item,
+which is modified each time you rate your recall of the item.
+</dd>
+<dt><a href="http://www.supermemo.com/english/ol/sm5.htm";>SM5</a> 
(default)</dt><dd>
+used in SuperMemo 5.0 (1989). This algorithm uses 'ease
+factors' but also uses a persistent, per-user 'matrix of optimal factors'
+which is also modified after each item repetition.
+</dd>
+<dt>Simple8</dt><dd>
+an experimental algorithm based on the <a 
href="http://www.supermemo.com/english/algsm8.htm";>SM8</a> algorithm. SM8 is 
used
+in SuperMemo 8.0 (1998) and is almost identical to SM11 which is
+used in SuperMemo 2002. Like SM5, it uses a matrix of optimal
+factors. Simple8 differs from SM8 in that it does not adapt the
+matrix to the individual user, though it does adapt each item's
+'ease factor'.
+
+</dd>
+</dl>
+
+
+<p>
+If you want Org-Drill to use the <code>SM2</code> algorithm, put the following 
in your
+<code>.emacs</code>:
+</p>
+
+
+
+<pre class="example">(setq org-drill-spaced-repetition-algorithm 'sm2)
+</pre>
+
+
+
+
+</div>
+
+</div>
+
+<div id="outline-container-8_3_2" class="outline-4">
+<h4 id="sec-8_3_2">Random variation of repetition intervals </h4>
+<div class="outline-text-4" id="text-8_3_2">
+
+
+
+<p>
+The intervals generated by the SM2 and SM5 algorithms are pretty
+deterministic. If you tend to add items in large, infrequent batches, the lack
+of variation in interval scheduling can lead to the problem of "lumpiness" --
+one day a large batch of items are due for review, the next there is almost
+nothing, a few days later another big pile of items is due.
+</p>
+<p>
+This problem can be ameliorated by adding some random "noise" to the interval
+scheduling algorithm. The author of SuperMemo actually recommends this approach
+for the SM5 algorithm, and Org-Drill's implementation uses <a 
href="http://www.supermemo.com/english/ol/sm5.htm";>his code</a>.
+</p>
+<p>
+To enable random "noise" for item intervals, set the variable
+<code>org-drill-add-random-noise-to-intervals-p</code> to true by putting the 
following in
+your <code>.emacs</code>:
+</p>
+
+
+
+<pre class="example">(setq org-drill-add-random-noise-to-intervals-p t)
+</pre>
+
+
+
+
+</div>
+
+</div>
+
+<div id="outline-container-8_3_3" class="outline-4">
+<h4 id="sec-8_3_3">Adjustment for early or late review of items </h4>
+<div class="outline-text-4" id="text-8_3_3">
+
+
+
+<p>
+Reviewing items earlier or later than their scheduled review date may affect
+how soon the next review date should be scheduled. Code to make this adjustment
+is also presented on the SuperMemo website. It can be enabled with:
+</p>
+
+
+
+<pre class="example">(setq 
org-drill-adjust-intervals-for-early-and-late-repetitions-p t)
+</pre>
+
+
+
+<p>
+This will affect both early and late repetitions if the Simple8 algorithm is
+used. For the SM5 algorithm it will affect early repetitions only. It has no
+effect on the SM2 algorithm.
+</p>
+
+</div>
+
+</div>
+
+<div id="outline-container-8_3_4" class="outline-4">
+<h4 id="sec-8_3_4">Adjusting item difficulty globally </h4>
+<div class="outline-text-4" id="text-8_3_4">
+
+
+
+<p>
+The <code>learn fraction</code> is a global value which affects how quickly 
the intervals
+(times between each retest of an item) increase with successive repetitions,
+for <i>all</i> items. The default value is 0.5, and this is the value used in
+SuperMemo. For some collections of information, you may find that you are
+reviewing items too often (they are too easy and the workload is too high), or
+too seldom (you are failing them too often). In these situations, it is
+possible to alter the learn fraction from its default in order to increase or
+decrease the frequency of repetition of items over time. Increasing the value
+will make the time intervals grow faster, and lowering it will make them grow
+more slowly. The table below shows the growth in intervals (in days) with some
+different values of the learn fraction (F). The table assumes that the item is
+successfully recalled each time, with an average quality of just under 4.
+</p>
+
+<table border="2" cellspacing="0" cellpadding="6" rules="groups" 
frame="hsides">
+<caption></caption>
+<colgroup><col class="left" /><col class="right" /><col class="right" /><col 
class="right" /><col class="right" /><col class="right" />
+</colgroup>
+<thead>
+<tr><th scope="col" class="left">Repetition</th><th scope="col" 
class="right">F=0.3</th><th scope="col" class="right">F=0.4</th><th scope="col" 
class="right"><b>F=0.5</b></th><th scope="col" class="right">F=0.6</th><th 
scope="col" class="right">F=0.7</th></tr>
+</thead>
+<tbody>
+<tr><td class="left">1st</td><td class="right">2</td><td 
class="right">2</td><td class="right">2</td><td class="right">2</td><td 
class="right">2</td></tr>
+<tr><td class="left">2nd</td><td class="right">7</td><td 
class="right">7</td><td class="right">7</td><td class="right">7</td><td 
class="right">7</td></tr>
+<tr><td class="left">5th</td><td class="right">26</td><td 
class="right">34</td><td class="right">46</td><td class="right">63</td><td 
class="right">85</td></tr>
+<tr><td class="left">10th</td><td class="right">85</td><td 
class="right">152</td><td class="right">316</td><td class="right">743</td><td 
class="right">1942</td></tr>
+<tr><td class="left">15th</td><td class="right">233</td><td 
class="right">501</td><td class="right">1426</td><td class="right">5471</td><td 
class="right">27868</td></tr>
+</tbody>
+</table>
+
+
+<p>
+To alter the learn fraction, put the following in your .emacs:
+</p>
+
+
+
+<pre class="src src-elisp"><span style="color: #696969;">(</span>setq 
org-drill-learn-fraction 0.45<span style="color: #696969;">)</span>   <span 
style="color: #db7093;">; </span><span style="color: #db7093;">change the value 
as desired
+</span></pre>
+
+
+
+
+</div>
+</div>
+
+</div>
+
+<div id="outline-container-8_4" class="outline-3">
+<h3 id="sec-8_4">Per-file customisation settings </h3>
+<div class="outline-text-3" id="text-8_4">
+
+
+
+<p>
+Most of the above settings are safe as file-local variables. This means you can
+include a commented section like this at the end of your .org file to apply
+special settings when running a Drill session using that file:
+</p>
+
+
+
+<pre class="src src-org"><span style="color: #db7093;"># Local 
Variables&#58;</span>
+<span style="color: #db7093;"># org-drill-maximum-items-per-session:    
50</span>
+<span style="color: #db7093;"># org-drill-spaced-repetition-algorithm:  
simple8</span>
+<span style="color: #db7093;"># End:</span>
+</pre>
+
+
+
+
+</div>
+</div>
+
+</div>
+
+<div id="outline-container-9" class="outline-2">
+<h2 id="sec-9">Incremental reading </h2>
+<div class="outline-text-2" id="text-9">
 
 
 
@@ -827,26 +1069,26 @@ captured facts.
 
 
 
-<pre class="example">(setq org-capture-templates
-       `(("u"
-         "Task: Read this URL"
+<pre class="src src-elisp"><span style="color: #696969;">(</span>setq 
org-capture-templates
+       `<span style="color: #696969;">((</span><span style="color: 
#008b00;">"u"</span>
+         <span style="color: #008b00;">"Task: Read this URL"</span>
          entry
-         (file+headline "tasks.org" "Articles To Read")
-         ,(concat "* TODO Read article: '%:description'\nURL: %c\n\n")
-         :empty-lines 1
-         :immediate-finish t)
+         <span style="color: #696969;">(</span>file+headline <span 
style="color: #008b00;">"tasks.org"</span> <span style="color: 
#008b00;">"Articles To Read"</span><span style="color: #696969;">)</span>
+         ,<span style="color: #696969;">(</span>concat <span style="color: 
#008b00;">"* TODO Read article: '%:description'\nURL: %c\n\n"</span><span 
style="color: #696969;">)</span>
+         <span style="color: #4169e1;">:empty-lines</span> 1
+         <span style="color: #4169e1;">:immediate-finish</span> t<span 
style="color: #696969;">)</span>
 
-        ("w"
-         "Capture web snippet"
+        <span style="color: #696969;">(</span><span style="color: 
#008b00;">"w"</span>
+         <span style="color: #008b00;">"Capture web snippet"</span>
          entry
-         (file+headline "my-facts.org" "Inbox")
-         ,(concat "* Fact: '%:description'        :"
-                  (format "%s" org-drill-question-tag)
-                  ":\n:PROPERTIES:\n:DATE_ADDED: %u\n:SOURCE_URL: 
%c\n:END:\n\n%i\n%?\n")
-         :empty-lines 1
-         :immediate-finish t)
-        ;; ...other capture templates...
-    ))
+         <span style="color: #696969;">(</span>file+headline <span 
style="color: #008b00;">"my-facts.org"</span> <span style="color: 
#008b00;">"Inbox"</span><span style="color: #696969;">)</span>
+         ,<span style="color: #696969;">(</span>concat <span style="color: 
#008b00;">"* Fact: '%:description'        :"</span>
+                  <span style="color: #696969;">(</span>format <span 
style="color: #008b00;">"%s"</span> org-drill-question-tag<span style="color: 
#696969;">)</span>
+                  <span style="color: #008b00;">":\n:PROPERTIES:\n:DATE_ADDED: 
%u\n:SOURCE_URL: %c\n:END:\n\n%i\n%?\n"</span><span style="color: 
#696969;">)</span>
+         <span style="color: #4169e1;">:empty-lines</span> 1
+         <span style="color: #4169e1;">:immediate-finish</span> t<span 
style="color: #696969;">)</span>
+        <span style="color: #db7093;">;; </span><span style="color: 
#db7093;">...other capture templates...
+</span>    <span style="color: #696969;">))</span>
 </pre>
 
 
@@ -924,10 +1166,10 @@ something like:
 
 
 
-<pre class="example">** Fact: 'Tuberculosis - Wikipedia, the Free 
Encyclopedia'        :drill:
-
+<pre class="src src-org"><span style="color: #4876ff; background-color: 
#000080; font-weight: bold;">** Fact: 'Tuberculosis - Wikipedia, the Free 
Encyclopedia'        </span><span style="color: #66cdaa; background-color: 
#000080; font-weight: bold;">:drill:</span><span style="color: #4876ff; 
background-color: #000080; font-weight: bold;">
+</span>
 Prevention relies on screening programs and vaccination, usually with Bacillus
-Calmette-Guérin vaccine.
+Calmette-Gu&#233;rin vaccine.
 </pre>
 
 
@@ -951,34 +1193,12 @@ templates, each of which might send its fact to a 
different file or subheading,
 or give it different tags or properties, for example.
 </p>
 
-</div>
-
-</div>
-
-<div id="outline-container-9" class="outline-2">
-<h2 id="sec-9">Still to do </h2>
-<div class="outline-text-2" id="text-9">
-
-
-<ul>
-<li>
-<code>org-drill-question-tag</code> should use a tag match string, rather than 
a
-single tag? Can use <code>org-make-tag-matcher</code>.
-</li>
-<li>
-perhaps take account of item priorities, showing high priority items first
-</li>
-<li>
-get tooltips to work for old/new/etc counts during review?
-</li>
-</ul>
-
 </div>
 </div>
 <div id="postamble">
 <p class="author"> Author: Paul Sexton
 </p>
-<p class="date"> Date: 2011-04-04 10:18:44 </p>
+<p class="date"> Date: 2011-04-08 16:00:36 </p>
 <p class="creator">HTML generated by org-mode 7.4 in emacs 23</p>
 </div>
 </div>
diff --git a/README.org b/README.org
index 1fbc98a510..77688c2ba3 100755
--- a/README.org
+++ b/README.org
@@ -22,72 +22,21 @@ student in different ways.
 
 For more on the spaced repetition algorithm, and examples of other programs
 that use it, see:
-- [[http://supermemo.com/index.htm][SuperMemo]] (the SM5 algorithm is 
discussed [[http://www.supermemo.com/english/ol/sm5.htm][here]])
+- [[http://supermemo.com/index.htm][SuperMemo]] (see descriptions of the SM2, 
SM5 and SM8 algorithms)
 - [[http://ichi2.net/anki/][Anki]]
 - [[http://mnemosyne-proj.org/index.php][Mnemosyne]]
 
 
-* Installation and Customisation
+* Installation
 
 
 Put the following in your =.emacs=. You will also need to make sure that Org's
 "contrib/lisp" directory is in the emacs load-path.
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC elisp
 (require 'org-drill)
-#+END_EXAMPLE
+#+END_SRC
 
-I also recommend the following, so that items are always eventually retested,
-even when you remember them well.
-
-#+BEGIN_EXAMPLE
-(setq org-learn-always-reschedule t)
-#+END_EXAMPLE
-
-If you want cloze-deleted text to show up in a special font within Org mode
-buffers, also add:
-
-#+BEGIN_EXAMPLE
-(setq org-drill-use-visible-cloze-face-p t)
-#+END_EXAMPLE
-
-Item headings may contain information that "gives away" the answer to the item,
-either in the heading text or in tags. If you want item headings to be made
-invisible while each item is being tested, add:
-
-#+BEGIN_EXAMPLE
-(setq org-drill-hide-item-headings-p t)
-#+END_EXAMPLE
-
-Org-Drill supports two different spaced repetition algorithms -- SM5 (the
-default, implemented by =org-learn=) and SM2. SM2 is an earlier algorithm which
-remains very popular -- Anki and Mnemosyne, two of the most popular spaced
-repetition programs, use SM2.
-
-If you want Org-Drill to use the SM2 algorithm, put the following in your
-=.emacs=:
-
-#+BEGIN_EXAMPLE
-(setq org-drill-spaced-repetition-algorithm 'sm2)
-#+END_EXAMPLE
-
-The intervals generated by the SM2 and SM5 algorithms are pretty
-deterministic. If you tend to add items in large, infrequent batches, the lack
-of variation in interval scheduling can lead to the problem of "lumpiness" --
-one day a large batch of items are due for review, the next there is almost
-nothing, a few days later another big pile of items is due.
-
-This problem can be ameliorated by adding some random "noise" to the interval
-scheduling algorithm. The author of SuperMemo actually recommends this approach
-for the SM5 algorithm, and Org-Drill's implementation uses 
[[http://www.supermemo.com/english/ol/sm5.htm][his code]].
-
-To enable random "noise" for item intervals, set the variable
-=org-drill-add-random-noise-to-intervals-p= to true by putting the following in
-your =.emacs=:
-
-#+BEGIN_EXAMPLE
-(setq org-drill-add-random-noise-to-intervals-p t)
-#+END_EXAMPLE
 
 
 * Demonstration
@@ -104,8 +53,9 @@ drill topics are written.
 
 
 Org-Drill uses org mode topics as 'drill items'. To be used as a drill item,
-the topic must have a tag that matches =org-drill-question-tag=. This is
-=:drill:= by default. Any other org topics will be ignored.
+the topic must have a tag that matches the value of
+=org-drill-question-tag=. This is =:drill:= by default. Any other org topics
+will be ignored.
 
 You don't need to schedule the topics initially.  However =org-drill= *will*
 recognise items that have been scheduled previously with
@@ -113,28 +63,41 @@ recognise items that have been scheduled previously with
 memorisation.
 
 How should 'drill topics' be structured? Any org topic is a legal drill topic
--- it will simply be shown with subheadings collapsed. After pressing a
-key, any hidden subheadings will be revealed, and you will be asked to rate
-your "recall" of the item.
+-- it will simply be shown with all subheadings collapsed, so thta only the
+material beneath the main item heading is visible. After pressing a key, any
+hidden subheadings will be revealed, and you will be asked to rate your
+"recall" of the item.
 
 This will be adequate for some items, but usually you will want to write items
 where you have more control over what information is hidden from the user for
-recall purposes.
+recall purposes. For this reason, some other card types are defined, including:
+- [[Two-sided cards]]
+- [[Multi-sided cards]]
+- [[Multicloze cards]]
+- [[User-defined card types]]
+
+*A note about comments:* In org mode, comment lines start with '#'. The rest of
+the line is ignored by Org (apart from some special cases). You may sometimes
+want to put material in comments which you do not want to see when you are
+being tested on the item. For this reason, comments are always rendered
+invisible while items are being tested.
+
 
 ** Simple topics
 
+
 The simplest drill topic has no special structure. When such a topic is
 presented during a drill session, any subheadings are "collapsed" with their
 contents hidden. So, you could include the question as text beneath the main
 heading, and the answer within a subheading. For example:
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC org
 * Item                                   :drill:
 What is the capital city of Estonia?
 
 ** The Answer
 Tallinn.
-#+END_EXAMPLE
+#+END_SRC
 
 When this item is presented for review, the text beneath the main heading will
 be visible, but the contents of the subheading ("The Answer") will be hidden.
@@ -142,6 +105,7 @@ be visible, but the contents of the subheading ("The 
Answer") will be hidden.
 
 ** Cloze deletion
 
+
 Cloze deletion can be used in any drill topic regardless of whether it is
 otherwise 'simple', or is one of the specialised topic types discussed
 below. To use cloze deletion, one or more parts of the body of the topic is
@@ -150,10 +114,11 @@ so]. When the topic is presented for review, the text 
within square brackets
 will be obscured. The text is then revealed after the user presses a key. For
 example:
 
-#+BEGIN_EXAMPLE
+
+#+BEGIN_SRC org
 * Item                                   :drill:
 The capital city of Estonia is [Tallinn].
-#+END_EXAMPLE
+#+END_SRC
 
 During review, the user will see:
 
@@ -171,10 +136,10 @@ the rest of the text is hidden.
 
 Example:
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC org
 Type 1 hypersensitivity reactions are mediated by [immunoglobulin E|molecule]
 and [mast cells|cell type].
-#+END_EXAMPLE
+#+END_SRC
 
 #+BEGIN_QUOTE
 Type 1 hypersensitivity reactions are mediated by
@@ -186,6 +151,7 @@ and @<font style="background-color: blue;" color="cyan">
 
 
 ** Two-sided cards
+# <<Two-sided cards>>
 
 The remaining topic types all use the topic property, =DRILL_CARD_TYPE=. This
 property tells =org-drill= which function to use to present the topic during
@@ -202,7 +168,7 @@ A two sided card can have more than 2 subheadings, but all 
subheadings after
 the first two are considered as "notes" and will always be hidden during topic
 review.
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC org
 * Noun                                               :drill:
     :PROPERTIES:
     :DRILL_CARD_TYPE: twosided
@@ -219,7 +185,7 @@ the woman
 ** Example sentence
 ¿Quién fue esa mujer?
 Who was that woman?
-#+END_EXAMPLE
+#+END_SRC
 
 In this example, the user will be shown the main text -- "Translate this word"
 -- and either 'la mujer', /or/ 'the woman', at random. The section 'Example
@@ -228,12 +194,14 @@ not one of the first two 'sides' of the topic.
 
 
 ** Multi-sided cards
+# <<Multi-sided cards>>
+
 
 The =multisided= card type is similar to =twosided=, except that any
 subheading has a chance of being presented during the topic review. One
 subheading is always shown and all others are always hidden.
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC org
 * Noun                                               :drill:
     :PROPERTIES:
     :DRILL_CARD_TYPE: multisided
@@ -249,28 +217,31 @@ the table
 
 ** Picture
 [[file:table.jpg][PICTURE]]
-#+END_EXAMPLE
+#+END_SRC
 
 The user will be shown the main text and either 'la mujer', /or/ 'the woman',
 /or/ a picture of a table.
 
+
 ** Multi-cloze cards
+# <<Multi-cloze cards>>
+
 
 Often, you will wish to create cards out of sentences that express several
 facts, such as the following:
 
-#+BEGIN_QUOTE
+#+BEGIN_SRC org
 The capital city of New Zealand is Wellington, which is located in the
 South Island and has a population of about 400,000.
-#+END_QUOTE
+#+END_SRC
 
 There is more than one fact in this statement -- you could create a single
 'simple' card with all the facts marked as cloze text, like so:
 
-#+BEGIN_QUOTE
+#+BEGIN_SRC org
 The capital city of [New Zealand] is [Wellington], which is located in
-[the South Island] and has a population of about [400,000].
-#+END_QUOTE
+the [North|North/South] Island and has a population of about [400,000].
+#+END_SRC
 
 But this card will be difficult to remember. If you get just one of the 4
 hidden facts wrong, you will fail the card. A card like this is likely to
@@ -280,7 +251,7 @@ A better way to express all these facts using 'simple' 
cards is to create
 several cards, with one fact per card. You might end up with something
 like this:
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC org
 * Fact
 The capital city of [New Zealand] is Wellington, which has a population of
 about 400,000.
@@ -295,16 +266,16 @@ about [400,000].
 
 * Fact
 The capital city of [New Zealand] is Wellington, which is located in the
-the South Island.
+the North Island.
 
 * Fact
 The capital city of New Zealand is [Wellington], which is located in
-the South Island.
+the North Island.
 
 * Fact
 The capital city of New Zealand is Wellington, which is located in
-[the South Island].
-#+END_EXAMPLE
+the [North|North/South] Island.
+#+END_SRC
 
 However, this is really cumbersome. The 'multicloze' card type exists for this
 situation. Multicloze cards behave like 'simple' cards, except that when there
@@ -317,19 +288,22 @@ but change its card type to 'multicloze'. Each time the 
card is presented for
 review, one of 'New Zealand', 'Wellington', 'the South Island' or '400,000'
 will be hidden.
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC org
 * Fact
   :PROPERTIES:
   :DRILL_CARD_TYPE: multicloze
   :END:
 
 The capital city of [New Zealand] is [Wellington], which is located in
-[the South Island] and has a population of about [400,000].
-#+END_EXAMPLE
+the [North|North/South] Island and has a population of about [400,000].
+#+END_SRC
+
 
-** User-defined topic types
+** User-defined card types
+# <<User-defined card types>>
 
-Finally, you can write your own elisp functions to define new kinds of
+
+Finally, you can write your own emacs lisp functions to define new kinds of
 topics. Any new topic type will need to be added to
 =org-drill-card-type-alist=, and cards using that topic type will need to have
 it as the value of their =DRILL_CARD_TYPE= property. For an example, see the
@@ -338,13 +312,6 @@ function =org-drill-present-spanish-verb=, which defines 
the new topic type
 
 See the file [[file:spanish.org][spanish.org]] for a full set of example 
material.
 
-** Comments
-
-In org mode, comment lines start with '#'. The rest of the line is ignored by
-Org (apart from some special cases). You may sometimes want to put material in
-comments which you do not want to see when you are being tested on the
-item. For this reason, comments are always rendered invisible while items are
-being tested.
 
 
 * Running the drill session
@@ -384,6 +351,19 @@ answer, or 'e' to finish the drill and jump to the current 
topic for editing
 (your progress up to that point will be saved).
 
 
+* Cram mode
+
+
+There are some situations, such as before an exam, where you will want to
+revise all of your cards regardless of when they are next due for review.
+
+To do this, run a /cram session/ with the =org-drill-cram= command (=M-x
+org-drill-cram RET=). This works the same as a normal drill session, except
+that all items are considered due for review unless you reviewed them within
+the last 12 hours (you can change the number of hours by customising the
+variable =org-drill-cram-hours=).
+
+
 * Leeches
 # <<leeches>>
 
@@ -416,17 +396,164 @@ card.
 See [[http://www.supermemo.com/help/leech.htm][the SuperMemo website]] for 
more on leeches.
 
 
-* Cram mode
+* Customisation
 
 
-There are some situations, such as before an exam, where you will want to
-revise all of your cards regardless of when they are next due for review.
+Org-Drill has several settings which you change using
+=M-x customize-group org-drill <RET>=. Alternatively you can change these
+settings by adding elisp code to your configuration file (=.emacs=).
 
-To do this, run a /cram session/ with the =org-drill-cram= command (=M-x
-org-drill-cram RET=). This works the same as a normal drill session, except
-that all items are considered due for review unless you reviewed them within
-the last 12 hours (you can change the number of hours by customising the
-variable =org-drill-cram-hours=).
+
+** Appearance of items during drill sessions
+
+
+If you want cloze-deleted text to show up in a special font within Org mode
+buffers, add this to your .emacs:
+
+#+BEGIN_SRC elisp
+(setq org-drill-use-visible-cloze-face-p t)
+#+END_SRC
+
+Item headings may contain information that "gives away" the answer to the item,
+either in the heading text or in tags. If you want item headings to be made
+invisible while each item is being tested, add:
+
+#+BEGIN_SRC elisp
+(setq org-drill-hide-item-headings-p t)
+#+END_SRC
+
+
+** Duration of drill sessions
+
+
+By default, a drill session will end when either 30 items have been
+successfully reviewed, or 20 minutes have passed. To change this behaviour, use
+the following settings.
+
+#+BEGIN_SRC elisp
+(setq org-drill-maximum-items-per-session 40)
+(setq org-drill-maximum-duration 30)   ; 30 minutes
+#+END_SRC
+
+If either of these variables is set to nil, then item count or elapsed time
+will not count as reasons to end the session. If both variables are nil, the
+session will not end until /all/ outstanding items have been reviewed.
+
+
+** Spaced repetition algorithm
+
+
+*** Choice of algorithm
+
+
+Org-Drill supports three different spaced repetition algorithms, all based on
+SuperMemo algorithms. These are:
+- [[http://www.supermemo.com/english/ol/sm2.htm][SM2]] :: an early algorithm, 
used in SuperMemo 2.0 (1988), which remains very
+  popular -- Anki and Mnemosyne, two of the most popular spaced repetition
+  programs, use SM2. This algorithm stores an 'ease factor' for each item,
+  which is modified each time you rate your recall of the item.
+- [[http://www.supermemo.com/english/ol/sm5.htm][SM5]] (default) :: used in 
SuperMemo 5.0 (1989). This algorithm uses 'ease
+     factors' but also uses a persistent, per-user 'matrix of optimal factors'
+     which is also modified after each item repetition.
+- Simple8 :: an experimental algorithm based on the 
[[http://www.supermemo.com/english/algsm8.htm][SM8]] algorithm. SM8 is used
+             in SuperMemo 8.0 (1998) and is almost identical to SM11 which is
+             used in SuperMemo 2002. Like SM5, it uses a matrix of optimal
+             factors. Simple8 differs from SM8 in that it does not adapt the
+             matrix to the individual user, though it does adapt each item's
+             'ease factor'.
+
+
+If you want Org-Drill to use the =SM2= algorithm, put the following in your
+=.emacs=:
+
+#+BEGIN_SRC elisp
+(setq org-drill-spaced-repetition-algorithm 'sm2)
+#+END_SRC
+
+
+*** Random variation of repetition intervals
+
+
+The intervals generated by the SM2 and SM5 algorithms are pretty
+deterministic. If you tend to add items in large, infrequent batches, the lack
+of variation in interval scheduling can lead to the problem of "lumpiness" --
+one day a large batch of items are due for review, the next there is almost
+nothing, a few days later another big pile of items is due.
+
+This problem can be ameliorated by adding some random "noise" to the interval
+scheduling algorithm. The author of SuperMemo actually recommends this approach
+for the SM5 algorithm, and Org-Drill's implementation uses 
[[http://www.supermemo.com/english/ol/sm5.htm][his code]].
+
+To enable random "noise" for item intervals, set the variable
+=org-drill-add-random-noise-to-intervals-p= to true by putting the following in
+your =.emacs=:
+
+#+BEGIN_SRC elisp
+(setq org-drill-add-random-noise-to-intervals-p t)
+#+END_SRC
+
+
+*** Adjustment for early or late review of items
+
+
+Reviewing items earlier or later than their scheduled review date may affect
+how soon the next review date should be scheduled. Code to make this adjustment
+is also presented on the SuperMemo website. It can be enabled with:
+
+#+BEGIN_SRC elisp
+(setq org-drill-adjust-intervals-for-early-and-late-repetitions-p t)
+#+END_SRC
+
+This will affect both early and late repetitions if the Simple8 algorithm is
+used. For the SM5 algorithm it will affect early repetitions only. It has no
+effect on the SM2 algorithm.
+
+
+*** Adjusting item difficulty globally
+
+
+The =learn fraction= is a global value which affects how quickly the intervals
+(times between each retest of an item) increase with successive repetitions,
+for /all/ items. The default value is 0.5, and this is the value used in
+SuperMemo. For some collections of information, you may find that you are
+reviewing items too often (they are too easy and the workload is too high), or
+too seldom (you are failing them too often). In these situations, it is
+possible to alter the learn fraction from its default in order to increase or
+decrease the frequency of repetition of items over time. Increasing the value
+will make the time intervals grow faster, and lowering it will make them grow
+more slowly. The table below shows the growth in intervals (in days) with some
+different values of the learn fraction (F). The table assumes that the item is
+successfully recalled each time, with an average quality of just under 4.
+
+
+| Repetition | F=0.3 | F=0.4 | *F=0.5* | F=0.6 | F=0.7 |
+|------------+-------+-------+---------+-------+-------|
+| 1st        |     2 |     2 |       2 |     2 |     2 |
+| 2nd        |     7 |     7 |       7 |     7 |     7 |
+| 5th        |    26 |    34 |      46 |    63 |    85 |
+| 10th       |    85 |   152 |     316 |   743 |  1942 |
+| 15th       |   233 |   501 |    1426 |  5471 | 27868 |
+
+To alter the learn fraction, put the following in your .emacs:
+
+#+BEGIN_SRC elisp
+(setq org-drill-learn-fraction 0.45)   ; change the value as desired
+#+END_SRC
+
+
+** Per-file customisation settings
+
+
+Most of the above settings are safe as file-local variables. This means you can
+include a commented section like this at the end of your .org file to apply
+special settings when running a Drill session using that file:
+
+#+BEGIN_SRC org
+# Local Variables:
+# org-drill-maximum-items-per-session:    50
+# org-drill-spaced-repetition-algorithm:  simple8
+# End:
+#+END_SRC org
 
 
 * Incremental reading
@@ -454,7 +581,7 @@ An example of using Org-Drill for incremental reading is 
given below. First,
 and most importantly, we need to define a couple of =org-capture= templates for
 captured facts.
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC elisp
 (setq org-capture-templates
        `(("u"
          "Task: Read this URL"
@@ -475,7 +602,7 @@ captured facts.
          :immediate-finish t)
         ;; ...other capture templates...
     ))
-#+END_EXAMPLE
+#+END_SRC
 
 Using these templates and =org-protocol=, you can set up buttons in your web
 browser to:
@@ -527,12 +654,12 @@ your "fact" file in Emacs. You should see that each piece 
of text you selected
 has been turned into a drill item. Continuing the above example, you would see
 something like:
 
-#+BEGIN_EXAMPLE
+#+BEGIN_SRC org
 ** Fact: 'Tuberculosis - Wikipedia, the Free Encyclopedia'        :drill:
 
 Prevention relies on screening programs and vaccination, usually with Bacillus
 Calmette-Guérin vaccine.
-#+END_EXAMPLE
+#+END_SRC
 
 You need to edit this fact so it makes sense independent of its context, as
 that is how it will be presented to you in future. The easiest way to turn the
@@ -548,7 +675,8 @@ templates, each of which might send its fact to a different 
file or subheading,
 or give it different tags or properties, for example.
 
 
-* Still to do
+* Still to do                                                         
:noexport:
+
 
 - =org-drill-question-tag= should use a tag match string, rather than a
   single tag? Can use =org-make-tag-matcher=.
diff --git a/org-drill.el b/org-drill.el
index f3687f0a56..7c35915fc8 100755
--- a/org-drill.el
+++ b/org-drill.el
@@ -1,18 +1,17 @@
-;;; org-drill.el - Self-testing with org-learn
+;;; org-drill.el - Self-testing using spaced repetition
 ;;;
 ;;; Author: Paul Sexton <eeeickythump@gmail.com>
-;;; Version: 1.7
+;;; Version: 2.0
 ;;; Repository at http://bitbucket.org/eeeickythump/org-drill/
 ;;;
 ;;;
 ;;; Synopsis
 ;;; ========
 ;;;
-;;; Uses the spaced repetition algorithm in `org-learn' to conduct interactive
+;;; Uses the SuperMemo spaced repetition algorithms to conduct interactive
 ;;; "drill sessions", where the material to be remembered is presented to the
 ;;; student in random order. The student rates his or her recall of each item,
-;;; and this information is fed back to `org-learn' to schedule the item for
-;;; later revision.
+;;; and this information is used to schedule the item for later revision.
 ;;;
 ;;; Each drill session can be restricted to topics in the current buffer
 ;;; (default), one or several files, all agenda files, or a subtree. A single
@@ -45,7 +44,6 @@ by `org-drill'."
   :type 'string)
 
 
-
 (defcustom org-drill-maximum-items-per-session
   30
   "Each drill session will present at most this many topics for review.
@@ -67,13 +65,28 @@ Nil means unlimited."
   2
   "If the quality of recall for an item is this number or lower,
 it is regarded as an unambiguous failure, and the repetition
-interval for the card is reset to 0 days.  By default this is
-2. For Mnemosyne-like behaviour, set it to 1.  Other values are
-not really sensible."
+interval for the card is reset to 0 days.  If the quality is higher
+than this number, it is regarded as successfully recalled, but the
+time interval to the next repetition will be lowered if the quality
+was near to a fail.
+
+By default this is 2, for SuperMemo-like behaviour. For
+Mnemosyne-like behaviour, set it to 1.  Other values are not
+really sensible."
   :group 'org-drill
   :type '(choice (const 2) (const 1)))
 
 
+(defcustom org-drill-forgetting-index
+  10
+  "What percentage of items do you consider it is 'acceptable' to
+forget each drill session? The default is 10%. A warning message
+is displayed at the end of the session if the percentage forgotten
+climbs above this number."
+  :group 'org-drill
+  :type 'integer)
+
+
 (defcustom org-drill-leech-failure-threshold
   15
   "If an item is forgotten more than this many times, it is tagged
@@ -174,6 +187,7 @@ during a drill session."
   ;; ver 3!  "\\(\\[.*?\\]\\|\\[.*?[[:cntrl:]]+.*?\\]\\)"
   "\\(\\[[[:cntrl:][:graph:][:space:]]*?\\)\\(\\||.+?\\)\\(\\]\\)")
 
+
 (defvar org-drill-cloze-keywords
   `((,org-drill-cloze-regexp
      (1 'org-drill-visible-cloze-face nil)
@@ -200,20 +214,62 @@ boolean value."
 (defcustom org-drill-spaced-repetition-algorithm
   'sm5
   "Which SuperMemo spaced repetition algorithm to use for scheduling items.
-Available choices are SM2 and SM5."
+Available choices are:
+- SM2 :: the SM2 algorithm, used in SuperMemo 2.0
+- SM5 :: the SM5 algorithm, used in SuperMemo 5.0
+- Simple8 :: a modified version of the SM8 algorithm. SM8 is used in
+  SuperMemo 98. The version implemented here is simplified in that while it
+  'learns' the difficulty of each item using quality grades and number of
+  failures, it does not modify the matrix of values that
+  governs how fast the inter-repetition intervals increase. A method for
+  adjusting intervals when items are reviewed early or late has been taken
+  from SM11, a later version of the algorithm, and included in Simple8."
+  :group 'org-drill
+  :type '(choice (const 'sm2) (const 'sm5) (const 'simple8)))
+
+
+
+(defcustom org-drill-optimal-factor-matrix
+  nil
+  "DO NOT CHANGE THE VALUE OF THIS VARIABLE.
+
+Persistent matrix of optimal factors, used by the SuperMemo SM5 algorithm.
+The matrix is saved (using the 'customize' facility) at the end of each
+drill session.
+
+Over time, values in the matrix will adapt to the individual user's
+pace of learning."
   :group 'org-drill
-  :type '(choice (const 'sm2) (const 'sm5)))
+  :type 'sexp)
+
 
 (defcustom org-drill-add-random-noise-to-intervals-p
   nil
   "If true, the number of days until an item's next repetition
 will vary slightly from the interval calculated by the SM2
 algorithm. The variation is very small when the interval is
-small, and scales up with the interval. The code for calculating
-random noise is adapted from Mnemosyne."
+small, but scales up with the interval."
   :group 'org-drill
   :type 'boolean)
 
+
+(defcustom org-drill-adjust-intervals-for-early-and-late-repetitions-p
+  nil
+  "If true, when the student successfully reviews an item 1 or more days
+before or after the scheduled review date, this will affect that date of
+the item's next scheduled review, according to the algorithm presented at
+ [[http://www.supermemo.com/english/algsm11.htm#Advanced%20repetitions]].
+
+Items that were reviewed early will have their next review date brought
+forward. Those that were reviewed late will have their next review
+date postponed further.
+
+Note that this option currently has no effect if the SM2 algorithm
+is used."
+  :group 'org-drill
+  :type 'boolean)
+
+
 (defcustom org-drill-cram-hours
   12
   "When in cram mode, items are considered due for review if
@@ -225,6 +281,7 @@ they were reviewed at least this many hours ago."
 (defvar *org-drill-session-qualities* nil)
 (defvar *org-drill-start-time* 0)
 (defvar *org-drill-new-entries* nil)
+(defvar *org-drill-dormant-entry-count* 0)
 (defvar *org-drill-mature-entries* nil)
 (defvar *org-drill-failed-entries* nil)
 (defvar *org-drill-again-entries* nil)
@@ -234,6 +291,41 @@ they were reviewed at least this many hours ago."
 for review unless they were already reviewed in the recent past?")
 
 
+(defcustom org-drill-learn-fraction
+  0.5
+  "Fraction between 0 and 1 that governs how quickly the spaces
+between successive repetitions increase, for all items. The
+default value is 0.5. Higher values make spaces increase more
+quickly with each successful repetition. You should only change
+this in small increments (for example 0.05-0.1) as it has an
+exponential effect on inter-repetition spacing."
+  :group 'org-drill
+  :type 'float)
+
+
+;;; Make the above settings safe as file-local variables.
+
+
+(put 'org-drill-question-tag 'safe-local-variable 'stringp)
+(put 'org-drill-maximum-items-per-session 'safe-local-variable
+     '(lambda (val) (or (stringp val) (null val))))
+(put 'org-drill-maximum-duration 'safe-local-variable
+     '(lambda (val) (or (stringp val) (null val))))
+(put 'org-drill-failure-quality 'safe-local-variable 'integerp)
+(put 'org-drill-forgetting-index 'safe-local-variable 'integerp)
+(put 'org-drill-leech-failure-threshold 'safe-local-variable 'integerp)
+(put 'org-drill-leech-method 'safe-local-variable
+     '(lambda (val) (memq val '(nil skip warn))))
+(put 'org-drill-use-visible-cloze-face-p 'safe-local-variable 'booleanp)
+(put 'org-drill-hide-item-headings-p 'safe-local-variable 'booleanp)
+(put 'org-drill-spaced-repetition-algorithm 'safe-local-variable
+     '(lambda (val) (memq val '(simple8 sm5 sm2))))
+(put 'org-drill-add-random-noise-to-intervals-p 'safe-local-variable 'booleanp)
+(put 'org-drill-adjust-intervals-for-early-and-late-repetitions-p
+     'safe-local-variable 'booleanp)
+(put 'org-drill-cram-hours 'safe-local-variable 'integerp)
+(put 'org-drill-learn-fraction 'safe-local-variable 'floatp)
+
 
 ;;;; Utilities ================================================================
 
@@ -330,9 +422,9 @@ in hours rather than days."
 
 (defun org-drill-entry-p ()
   "Is the current entry a 'drill item'?"
-  (or (org-entry-get (point) "LEARN_DATA")
-      ;;(assoc "LEARN_DATA" (org-entry-properties nil))
-      (member org-drill-question-tag (org-get-local-tags))))
+  ;;(or (org-entry-get (point) "LEARN_DATA")
+  ;;(assoc "LEARN_DATA" (org-entry-properties nil))
+  (member org-drill-question-tag (org-get-local-tags)))
 
 
 (defun org-part-of-drill-entry-p ()
@@ -374,7 +466,7 @@ drill entry."
       (and (org-drill-entry-p)
            (or (not (eql 'skip org-drill-leech-method))
                (not (org-drill-entry-leech-p)))
-           (or (null item-time)
+           (or (null item-time)         ; not scheduled
                (not (minusp             ; scheduled for today/in future
                      (- (time-to-days (current-time))
                         (time-to-days item-time))))))))))
@@ -386,7 +478,6 @@ drill entry."
          (null item-time))))
 
 
-
 (defun org-drill-entry-last-quality ()
   (let ((quality (org-entry-get (point) "DRILL_LAST_QUALITY")))
     (if quality
@@ -394,20 +485,147 @@ drill entry."
       nil)))
 
 
+(defun org-drill-entry-failure-count ()
+  (let ((quality (org-entry-get (point) "DRILL_FAILURE_COUNT")))
+    (if quality
+        (string-to-number quality)
+      0)))
+
+
+(defun org-drill-entry-average-quality (&optional default)
+  (let ((val (org-entry-get (point) "DRILL_AVERAGE_QUALITY")))
+    (if val
+        (string-to-number val)
+      (or default nil))))
+
+(defun org-drill-entry-last-interval (&optional default)
+  (let ((val (org-entry-get (point) "DRILL_LAST_INTERVAL")))
+    (if val
+        (string-to-number val)
+      (or default 0))))
+
+(defun org-drill-entry-repeats-since-fail (&optional default)
+  (let ((val (org-entry-get (point) "DRILL_REPEATS_SINCE_FAIL")))
+    (if val
+        (string-to-number val)
+      (or default 0))))
+
+(defun org-drill-entry-total-repeats (&optional default)
+  (let ((val (org-entry-get (point) "DRILL_TOTAL_REPEATS")))
+    (if val
+        (string-to-number val)
+      (or default 0))))
+
+(defun org-drill-entry-ease (&optional default)
+  (let ((val (org-entry-get (point) "DRILL_EASE")))
+    (if val
+        (string-to-number val)
+      default)))
+
+
+;;; From http://www.supermemo.com/english/ol/sm5.htm
+(defun org-drill-random-dispersal-factor ()
+  (let ((a 0.047)
+        (b 0.092)
+        (p (- (random* 1.0) 0.5)))
+    (flet ((sign (n)
+                 (cond ((zerop n) 0)
+                       ((plusp n) 1)
+                       (t -1))))
+      (/ (+ 100 (* (* (/ -1 b) (log (- 1 (* (/ b a ) (abs p)))))
+                   (sign p)))
+         100))))
+
+
+(defun org-drill-early-interval-factor (optimal-factor
+                                                optimal-interval
+                                                days-ahead)
+  "Arguments:
+- OPTIMAL-FACTOR: interval-factor if the item had been tested
+exactly when it was supposed to be.
+- OPTIMAL-INTERVAL: interval for next repetition (days) if the item had been
+tested exactly when it was supposed to be.
+- DAYS-AHEAD: how many days ahead of time the item was reviewed.
+
+Returns an adjusted optimal factor which should be used to
+calculate the next interval, instead of the optimal factor found
+in the matrix."
+  (let ((delta-ofmax (* (1- optimal-factor)
+                    (/ (+ optimal-interval
+                          (* 0.6 optimal-interval) -1) (1- 
optimal-interval)))))
+    (- optimal-factor
+       (* delta-ofmax (/ days-ahead (+ days-ahead (* 0.6 
optimal-interval)))))))
+
+
+(defun org-drill-get-item-data ()
+  "Returns a list of 6 items, containing all the stored recall
+  data for the item at point:
+- LAST-INTERVAL is the interval in days that was used to schedule the item's
+  current review date.
+- REPEATS is the number of items the item has been successfully recalled 
without
+  without any failures. It is reset to 0 upon failure to recall the item.
+- FAILURES is the total number of times the user has failed to recall the item.
+- TOTAL-REPEATS includes both successful and unsuccessful repetitions.
+- AVERAGE-QUALITY is the mean quality of recall of the item over
+  all its repetitions, successful and unsuccessful.
+- EASE is a number reflecting how easy the item is to learn. Higher is easier.
+"
+  (let ((learn-str (org-entry-get (point) "LEARN_DATA"))
+        (repeats (org-drill-entry-total-repeats :missing)))
+    (cond
+     (learn-str
+      (let ((learn-data (or (and learn-str
+                                 (read learn-str))
+                            (copy-list initial-repetition-state))))
+        (list (nth 0 learn-data)        ; last interval
+              (nth 1 learn-data)        ; repetitions
+              (org-drill-entry-failure-count)
+              (nth 1 learn-data)
+              (org-drill-entry-last-quality)
+              (nth 2 learn-data)        ; EF
+              )))
+     ((not (eql :missing repeats))
+      (list (org-drill-entry-last-interval)
+            (org-drill-entry-repeats-since-fail)
+            (org-drill-entry-failure-count)
+            (org-drill-entry-total-repeats)
+            (org-drill-entry-average-quality)
+            (org-drill-entry-ease)))
+     (t  ; virgin item
+      (list 0 0 0 0 nil nil)))))
+
+
+(defun org-drill-store-item-data (last-interval repeats failures
+                                                total-repeats meanq
+                                                ease)
+  "Stores the given data in the item at point."
+  (org-entry-delete (point) "LEARN_DATA")
+  (org-set-property "DRILL_LAST_INTERVAL"
+                    (number-to-string (round-float last-interval 4)))
+  (org-set-property "DRILL_REPEATS_SINCE_FAIL" (number-to-string repeats))
+  (org-set-property "DRILL_TOTAL_REPEATS" (number-to-string total-repeats))
+  (org-set-property "DRILL_FAILURE_COUNT" (number-to-string failures))
+  (org-set-property "DRILL_AVERAGE_QUALITY"
+                    (number-to-string (round-float meanq 3)))
+  (org-set-property "DRILL_EASE"
+                    (number-to-string (round-float ease 3))))
+
+
+
 ;;; SM2 Algorithm =============================================================
 
 
-(defun determine-next-interval-sm2 (last-interval n ef quality of-matrix)
+(defun determine-next-interval-sm2 (last-interval n ef quality
+                                                  failures meanq total-repeats)
   "Arguments:
 - LAST-INTERVAL -- the number of days since the item was last reviewed.
-- N -- the number of times the item has been successfully reviewed
+- REPEATS -- the number of times the item has been successfully reviewed
 - EF -- the 'easiness factor'
 - QUALITY -- 0 to 5
-- OF-MATRIX -- a matrix of values, used by SM5 but not by SM2.
 
-Returns a list: (INTERVAL N EF OFMATRIX), where:
+Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), 
where:
 - INTERVAL is the number of days until the item should next be reviewed
-- N is incremented by 1.
+- REPEATS is incremented by 1.
 - EF is modified based on the recall quality for the item.
 - OF-MATRIX is not modified."
   (assert (> n 0))
@@ -415,7 +633,8 @@ Returns a list: (INTERVAL N EF OFMATRIX), where:
   (if (<= quality org-drill-failure-quality)
       ;; When an item is failed, its interval is reset to 0,
       ;; but its EF is unchanged
-      (list -1 1 ef of-matrix)
+      (list -1 1 ef (1+ failures) meanq (1+ total-repeats)
+            org-drill-optimal-factor-matrix)
     ;; else:
     (let* ((next-ef (modify-e-factor ef quality))
            (interval
@@ -431,62 +650,74 @@ Returns a list: (INTERVAL N EF OFMATRIX), where:
                   (2 1)
                   (t -1)))
                (t 6)))
-             (t (ceiling (* last-interval next-ef))))))
-      (list (round
-             (if org-drill-add-random-noise-to-intervals-p
-                 (+ last-interval (* (- interval last-interval)
-                                     (org-drill-random-dispersal-factor)))
-               interval))
-            (1+ n) next-ef of-matrix))))
+             (t (* last-interval next-ef)))))
+      (list (if org-drill-add-random-noise-to-intervals-p
+                (+ last-interval (* (- interval last-interval)
+                                    (org-drill-random-dispersal-factor)))
+              interval)
+            (1+ n)
+            next-ef
+            failures meanq (1+ total-repeats)
+            org-drill-optimal-factor-matrix))))
 
 
 ;;; SM5 Algorithm =============================================================
 
-;;; From http://www.supermemo.com/english/ol/sm5.htm
-(defun org-drill-random-dispersal-factor ()
-  (let ((a 0.047)
-        (b 0.092)
-        (p (- (random* 1.0) 0.5)))
-    (flet ((sign (n)
-                 (cond ((zerop n) 0)
-                       ((plusp n) 1)
-                       (t -1))))
-      (/ (+ 100 (* (* (/ -1 b) (log (- 1 (* (/ b a ) (abs p)))))
-                   (sign p)))
-         100))))
-
 
 (defun inter-repetition-interval-sm5 (last-interval n ef &optional of-matrix)
-  (let ((of (get-optimal-factor n ef of-matrix)))
+  (let ((of (get-optimal-factor n ef (or of-matrix
+                                         org-drill-optimal-factor-matrix))))
     (if (= 1 n)
        of
       (* of last-interval))))
 
 
-(defun determine-next-interval-sm5 (last-interval n ef quality of-matrix)
+(defun determine-next-interval-sm5 (last-interval n ef quality
+                                                  failures meanq total-repeats
+                                                  of-matrix &optional 
delta-days)
+  (if (zerop n) (setq n 1))
+  (if (null ef) (setq ef 2.5))
   (assert (> n 0))
   (assert (and (>= quality 0) (<= quality 5)))
+  (unless of-matrix
+    (setq of-matrix org-drill-optimal-factor-matrix))
+  (setq of-matrix (cl-copy-tree of-matrix))
+
+  (setq meanq (if meanq
+                  (/ (+ quality (* meanq total-repeats 1.0))
+                     (1+ total-repeats))
+                quality))
+
   (let ((next-ef (modify-e-factor ef quality))
         (old-ef ef)
+        (new-of (modify-of (get-optimal-factor n ef of-matrix)
+                           quality org-drill-learn-fraction))
         (interval nil))
+    (when (and org-drill-adjust-intervals-for-early-and-late-repetitions-p
+               delta-days (minusp delta-days))
+      (setq new-of (org-drill-early-interval-factor
+                    (get-optimal-factor n ef of-matrix)
+                    (inter-repetition-interval-sm5
+                     last-interval n ef of-matrix)
+                    delta-days)))
+
     (setq of-matrix
           (set-optimal-factor n next-ef of-matrix
-                              (round-float
-                               (modify-of (get-optimal-factor n ef of-matrix)
-                                          quality org-learn-fraction)
-                               3)))     ; round OF to 3 d.p.
+                              (round-float new-of 3)))     ; round OF to 3 d.p.
 
     (setq ef next-ef)
 
     (cond
      ;; "Failed" -- reset repetitions to 0,
      ((<= quality org-drill-failure-quality)
-      (list -1 1 old-ef of-matrix))     ; Not clear if OF matrix is supposed to
-                                        ; be preserved
+      (list -1 1 old-ef (1+ failures) meanq (1+ total-repeats)
+            of-matrix))     ; Not clear if OF matrix is supposed to be
+                            ; preserved
      ;; For a zero-based quality of 4 or 5, don't repeat
-     ((and (>= quality 4)
-           (not org-learn-always-reschedule))
-      (list 0 (1+ n) ef of-matrix))     ; 0 interval = unschedule
+     ;; ((and (>= quality 4)
+     ;;       (not org-learn-always-reschedule))
+     ;;  (list 0 (1+ n) ef failures meanq
+     ;;        (1+ total-repeats) of-matrix))     ; 0 interval = unschedule
      (t
       (setq interval (inter-repetition-interval-sm5
                       last-interval n ef of-matrix))
@@ -494,7 +725,122 @@ Returns a list: (INTERVAL N EF OFMATRIX), where:
           (setq interval (+ last-interval
                             (* (- interval last-interval)
                                (org-drill-random-dispersal-factor)))))
-      (list (round interval) (1+ n) ef of-matrix)))))
+      (list interval
+            (1+ n)
+            ef
+            failures
+            meanq
+            (1+ total-repeats)
+            of-matrix)))))
+
+
+;;; Simple8 Algorithm =========================================================
+
+
+(defun org-drill-simple8-first-interval (failures)
+  "Arguments:
+- FAILURES: integer >= 0. The total number of times the item has
+  been forgotten, ever.
+
+Returns the optimal FIRST interval for an item which has previously been
+forgotten on FAILURES occasions."
+  (* 2.4849 (exp (* -0.057 failures))))
+
+
+(defun org-drill-simple8-interval-factor (ease repetition)
+  "Arguments:
+- EASE: floating point number >= 1.2. Corresponds to `AF' in SM8 algorithm.
+- REPETITION: the number of times the item has been tested.
+1 is the first repetition (ie the second trial).
+Returns:
+The factor by which the last interval should be
+multiplied to give the next interval. Corresponds to `RF' or `OF'."
+  (+ 1.2 (* (- ease 1.2) (expt org-drill-learn-fraction (log repetition 2)))))
+
+
+(defun org-drill-simple8-quality->ease (quality)
+  "Returns the ease (`AF' in the SM8 algorithm) which corresponds
+to a mean item quality of QUALITY."
+  (+ (* 0.0542 (expt quality 4))
+     (* -0.4848 (expt quality 3))
+     (* 1.4916 (expt quality 2))
+     (* -1.2403 quality)
+     1.4515))
+
+
+(defun determine-next-interval-simple8 (last-interval repeats quality
+                                                      failures meanq totaln
+                                                      &optional delta-days)
+  "Arguments:
+- LAST-INTERVAL -- the number of days since the item was last reviewed.
+- REPEATS -- the number of times the item has been successfully reviewed
+- EASE -- the 'easiness factor'
+- QUALITY -- 0 to 5
+- DELTA-DAYS -- how many days overdue was the item when it was reviewed.
+  0 = reviewed on the scheduled day. +N = N days overdue.
+  -N = reviewed N days early.
+
+Returns the new item data, as a list of 6 values:
+- NEXT-INTERVAL
+- REPEATS
+- EASE
+- FAILURES
+- AVERAGE-QUALITY
+- TOTAL-REPEATS.
+See the documentation for `org-drill-get-item-data' for a description of 
these."
+  (assert (>= repeats 0))
+  (assert (and (>= quality 0) (<= quality 5)))
+  (assert (or (null meanq) (and (>= meanq 0) (<= meanq 5))))
+  (let ((next-interval nil))
+    (setf meanq (if meanq
+                    (/ (+ quality (* meanq totaln 1.0)) (1+ totaln))
+                  quality))
+    (cond
+     ((or (zerop repeats)
+          (zerop last-interval))
+      (setf next-interval (org-drill-simple8-first-interval failures))
+      (incf repeats)
+      (incf totaln))
+     (t
+      (cond
+       ((<= quality org-drill-failure-quality)
+        (incf failures)
+        (setf repeats 0
+              next-interval -1))
+       (t
+        (let* ((use-n
+                (if (and
+                     
org-drill-adjust-intervals-for-early-and-late-repetitions-p
+                     (numberp delta-days) (plusp delta-days)
+                     (plusp last-interval))
+                    (+ repeats (min 1 (/ delta-days last-interval 1.0)))
+                  repeats))
+               (factor (org-drill-simple8-interval-factor
+                        (org-drill-simple8-quality->ease meanq) use-n))
+               (next-int (* last-interval factor)))
+          (when (and 
org-drill-adjust-intervals-for-early-and-late-repetitions-p
+                     (numberp delta-days) (minusp delta-days))
+            ;; The item was reviewed earlier than scheduled.
+            (setf factor (org-drill-early-interval-factor
+                          factor next-int (abs delta-days))
+                  next-int (* last-interval factor)))
+          (setf next-interval next-int)
+          (incf repeats)
+          (incf totaln))))))
+    (list
+     (if (and org-drill-add-random-noise-to-intervals-p
+              (plusp next-interval))
+         (+ last-interval (* (- next-interval last-interval)
+                             (org-drill-random-dispersal-factor)))
+       next-interval)
+     repeats
+     (org-drill-simple8-quality->ease meanq)
+     failures
+     meanq
+     totaln
+     )))
+
+
 
 
 ;;; Essentially copied from `org-learn.el', but modified to
@@ -502,62 +848,73 @@ Returns a list: (INTERVAL N EF OFMATRIX), where:
 (defun org-drill-smart-reschedule (quality &optional days-ahead)
   "If DAYS-AHEAD is supplied it must be a positive integer. The
 item will be scheduled exactly this many days into the future."
-  (let* ((learn-str (org-entry-get (point) "LEARN_DATA"))
-        (learn-data (or (and learn-str
-                             (read learn-str))
-                        (copy-list initial-repetition-state)))
-        closed-dates)
-    (setq learn-data
+  (let ((delta-days (- (time-to-days (current-time))
+                   (time-to-days (or (org-get-scheduled-time (point))
+                                     (current-time)))))
+        (ofmatrix org-drill-optimal-factor-matrix))
+    (destructuring-bind (last-interval repetitions failures
+                                       total-repeats meanq ease)
+        (org-drill-get-item-data)
+      (destructuring-bind (next-interval repetitions ease
+                                         failures meanq total-repeats
+                                         &optional new-ofmatrix)
           (case org-drill-spaced-repetition-algorithm
-            (sm5 (determine-next-interval-sm5 (nth 0 learn-data)
-                                              (nth 1 learn-data)
-                                              (nth 2 learn-data)
-                                              quality
-                                              (nth 3 learn-data)))
-            (sm2 (determine-next-interval-sm2 (nth 0 learn-data)
-                                              (nth 1 learn-data)
-                                              (nth 2 learn-data)
-                                              quality
-                                              (nth 3 learn-data)))))
-    (if (integerp days-ahead)
-        (setf (nth 0 learn-data) days-ahead))
-    (org-entry-put (point) "LEARN_DATA" (prin1-to-string learn-data))
-    (cond
-     ((= 0 (nth 0 learn-data))
-      (org-schedule t))
-     ((minusp (first learn-data))
-      (org-schedule nil (current-time)))
-     (t
-      (org-schedule nil (time-add (current-time)
-                                 (days-to-time (nth 0 learn-data))))))))
+            (sm5 (determine-next-interval-sm5 last-interval repetitions
+                                              ease quality failures
+                                              meanq total-repeats ofmatrix))
+            (sm2 (determine-next-interval-sm2 last-interval repetitions
+                                              ease quality failures
+                                              meanq total-repeats))
+            (simple8 (determine-next-interval-simple8 last-interval repetitions
+                                                      quality failures meanq
+                                                      total-repeats
+                                                      delta-days)))
+        (if (integerp days-ahead)
+            (setf next-interval days-ahead))
+        (org-drill-store-item-data next-interval repetitions failures
+                                   total-repeats meanq ease)
+        (if (eql 'sm5 org-drill-spaced-repetition-algorithm)
+            (setq org-drill-optimal-factor-matrix new-ofmatrix))
+
+        (cond
+         ((= 0 days-ahead)
+          (org-schedule t))
+         ((minusp days-ahead)
+          (org-schedule nil (current-time)))
+         (t
+          (org-schedule nil (time-add (current-time)
+                                      (days-to-time
+                                       (round next-interval))))))))))
+
 
 
 (defun org-drill-hypothetical-next-review-date (quality)
   "Returns an integer representing the number of days into the future
 that the current item would be scheduled, based on a recall quality
 of QUALITY."
-  (let* ((learn-str (org-entry-get (point) "LEARN_DATA"))
-        (learn-data (or (and learn-str
-                             (read learn-str))
-                        (copy-list initial-repetition-state)))
-        closed-dates)
-    (setq learn-data
-          (case org-drill-spaced-repetition-algorithm
-            (sm5 (determine-next-interval-sm5 (nth 0 learn-data)
-                                              (nth 1 learn-data)
-                                              (nth 2 learn-data)
-                                              quality
-                                              (nth 3 learn-data)))
-            (sm2 (determine-next-interval-sm2 (nth 0 learn-data)
-                                              (nth 1 learn-data)
-                                              (nth 2 learn-data)
-                                              quality
-                                              (nth 3 learn-data)))))
-    (cond
-     ((not (plusp (nth 0 learn-data)))
-      0)
-     (t
-      (nth 0 learn-data)))))
+  (destructuring-bind (last-interval repetitions failures
+                                     total-repeats meanq ease)
+      (org-drill-get-item-data)
+    (destructuring-bind (next-interval repetitions ease
+                                       failures meanq total-repeats
+                                       &optional ofmatrix)
+        (case org-drill-spaced-repetition-algorithm
+          (sm5 (determine-next-interval-sm5 last-interval repetitions
+                                            ease quality failures
+                                            meanq total-repeats
+                                            org-drill-optimal-factor-matrix))
+          (sm2 (determine-next-interval-sm2 last-interval repetitions
+                                            ease quality failures
+                                            meanq total-repeats))
+          (simple8 (determine-next-interval-simple8 last-interval repetitions
+                                                    quality failures meanq
+                                                    total-repeats)))
+      (cond
+       ((not (plusp next-interval))
+        0)
+       (t
+        next-interval)))))
+
 
 
 (defun org-drill-hypothetical-next-review-dates ()
@@ -589,9 +946,9 @@ of QUALITY."
 5 - You remembered the item really easily. (+%s days)
 
 How well did you do? (0-5, ?=help, e=edit, t=tags, q=quit)"
-                                 (nth 3 next-review-dates)
-                                 (nth 4 next-review-dates)
-                                 (nth 5 next-review-dates))
+                                 (round (nth 3 next-review-dates))
+                                 (round (nth 4 next-review-dates))
+                                 (round (nth 5 next-review-dates)))
                        "How well did you do? (0-5, ?=help, e=edit, q=quit)")))
         (cond
          ((stringp input)
@@ -614,7 +971,7 @@ How well did you do? (0-5, ?=help, e=edit, t=tags, q=quit)"
     (cond
      ((and (>= ch ?0) (<= ch ?5))
       (let ((quality (- ch ?0))
-            (failures (org-entry-get (point) "DRILL_FAILURE_COUNT")))
+            (failures (org-drill-entry-failure-count)))
         (save-excursion
           (org-drill-smart-reschedule quality
                                       (nth quality next-review-dates)))
@@ -622,9 +979,9 @@ How well did you do? (0-5, ?=help, e=edit, t=tags, q=quit)"
         (cond
          ((<= quality org-drill-failure-quality)
           (when org-drill-leech-failure-threshold
-            (setq failures (if failures (string-to-number failures) 0))
-            (org-set-property "DRILL_FAILURE_COUNT"
-                              (format "%d" (1+ failures)))
+            ;;(setq failures (if failures (string-to-number failures) 0))
+            ;; (org-set-property "DRILL_FAILURE_COUNT"
+            ;;                   (format "%d" (1+ failures)))
             (if (> (1+ failures) org-drill-leech-failure-threshold)
                 (org-toggle-tag "leech" 'on))))
          (t
@@ -960,46 +1317,6 @@ See `org-drill' for more details."
           (org-drill-reschedule)))))))
 
 
-;; (defun org-drill-entries (entries)
-;;   "Returns nil, t, or a list of markers representing entries that were
-;; 'failed' and need to be presented again before the session ends."
-;;   (let ((again-entries nil))
-;;     (setq *org-drill-done-entry-count* 0
-;;           *org-drill-pending-entry-count* (length entries))
-;;     (if (and org-drill-maximum-items-per-session
-;;              (> (length entries)
-;;                 org-drill-maximum-items-per-session))
-;;         (setq entries (subseq entries 0
-;;                               org-drill-maximum-items-per-session)))
-;;     (block org-drill-entries
-;;       (dolist (m entries)
-;;         (save-restriction
-;;           (switch-to-buffer (marker-buffer m))
-;;           (goto-char (marker-position m))
-;;           (setq result (org-drill-entry))
-;;           (cond
-;;            ((null result)
-;;             (message "Quit")
-;;             (return-from org-drill-entries nil))
-;;            ((eql result 'edit)
-;;             (setq end-pos (point-marker))
-;;             (return-from org-drill-entries nil))
-;;            (t
-;;             (cond
-;;              ((< result 3)
-;;               (push m again-entries))
-;;              (t
-;;               (decf *org-drill-pending-entry-count*)
-;;               (incf *org-drill-done-entry-count*)))
-;;             (when (and org-drill-maximum-duration
-;;                        (> (- (float-time (current-time)) 
*org-drill-start-time*)
-;;                           (* org-drill-maximum-duration 60)))
-;;               (message "This drill session has reached its maximum 
duration.")
-;;               (return-from org-drill-entries nil))))))
-;;       (or again-entries
-;;           t))))
-
-
 (defun org-drill-entries-pending-p ()
   (or *org-drill-again-entries*
       (and (not (org-drill-maximum-item-count-reached-p))
@@ -1093,16 +1410,22 @@ maximum number of items."
 
 
 (defun org-drill-final-report ()
-  (read-char-exclusive
+  (let ((pass-percent
+         (round (* 100 (count-if (lambda (qual)
+                                   (> qual org-drill-failure-quality))
+                                 *org-drill-session-qualities*))
+                (max 1 (length *org-drill-session-qualities*))))
+        (prompt nil))
+  (setq prompt
    (format
     "%d items reviewed
-%d items awaiting review (%s, %s, %s)
+%d items awaiting review (%s, %s, %s). %d items dormant.
 Session duration %s
 
 Recall of reviewed items:
- Excellent (5):     %3d%%   |   Near miss (2):     %3d%%
- Good (4):          %3d%%   |   Failure (1):       %3d%%
- Hard (3):          %3d%%   |   Total failure (0): %3d%%
+ Excellent (5):     %3d%%   |   Near miss (2):      %3d%%
+ Good (4):          %3d%%   |   Failure (1):        %3d%%
+ Hard (3):          %3d%%   |   Abject failure (0): %3d%%
 
 You successfully recalled %d%% of reviewed items (quality > %s)
 Session finished. Press a key to continue..."
@@ -1121,6 +1444,7 @@ Session finished. Press a key to continue..."
      (format "%d new"
              (length *org-drill-new-entries*))
      'face `(:foreground ,org-drill-new-count-color))
+    *org-drill-dormant-entry-count*
     (format-seconds "%h:%.2m:%.2s"
                     (- (float-time (current-time)) *org-drill-start-time*))
     (round (* 100 (count 5 *org-drill-session-qualities*))
@@ -1135,13 +1459,26 @@ Session finished. Press a key to continue..."
            (max 1 (length *org-drill-session-qualities*)))
     (round (* 100 (count 0 *org-drill-session-qualities*))
            (max 1 (length *org-drill-session-qualities*)))
-    (round (* 100 (count-if (lambda (qual)
-                              (> qual org-drill-failure-quality))
-                            *org-drill-session-qualities*))
-           (max 1 (length *org-drill-session-qualities*)))
+    pass-percent
     org-drill-failure-quality
-    )))
-
+    ))
+
+  (while (not (input-pending-p))
+      (message "%s" prompt)
+      (sit-for 0.5))
+  (read-char-exclusive)
+
+  (if (< pass-percent (- 100 org-drill-forgetting-index))
+      (read-char-exclusive
+       (format
+        "%s
+You failed %d%% of the items you reviewed during this session.
+Are you keeping up with your items, and reviewing them
+when they are scheduled? If so, you may want to consider
+lowering the value of `org-drill-learn-fraction' slightly in
+order to make items appear more frequently over time."
+        (propertize "WARNING!" 'face 'org-warning)
+        (- 100 pass-percent))))))
 
 
 (defun org-drill (&optional scope)
@@ -1152,13 +1489,12 @@ hidden. The user attempts to recall the hidden 
information or
 answer the question, then presses a key to reveal the answer. The
 user then rates his or her recall or performance on that
 topic. This rating information is used to reschedule the topic
-for future review using the `org-learn' library.
+for future review.
 
 Org-drill proceeds by:
 
 - Finding all topics (headings) in SCOPE which have either been
-  used and rescheduled by org-learn before (i.e. the LEARN_DATA
-  property is set), or which have a tag that matches
+  used and rescheduled before, or which have a tag that matches
   `org-drill-question-tag'.
 
 - All matching topics which are either unscheduled, or are
@@ -1189,6 +1525,7 @@ agenda-with-archives
         (cnt 0))
     (block org-drill
       (setq *org-drill-done-entries* nil
+            *org-drill-dormant-entry-count* 0
             *org-drill-new-entries* nil
             *org-drill-mature-entries* nil
             *org-drill-failed-entries* nil
@@ -1206,16 +1543,19 @@ agenda-with-archives
                                (length *org-drill-mature-entries*)
                                (length *org-drill-failed-entries*))
                             (make-string (ceiling cnt 50) ?.)))
-                 (when (org-drill-entry-due-p)
-                   (cond
-                    ((org-drill-entry-new-p)
-                     (push (point-marker) *org-drill-new-entries*))
-                    ((and (org-drill-entry-last-quality)
-                          (<= (org-drill-entry-last-quality)
-                              org-drill-failure-quality))
-                     (push (point-marker) *org-drill-failed-entries*))
-                    (t
-                     (push (point-marker) *org-drill-mature-entries*)))))
+                 (cond
+                  ((not (org-drill-entry-p))
+                   nil)                 ; skip
+                  ((not (org-drill-entry-due-p))
+                   (incf *org-drill-dormant-entry-count*))
+                  ((org-drill-entry-new-p)
+                   (push (point-marker) *org-drill-new-entries*))
+                  ((and (org-drill-entry-last-quality)
+                        (<= (org-drill-entry-last-quality)
+                            org-drill-failure-quality))
+                   (push (point-marker) *org-drill-failed-entries*))
+                  (t
+                   (push (point-marker) *org-drill-mature-entries*))))
                (concat "+" org-drill-question-tag) scope))
             (cond
              ((and (null *org-drill-new-entries*)
@@ -1225,22 +1565,6 @@ agenda-with-archives
              (t
               (org-drill-entries)
               (message "Drill session finished!"))))
-        ;; (cond
-        ;; ((null entries)
-        ;;  (message "I did not find any pending drill items."))
-        ;; (t
-        ;;  (let ((again t))
-        ;;    (while again
-        ;;      (when (listp again)
-        ;;        (setq entries (shuffle-list again)))
-        ;;      (setq again (org-drill-entries entries))
-        ;;      (cond
-        ;;       ((null again)
-        ;;        (return-from org-drill nil))
-        ;;       ((eql t again)
-        ;;        (setq again nil))))
-        ;;    (message "Drill session finished!")
-        ;;    ))))
         (progn
           (dolist (m (append *org-drill-new-entries*
                              *org-drill-failed-entries*
@@ -1253,7 +1577,16 @@ agenda-with-archives
       (goto-char (marker-position end-pos))
       (message "Edit topic."))
      (t
-      (org-drill-final-report)))))
+      (org-drill-final-report)
+      (if (eql 'sm5 org-drill-spaced-repetition-algorithm)
+          (org-drill-save-optimal-factor-matrix))
+      ))))
+
+
+(defun org-drill-save-optimal-factor-matrix ()
+  (message "Saving optimal factor matrix...")
+  (customize-save-variable 'org-drill-optimal-factor-matrix
+                           org-drill-optimal-factor-matrix))
 
 
 (defun org-drill-cram (&optional scope)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]