From 9938a6aa93a3aeedf0d84f184f30d75eb8c87ec1 Mon Sep 17 00:00:00 2001 From: Paul Sexton Date: Wed, 25 May 2011 11:43:29 +1200 Subject: [PATCH] org-drill.el: fixed handling of cloze text in items with [[bracketed links]] org-drill.el: fontification of cloze itext now works when first org file is loaded. org-drill:el: new cards - hidefirst, hidelast --- contrib/lisp/org-drill.el | 145 +++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 65 deletions(-) diff --git a/contrib/lisp/org-drill.el b/contrib/lisp/org-drill.el index 96763abcc..7592f0607 100644 --- a/contrib/lisp/org-drill.el +++ b/contrib/lisp/org-drill.el @@ -1,7 +1,8 @@ +;;; -*- coding: utf-8-unix -*- ;;; org-drill.el - Self-testing using spaced repetition ;;; ;;; Author: Paul Sexton -;;; Version: 2.3.2 +;;; Version: 2.3.3 ;;; Repository at http://bitbucket.org/eeeickythump/org-drill/ ;;; ;;; @@ -212,6 +213,8 @@ during a drill session." ("show1cloze" . org-drill-present-multicloze-show1) ("show2cloze" . org-drill-present-multicloze-show2) ("multicloze" . org-drill-present-multicloze-hide1) + ("hidefirst" . org-drill-present-multicloze-hide-first) + ("hidelast" . org-drill-present-multicloze-hide-last) ("hide1_firstmore" . org-drill-present-multicloze-hide1-firstmore) ("show1_lastmore" . org-drill-present-multicloze-show1-lastmore) ("show1_firstless" . org-drill-present-multicloze-show1-firstless) @@ -1410,8 +1413,9 @@ visual overlay, or with the string TEXT if it is supplied." (while (re-search-forward org-drill-cloze-regexp nil t) ;; Don't hide org links, partly because they might contain inline ;; images which we want to keep visible - (unless (org-pos-in-regexp (match-beginning 0) - org-bracket-link-regexp 1) + (unless (save-match-data + (org-pos-in-regexp (match-beginning 0) + org-bracket-link-regexp 1)) (org-drill-hide-matched-cloze-text))))) @@ -1436,8 +1440,9 @@ visual overlay, or with the string TEXT if it is supplied." (defun org-drill-hide-cloze-hints () (save-excursion (while (re-search-forward org-drill-cloze-regexp nil t) - (unless (or (org-pos-in-regexp (match-beginning 0) - org-bracket-link-regexp 1) + (unless (or (save-match-data + (org-pos-in-regexp (match-beginning 0) + org-bracket-link-regexp 1)) (null (match-beginning 2))) ; hint subexpression matched (org-drill-hide-region (match-beginning 2) (match-end 2)))))) @@ -1599,14 +1604,19 @@ items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)." (save-excursion (goto-char body-start) (while (re-search-forward org-drill-cloze-regexp item-end t) - (incf match-count))) + (let ((in-regexp? (save-match-data + (org-pos-in-regexp (match-beginning 0) + org-bracket-link-regexp 1)))) + (unless in-regexp? + (incf match-count))))) (if (minusp number-to-hide) (setq number-to-hide (+ match-count number-to-hide))) (when (plusp match-count) (let* ((positions (shuffle-list (loop for i from 1 to match-count collect i))) - (match-nums nil)) + (match-nums nil) + (cnt nil)) (if force-hide-first ;; Force '1' to be in the list, and to be the first item ;; in the list. @@ -1618,12 +1628,23 @@ items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)." (setq match-nums (subseq positions 0 (min number-to-hide (length positions)))) - (dolist (pos-to-hide match-nums) - (save-excursion - (goto-char body-start) - (re-search-forward org-drill-cloze-regexp - item-end t pos-to-hide) - (org-drill-hide-matched-cloze-text))))) + ;; (dolist (pos-to-hide match-nums) + (save-excursion + (goto-char body-start) + (setq cnt 0) + (while (re-search-forward org-drill-cloze-regexp item-end t) + (unless (save-match-data + (org-pos-in-regexp (match-beginning 0) + org-bracket-link-regexp 1)) + (incf cnt) + (if (memq cnt match-nums) + (org-drill-hide-matched-cloze-text))))))) + ;; (loop + ;; do (re-search-forward org-drill-cloze-regexp + ;; item-end t pos-to-hide) + ;; while (org-pos-in-regexp (match-beginning 0) + ;; org-bracket-link-regexp 1)) + ;; (org-drill-hide-matched-cloze-text))))) (org-display-inline-images t) (org-cycle-hide-drawers 'all) (prog1 (org-drill-presentation-prompt) @@ -1631,20 +1652,9 @@ items if FORCE-SHOW-FIRST or FORCE-SHOW-LAST is non-nil)." (org-drill-unhide-clozed-text)))))) -(defun org-drill-present-multicloze-hide1 () - "Hides one of the pieces of text that are marked for cloze deletion, -chosen at random." - (org-drill-present-multicloze-hide-n 1)) - - -(defun org-drill-present-multicloze-hide2 () - "Hides two of the pieces of text that are marked for cloze deletion, -chosen at random." - (org-drill-present-multicloze-hide-n 2)) - - -(defun org-drill-present-multicloze-hide-nth (cnt) - "Hide the CNT'th piece of clozed text. 1 is the first piece. If +(defun org-drill-present-multicloze-hide-nth (to-hide) + "Hide the TO-HIDE'th piece of clozed text. 1 is the first piece. If +TO-HIDE is negative, count backwards, so -1 means the last item, -2 CNT is negative, count backwards, so -1 means the last item, -2 the second to last, etc." (with-hidden-comments @@ -1652,7 +1662,8 @@ the second to last, etc." (let ((item-end nil) (match-count 0) (body-start (or (cdr (org-get-property-block)) - (point)))) + (point))) + (cnt 0)) (org-drill-hide-all-subheadings-except nil) (save-excursion (outline-next-heading) @@ -1660,23 +1671,29 @@ the second to last, etc." (save-excursion (goto-char body-start) (while (re-search-forward org-drill-cloze-regexp item-end t) - (incf match-count))) + (let ((in-regexp? (save-match-data + (org-pos-in-regexp (match-beginning 0) + org-bracket-link-regexp 1)))) + (unless in-regexp? + (incf match-count))))) + (if (minusp to-hide) + (setq to-hide (+ 1 to-hide match-count))) (cond ((or (not (plusp match-count)) - (> cnt match-count) + (> to-hide match-count)) (and (minusp cnt) (> (abs cnt) match-count))) nil) (t (save-excursion (goto-char body-start) - (re-search-forward org-drill-cloze-regexp - item-end t (if (minusp cnt) (+ 1 cnt match-count) cnt)) - (org-drill-hide-matched-cloze-text)))) - (org-display-inline-images t) - (org-cycle-hide-drawers 'all) - (prog1 (org-drill-presentation-prompt) - (org-drill-hide-subheadings-if 'org-drill-entry-p) - (org-drill-unhide-clozed-text)))))) + (setq cnt 0) + (while (re-search-forward org-drill-cloze-regexp item-end t) + (unless (save-match-data + (org-pos-in-regexp (match-beginning 0) + org-bracket-link-regexp 1)) + (incf cnt) + (if (= cnt to-hide) + (org-drill-hide-matched-cloze-text))))))) (defun org-drill-present-multicloze-hide-first () @@ -1714,7 +1731,7 @@ piece. The effect is similar to 'show1cloze' except that the last item is much less likely to be the item that is visible." (if (zerop (mod (1+ (org-drill-entry-total-repeats 0)) 4)) ;; 25% of time, show any item except the last - (org-drill-present-multicloze-hide-n -1 nil t) + (org-drill-present-multicloze-hide-n -1 nil nil t) ;; 75% of time, show the LAST item (org-drill-present-multicloze-hide-n -1 nil t))) @@ -2008,19 +2025,32 @@ RESUMING-P is true if we are resuming a suspended drill session." (setq prompt (format "%d items reviewed. Session duration %s. -%d/%d items awaiting review (%s, %s, %s, %s, %s). - Recall of reviewed items: 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) +%d/%d items still await review (%s, %s, %s, %s, %s). Tomorrow, %d more items will become due for review. Session finished. Press a key to continue..." (length *org-drill-done-entries*) (format-seconds "%h:%.2m:%.2s" (- (float-time (current-time)) *org-drill-start-time*)) + (round (* 100 (count 5 *org-drill-session-qualities*)) + (max 1 (length *org-drill-session-qualities*))) + (round (* 100 (count 2 *org-drill-session-qualities*)) + (max 1 (length *org-drill-session-qualities*))) + (round (* 100 (count 4 *org-drill-session-qualities*)) + (max 1 (length *org-drill-session-qualities*))) + (round (* 100 (count 1 *org-drill-session-qualities*)) + (max 1 (length *org-drill-session-qualities*))) + (round (* 100 (count 3 *org-drill-session-qualities*)) + (max 1 (length *org-drill-session-qualities*))) + (round (* 100 (count 0 *org-drill-session-qualities*)) + (max 1 (length *org-drill-session-qualities*))) + pass-percent + org-drill-failure-quality (org-drill-pending-entry-count) (+ (org-drill-pending-entry-count) *org-drill-dormant-entry-count*) @@ -2045,20 +2075,6 @@ Session finished. Press a key to continue..." (format "%d old" (length *org-drill-old-mature-entries*)) 'face `(:foreground ,org-drill-mature-count-color)) - (round (* 100 (count 5 *org-drill-session-qualities*)) - (max 1 (length *org-drill-session-qualities*))) - (round (* 100 (count 2 *org-drill-session-qualities*)) - (max 1 (length *org-drill-session-qualities*))) - (round (* 100 (count 4 *org-drill-session-qualities*)) - (max 1 (length *org-drill-session-qualities*))) - (round (* 100 (count 1 *org-drill-session-qualities*)) - (max 1 (length *org-drill-session-qualities*))) - (round (* 100 (count 3 *org-drill-session-qualities*)) - (max 1 (length *org-drill-session-qualities*))) - (round (* 100 (count 0 *org-drill-session-qualities*)) - (max 1 (length *org-drill-session-qualities*))) - pass-percent - org-drill-failure-quality *org-drill-due-tomorrow-count* )) @@ -2430,12 +2446,15 @@ values as `org-drill-scope'." -(add-hook 'org-mode-hook - (lambda () - (when org-drill-use-visible-cloze-face-p - (font-lock-add-keywords 'org-mode - org-drill-cloze-keywords - nil)))) +(defun org-drill-add-cloze-fontification () + (when org-drill-use-visible-cloze-face-p + (font-lock-add-keywords 'org-mode + org-drill-cloze-keywords + nil))) + +(add-hook 'org-mode-hook 'org-drill-add-cloze-fontification) + +(org-drill-add-cloze-fontification) ;;; Synching card collections ================================================= @@ -2505,10 +2524,6 @@ equivalent location in DEST to its location in SRC, by matching the heading hierarchy. However if IGNORE-NEW-ITEMS-P is non-nil, we simply ignore any items that do not exist in DEST, and do not copy them across." - ;; In future could look at what to do if we find an item in SRC whose ID - ;; is not present in DEST -- copy the whole item to DEST? - ;; org-copy-subtree --> org-paste-subtree - ;; could try to put it "near" the closest marker (interactive "bImport scheduling info from which buffer?") (unless dest (setq dest (current-buffer)))