;;; planner-db.el --- multiple task views for planner.el ;; sacha@free.net.ph, GPL ;; Copyright (C) 2004 Sandra Jean Chua (Sacha) ;; This file is not part of GNU Emacs. ;; This is free software; you can redistribute it and/or modify it under ;; the terms of the GNU General Public License as published by the Free ;; Software Foundation; either version 2, or (at your option) any later ;; version. ;; ;; This is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ;; for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ;; MA 02111-1307, USA. ;;; Commentary: ;; ;; Usage: ;; ;; Add (require 'planner-db) to your ~/.emacs . Then you can use ;; ;; ;; ;; ;; in your planner pages to get a list of all the tasks from a ;; particular page. To regenerate the contents, call ;; `planner-db-update-page'. ;; ;; What works: ;; - updating the list of tasks ;; - marking a task as closed, whatever (changes reflected in main ;; database) ;; ;; Note that this module redefines the behavior of ;; planner-jump-to-linked-task! I currently wouldn't advise it for ;; people who use plan pages, as planner-db.el can't tell the ;; difference between tasks it manages and tasks you manually put on ;; plan pages. ;; ;; Be very, very careful about mismatched tags! This will _DELETE_ any ;; text between the opening and closing tags. ;; ;; Also, I haven't figured out how to neatly do the following: ;; - publishing ;; - updating lots of pages ;; - working nicely with the rest of the code ;; - getting the planner task-related functions to all do the ;; Right Thing. ;; Not bad, though, for a proof-of-concept one-hour hack. ;;; Code: (defvar planner-db-page "TaskPool" "Page containing all the current tasks.") (defvar planner-db-task-tag "taskdb" "Tag name for tasks from database.") (defvar planner-db-task-condition-attribute "s" "Attribute name for `planner-db-task-tag' conditions.") (defun planner-db-get-tasks (condition) "Return a list of tasks matching CONDITION. Tasks are looked up in `planner-db-page'. CONDITION is a regexp." (save-window-excursion (save-excursion (save-restriction (planner-find-file planner-db-page) (widen) (goto-char (point-min)) (let (results info description condition line) (while (re-search-forward planner-task-regexp nil t) (when (or (not condition) (string-match condition (buffer-substring (line-beginning-position) (line-end-position)))) (setq results (cons (planner-current-task-info) results)))) results))))) (defun planner-db-insert-tasks (condition) "Insert tasks matching CONDITION. Lines should match CONDITION is a regexp." (let (tasks) (setq tasks (planner-db-get-tasks condition)) (while tasks (insert (planner-format-task (car tasks)) "\n") (setq tasks (cdr tasks))))) ;; A general function should be moved into emacs-wiki for edit-time ;; markup. (defun planner-db-update-page () "Search forward for all tasks tag and replace the text." (interactive) (save-excursion (save-restriction (widen) (goto-char (point-min)) (while (re-search-forward emacs-wiki-tag-regexp nil t) (let ((tag-name (match-string-no-properties 1)) beg attrs) (when (string= tag-name planner-db-task-tag) (setq beg (match-end 0)) (let ((attrstr (match-string 2))) (while (and attrstr (string-match "\\([^ \t\n=]+\\)\\(=\"\\([^\"]+\\)\"\\)?" attrstr)) (let ((attr (cons (downcase (match-string-no-properties 1 attrstr)) (match-string-no-properties 3 attrstr)))) (setq attrstr (replace-match "" t t attrstr)) (if attrs (nconc attrs (list attr)) (setq attrs (list attr)))))) (when (search-forward (concat "") nil t) (save-restriction (goto-char beg) (unless (= (point) (line-beginning-position)) (insert "\n")) (narrow-to-region (point) (match-beginning 0)) (delete-region (point-min) (point-max)) (planner-db-insert-tasks (cdr (assoc planner-db-task-condition-attribute attrs))) (add-text-properties (point-min) (point-max) '(planner-db t)))))))))) (defun planner-db-jump-to-linked-task (&optional task-info) "Display the task page linked to by the current task or TASK-INFO." (interactive) (let* ((task-info (or task-info (planner-current-task-info)))) (planner-find-file planner-db-page) (widen) (goto-char (point-min)) (when (search-forward (planner-task-description task-info) nil t) (beginning-of-line) t))) (defalias 'planner-jump-to-linked-task 'planner-db-jump-to-linked-task) (provide 'planner-db) ;;; planner-db.el ends here