emacs-wiki-discuss
[Top][All Lists]
Advanced

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

[emacs-wiki-discuss] Tentative hack Re: Assigning tasks to multiple proj


From: Sacha Chua
Subject: [emacs-wiki-discuss] Tentative hack Re: Assigning tasks to multiple projects/pages
Date: Tue, 30 Nov 2004 13:02:21 +0900
User-agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3.50 (gnu/linux)

First shot at a hack for multiple task views. The following code
rewrites everything between

<taskdb s="someregexp">
</taskdb>

with a list of tasks matching the optional regular expression.
The tasks are taken from TaskPool.

Here there be dragons. I suggest testing it outside your normal wiki.
To use, require it, create lots of stuff in your TaskPool, add

<taskdb s="someregexp">
</taskdb>

on some page, and then call M-x planner-db-update-page .

It seems like a promising direction, though. I haven't figured out how
to get it to cooperate with normal plan pages, and would appreciate
insights.

;;; planner-db.el --- multiple task views for planner.el
;; address@hidden, GPL

;; Copyright (C) 2004 Sandra Jean Chua (Sacha) <address@hidden>

;; 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
;;
;; <taskdb s="someregexp">
;; </taskdb>
;;
;; 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 "</" tag-name ">") 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
-- 
Sacha Chua <address@hidden> - open source geekette
http://sacha.free.net.ph/ - PGP Key ID: 0xE7FDF77C
interests: emacs, gnu/linux, personal information management, CS ed
applying as a Debian new maintainer | looking for a grad school




reply via email to

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