Function: org-habit-parse-todo
org-habit-parse-todo is a byte-compiled function defined in
org-habit.el.gz.
Signature
(org-habit-parse-todo &optional POM)
Documentation
Parse the TODO surrounding point for its habit-related data.
Returns a list with the following elements:
0: Scheduled date for the habit (may be in the past)
1: ".+"-style repeater for the schedule, in days
2: Optional deadline (nil if not present)
3: If deadline, the repeater for the deadline, otherwise nil
4: A list of all the past dates this todo was mark closed
5: Repeater type as a string
This list represents a "habit" for the rest of this module.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-habit.el.gz
(defun org-habit-parse-todo (&optional pom)
"Parse the TODO surrounding point for its habit-related data.
Returns a list with the following elements:
0: Scheduled date for the habit (may be in the past)
1: \".+\"-style repeater for the schedule, in days
2: Optional deadline (nil if not present)
3: If deadline, the repeater for the deadline, otherwise nil
4: A list of all the past dates this todo was mark closed
5: Repeater type as a string
This list represents a \"habit\" for the rest of this module."
(save-excursion
(if pom (goto-char pom))
(cl-assert (org-is-habit-p (point)))
(let* ((scheduled (org-get-scheduled-time (point)))
(scheduled-repeat (org-get-repeat (org-entry-get (point) "SCHEDULED")))
(end (org-entry-end-position))
(habit-entry (org-no-properties (nth 4 (org-heading-components))))
closed-dates deadline dr-days sr-days sr-type)
(if scheduled
(setq scheduled (time-to-days scheduled))
(error "Habit %s has no scheduled date" habit-entry))
(unless scheduled-repeat
(error
"Habit `%s' has no scheduled repeat period or has an incorrect one"
habit-entry))
(setq sr-days (org-habit-duration-to-days scheduled-repeat)
sr-type (progn (string-match "[\\.+]?\\+" scheduled-repeat)
(match-string-no-properties 0 scheduled-repeat)))
(unless (> sr-days 0)
(error "Habit %s scheduled repeat period is less than 1d" habit-entry))
(when (string-match "/\\([0-9]+[dwmy]\\)" scheduled-repeat)
(setq dr-days (org-habit-duration-to-days
(match-string-no-properties 1 scheduled-repeat)))
(if (<= dr-days sr-days)
(error "Habit %s deadline repeat period is less than or equal to scheduled (%s)"
habit-entry scheduled-repeat))
(setq deadline (+ scheduled (- dr-days sr-days))))
(org-back-to-heading t)
(let* ((maxdays (+ org-habit-preceding-days org-habit-following-days))
(reversed org-log-states-order-reversed)
(search (if reversed 're-search-forward 're-search-backward))
(limit (if reversed end (point)))
(count 0)
(re (format
"^[ \t]*-[ \t]+\\(?:State \"%s\".*%s%s\\)"
(regexp-opt org-done-keywords)
org-ts-regexp-inactive
(let ((value (cdr (assq 'done org-log-note-headings))))
(if (not value) ""
(concat "\\|"
(org-replace-escapes
(regexp-quote value)
`(("%d" . ,org-ts-regexp-inactive)
("%D" . ,org-ts-regexp)
("%s" . "\"\\S-+\"")
("%S" . "\"\\S-+\"")
("%t" . ,org-ts-regexp-inactive)
("%T" . ,org-ts-regexp)
("%u" . ".*?")
("%U" . ".*?")))))))))
(unless reversed (goto-char end))
(while (and (< count maxdays) (funcall search re limit t))
(push (time-to-days
(org-time-string-to-time
(or (match-string-no-properties 1)
(match-string-no-properties 2))))
closed-dates)
(setq count (1+ count))))
(list scheduled sr-days deadline dr-days closed-dates sr-type))))