1 ;;; planner-cyclic.el --- Cyclic task support for the Emacs Planner
3 ;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 ;; Parts copyright (C) 2005 Sergey Vlasov (vsu AT altlinux.ru)
6 ;; Filename: planner-cyclic.el
7 ;; Author: Sacha Chua <sacha@free.net.ph>
8 ;; Description: Provide cyclic task support
9 ;; URL: http://www.plannerlove.com/
10 ;; Compatibility: Emacs21, XEmacs21
12 ;; This file is part of Planner. It is not part of GNU Emacs.
14 ;; Planner is free software; you can redistribute it and/or modify it
15 ;; under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 2, or (at your option)
19 ;; Planner is distributed in the hope that it will be useful, but
20 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 ;; General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with Planner; see the file COPYING. If not, write to the
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 ;; Boston, MA 02110-1301, USA.
31 ;; Place planner-cyclic.el in your load path and add this to your .emacs:
33 ;; (require 'planner-cyclic)
35 ;; Create a diary file named ~/.diary.cyclic-tasks
36 ;; (or the value of planner-cyclic-diary-file). Example:
38 ;; Tuesday #B0 _ Study Japanese
39 ;; Friday #B0 _ Study Japanese (JapaneseStudies)
41 ;; The first will be a plain task, the second will be linked.
43 ;; By default, planner-cyclic creates multiple tasks if you let tasks build up
44 ;; (that is, the next Tuesday rolls around and you _still_ haven't
45 ;; marked the task as done.) To turn off this behavior:
47 ;; (setq planner-cyclic-diary-nag nil)
54 (defcustom planner-cyclic-diary-file
"~/.diary.cyclic-tasks"
55 "Diary file containing cyclic tasks."
59 (defcustom planner-cyclic-diary-nag t
60 "If non-nil, create tasks even if there are procrastinated cyclic tasks."
64 (defcustom planner-cyclic-task-description-format
"%s from %s"
65 "Format used by `planner-cyclic-generate-task' when creating a task.
66 This string must be a valid control string for `format'. First format
67 argument is the task description read from `planner-cyclic-diary-file',
68 second argument is the date string.
70 If this format is changed when you already have some cyclic tasks
71 created with the old format, `planner-cyclic-create-tasks-maybe' will
72 add the same tasks with the new format, unless you convert existing
73 tasks to the new format manually."
79 (defun planner-cyclic-get-cyclic-tasks (date &optional no-of-days
)
80 "For DATE, get the cyclic tasks."
81 (let ((date (if (stringp date
)
82 (planner-filename-to-calendar-date date
)
85 (mapcar (lambda (item)
86 (when (string-match "#[A-C].+" (elt item
1))
87 (match-string 0 (elt item
1))))
88 (planner-list-diary-entries planner-cyclic-diary-file
91 (defun planner-cyclic-generate-task (date task-string
)
92 "For DATE, generate a cyclic task based on TASK-STRING."
93 (let ((info (planner-task-info-from-string date task-string
)))
95 (setcar (nthcdr 4 info
)
96 (format planner-cyclic-task-description-format
97 (planner-task-description info
)
99 (message "Cannot parse task %s" task-string
))
102 (defun planner-cyclic-create-task-maybe (date task-string
)
103 "For DATE, possibly create a task based on TASK-STRING."
104 (when (string-match planner-task-regexp task-string
)
105 (let ((orig-task (planner-task-info-from-string date task-string
))
106 (new-task (planner-cyclic-generate-task date task-string
)))
107 (unless (planner-find-task new-task
)
108 (when (or planner-cyclic-diary-nag
(not (planner-find-task orig-task
)))
109 (planner-create-task-from-info new-task nil nil nil nil nil date
))))))
112 (defun planner-cyclic-create-tasks-maybe ()
113 "Maybe create cyclic tasks.
114 This will only create tasks for future dates or today."
116 (when (and (planner-derived-mode-p 'planner-mode
)
118 (not muse-publishing-p
)
119 (string-match planner-date-regexp
(planner-page-name))
120 (or (string< (planner-today) (planner-page-name))
121 (string= (planner-today) (planner-page-name))))
123 (lambda (task-string)
125 (planner-cyclic-create-task-maybe (planner-page-name)
127 (planner-cyclic-get-cyclic-tasks (planner-page-name)))))
129 (add-hook 'planner-mode-hook
'planner-cyclic-create-tasks-maybe
)
131 (provide 'planner-cyclic
)
133 ;;; planner-cyclic.el ends here