Browse Source

Intermediate state, I am just trying comiting now.

Carsten Dominik 12 years ago
parent
commit
93c665b56d
63 changed files with 84249 additions and 2861 deletions
  1. 348 0
      BUGFIXING/org-log.el
  2. 235 0
      CONTRIB/org-depend.el
  3. 33 0
      CONTRIB/org-export-freemind-0.1.0/ChangeLog
  4. 50 0
      CONTRIB/org-export-freemind-0.1.0/README
  5. 7 0
      CONTRIB/org-export-freemind-0.1.0/org-export-freemind-install.el
  6. 196 0
      CONTRIB/org-export-freemind-0.1.0/org-export-freemind.el
  7. 196 0
      CONTRIB/org-export-freemind.el
  8. 153 0
      CONTRIB/org-mairix.el
  9. 39 0
      CONTRIB/org-man.el
  10. 488 0
      CONTRIB/org-toc.el
  11. 37 4
      ChangeLog
  12. 3 0
      EXPERIMENTAL/find-links-to-local.el
  13. 328 0
      EXPERIMENTAL/interactive-query/org-interactive-query.patch.txt
  14. 28057 0
      EXPERIMENTAL/interactive-query/org.el
  15. 8355 2555
      org_xemacs.el
  16. 70 0
      EXPERIMENTAL/john.el
  17. 154 0
      EXPERIMENTAL/org-bibtex.el
  18. 235 0
      EXPERIMENTAL/org-depend.el
  19. 158 0
      EXPERIMENTAL/org-elisp-symbol.el
  20. 135 0
      EXPERIMENTAL/org-fastup.el
  21. 107 0
      EXPERIMENTAL/org-indent.el
  22. 642 0
      EXPERIMENTAL/org-panel.el
  23. 191 0
      EXPERIMENTAL/org-pic.el
  24. 111 0
      EXPERIMENTAL/sacha-load.el
  25. 16 11
      Makefile
  26. BIN
      ORGWEBPAGE/.DS_Store
  27. 6354 0
      ORGWEBPAGE/Changes.html
  28. 3353 0
      ORGWEBPAGE/Changes.org
  29. 3152 0
      ORGWEBPAGE/Changes.txt
  30. 555 0
      ORGWEBPAGE/faq.html
  31. 372 0
      ORGWEBPAGE/faq.org
  32. 66 0
      ORGWEBPAGE/freeshell2.css
  33. 403 0
      ORGWEBPAGE/index.html
  34. 211 0
      ORGWEBPAGE/index.org
  35. 151 0
      ORGWEBPAGE/index.txt
  36. 5 0
      ORGWEBPAGE/org.texi
  37. 24 0
      ORGWEBPAGE/org/index.html
  38. 231 0
      ORGWEBPAGE/qanda.org
  39. 2195 0
      ORGWEBPAGE/survey.html
  40. 1158 0
      ORGWEBPAGE/survey.org
  41. BIN
      ORGWEBPAGE/tmp/.DS_Store
  42. 6368 0
      ORGWEBPAGE/tmp/Changes.html
  43. 3562 0
      ORGWEBPAGE/tmp/Changes.txt
  44. 663 0
      ORGWEBPAGE/tmp/faq.html
  45. 65 0
      ORGWEBPAGE/tmp/freeshell2.css
  46. 419 0
      ORGWEBPAGE/tmp/index.html
  47. 457 0
      ORGWEBPAGE/tmp/orgcard.txt
  48. 449 0
      ORGWEBPAGE/tmp/qanda.html
  49. 44 0
      ORGWEBPAGE/tmp/request-assign-future.txt
  50. 2169 0
      ORGWEBPAGE/tmp/survey.html
  51. 1209 0
      ORGWEBPAGE/tmp/todo.html
  52. 317 0
      ORGWEBPAGE/tmp/tutorials.html
  53. 920 0
      ORGWEBPAGE/todo.html
  54. 649 0
      ORGWEBPAGE/todo.org
  55. 340 0
      ORGWEBPAGE/tutorials.html
  56. 105 0
      ORGWEBPAGE/tutorials.org
  57. 206 0
      TODO
  58. 72 0
      UTILITIES/fake_change_log.pl
  59. 482 272
      org.el
  60. 31 16
      org.texi
  61. 3 3
      orgcard.tex
  62. 457 0
      orgcard.txt
  63. 6688 0
      texinfo.tex

+ 348 - 0
BUGFIXING/org-log.el

@@ -0,0 +1,348 @@
+(defun org-agenda-switch-to (&optional delete-other-windows)
+  "Go to the Org-mode file which contains the item at point."
+  (interactive)
+  (let ((cb (current-buffer))
+	(line (org-current-line))
+	(col (current-column))
+	(buf (current-buffer))
+	(pos (point)))
+    (with-current-buffer (get-buffer-create "OrgAgendaGotoLog")
+      (goto-char (point-max))
+      (insert "--------------------------------------------------------\n")
+      (insert (format "This command: %s\n" this-command))
+      (insert (format "Last command: %s\n" last-command))
+      (insert (format "Line/Column/Point: %d/%d/%d\n" line col pos))))
+  (orglog-describe-char (point))
+  (let* ((marker (or (get-text-property (point) 'org-marker)
+		     (org-agenda-error)))
+	 (buffer (marker-buffer marker))
+	 (pos (marker-position marker)))
+    (switch-to-buffer buffer)
+    (and delete-other-windows (delete-other-windows))
+    (widen)
+    (goto-char pos)
+    (when (org-mode-p)
+      (org-show-context 'agenda)
+      (save-excursion
+	(and (outline-next-heading)
+	     (org-flag-heading nil))))
+    (let ((cb (current-buffer))
+	  (pos (point)))
+      (with-current-buffer (get-buffer-create "OrgAgendaGotoLog")
+      (goto-char (point-max))
+	(insert (format "Arrived: %s %d\n" cb pos))))))
+
+(defun org-agenda-goto (&optional highlight)
+  "Go to the Org-mode file which contains the item at point."
+  (interactive)
+  (let ((cb (current-buffer))
+	(line (org-current-line))
+	(col (current-column))
+	(buf (current-buffer))
+	(pos (point)))
+    (with-current-buffer (get-buffer-create "OrgAgendaGotoLog")
+      (goto-char (point-max))
+      (insert "--------------------------------------------------------\n")
+      (insert (format "This command: %s\n" this-command))
+      (insert (format "Last command: %s\n" last-command))
+      (insert (format "Line/Column/Point: %d/%d/%d\n" line col pos))))
+  (orglog-describe-char (point))
+  (let* ((marker (or (get-text-property (point) 'org-marker)
+		     (org-agenda-error)))
+	 (buffer (marker-buffer marker))
+	 (pos (marker-position marker)))
+    (switch-to-buffer-other-window buffer)
+    (widen)
+    (goto-char pos)
+    (when (org-mode-p)
+      (org-show-context 'agenda)
+      (save-excursion
+	(and (outline-next-heading)
+	     (org-flag-heading nil)))) ; show the next heading
+    (run-hooks 'org-agenda-after-show-hook)
+    (and highlight (org-highlight (point-at-bol) (point-at-eol)))
+    (let ((cb (current-buffer))
+	  (pos (point)))
+      (with-current-buffer (get-buffer-create "OrgAgendaGotoLog")
+	(goto-char (point-max))
+	(insert (format "Arrived: %s %d\n" cb pos))))))
+
+
+(defun orglog-describe-char (pos)
+  "Describe the character after POS (interactively, the character after point).
+The information includes character code, charset and code points in it,
+syntax, category, how the character is encoded in a file,
+character composition information (if relevant),
+as well as widgets, buttons, overlays, and text properties."
+  (interactive "d")
+  (if (>= pos (point-max))
+      (error "No character follows specified position"))
+  (let* ((char (char-after pos))
+	 (charset (char-charset char))
+	 (composition (find-composition pos nil nil t))
+	 (component-chars nil)
+	 (display-table (or (window-display-table)
+			    buffer-display-table
+			    standard-display-table))
+	 (disp-vector (and display-table (aref display-table char)))
+	 (multibyte-p enable-multibyte-characters)
+	 (overlays (mapcar #'(lambda (o) (overlay-properties o))
+			   (overlays-at pos)))
+	 (char-description (if (not multibyte-p)
+			       (single-key-description char)
+			     (if (< char 128)
+				 (single-key-description char)
+			       (string-to-multibyte
+				(char-to-string char)))))
+	 (text-props-desc
+	  (let ((tmp-buf (generate-new-buffer " *text-props*")))
+	    (unwind-protect
+		(progn
+		  (describe-text-properties pos tmp-buf)
+		  (with-current-buffer tmp-buf (buffer-string)))
+	      (kill-buffer tmp-buf))))
+	 item-list max-width unicode)
+
+    (if (or (< char 256)
+	    (memq 'mule-utf-8 (find-coding-systems-region pos (1+ pos)))
+	    (get-char-property pos 'untranslated-utf-8))
+	(setq unicode (or (get-char-property pos 'untranslated-utf-8)
+			  (encode-char char 'ucs))))
+    (setq item-list
+	  `(("character"
+	     ,(format "%s (%d, #o%o, #x%x%s)"
+		      (apply 'propertize char-description
+			     (text-properties-at pos))
+		      char char char
+		      (if unicode
+			  (format ", U+%04X" unicode)
+			"")))
+	    ("charset"
+	     ,`(insert-text-button
+		,(symbol-name charset)
+		'type 'help-character-set 'help-args '(,charset))
+	     ,(format "(%s)" (charset-description charset)))
+	    ("code point"
+	     ,(let ((split (split-char char)))
+		`(insert-text-button
+		  ,(if (= (charset-dimension charset) 1)
+		       (format "#x%02X" (nth 1 split))
+		     (format "#x%02X #x%02X" (nth 1 split)
+			     (nth 2 split)))
+		  'action (lambda (&rest ignore)
+			    (list-charset-chars ',charset)
+			    (with-selected-window
+				(get-buffer-window "*Character List*" 0)
+			      (goto-char (point-min))
+			      (forward-line 2) ;Skip the header.
+			      (let ((case-fold-search nil))
+				(search-forward ,(char-to-string char)
+						nil t))))
+		  'help-echo
+		  "mouse-2, RET: show this character in its character set")))
+	    ("syntax"
+	     ,(let ((syntax (syntax-after pos)))
+		(with-temp-buffer
+		  (internal-describe-syntax-value syntax)
+		  (buffer-string))))
+	    ("category"
+	     ,@(let ((category-set (char-category-set char)))
+		 (if (not category-set)
+		     '("-- none --")
+		   (mapcar #'(lambda (x) (format "%c:%s"
+						 x (category-docstring x)))
+			   (category-set-mnemonics category-set)))))
+	    ,@(let ((props (aref char-code-property-table char))
+		    ps)
+		(when props
+		  (while props
+		    (push (format "%s:" (pop props)) ps)
+		    (push (format "%s;" (pop props)) ps))
+		  (list (cons "Properties" (nreverse ps)))))
+	    ("to input"
+	     ,@(let ((key-list (and (eq input-method-function
+					'quail-input-method)
+				    (quail-find-key char))))
+		 (if (consp key-list)
+		     (list "type"
+			   (mapconcat #'(lambda (x) (concat "\"" x "\""))
+				      key-list " or ")
+			   "with"
+			   `(insert-text-button
+			     ,current-input-method
+			     'type 'help-input-method
+			     'help-args '(,current-input-method))))))
+	    ("buffer code"
+	     ,(encoded-string-description
+	       (string-as-unibyte (char-to-string char)) nil))
+	    ("file code"
+	     ,@(let* ((coding buffer-file-coding-system)
+		      (encoded (encode-coding-char char coding)))
+		 (if encoded
+		     (list (encoded-string-description encoded coding)
+			   (format "(encoded by coding system %S)" coding))
+		   (list "not encodable by coding system"
+			 (symbol-name coding)))))
+	    ("display"
+	     ,(cond
+	       (disp-vector
+		(setq disp-vector (copy-sequence disp-vector))
+		(dotimes (i (length disp-vector))
+		  (setq char (aref disp-vector i))
+		  (aset disp-vector i
+			(cons char (describe-char-display
+				    pos (glyph-char char)))))
+		(format "by display table entry [%s] (see below)"
+			(mapconcat
+			 #'(lambda (x)
+			     (format "?%c" (glyph-char (car x))))
+			 disp-vector " ")))
+	       (composition
+		(let ((from (car composition))
+		      (to (nth 1 composition))
+		      (next (1+ pos))
+		      (components (nth 2 composition))
+		      ch)
+		  (setcar composition
+			  (and (< from pos) (buffer-substring from pos)))
+		  (setcar (cdr composition)
+			  (and (< next to) (buffer-substring next to)))
+		  (dotimes (i (length components))
+		    (if (integerp (setq ch (aref components i)))
+			(push (cons ch (describe-char-display pos ch))
+			      component-chars)))
+		  (setq component-chars (nreverse component-chars))
+		  (format "composed to form \"%s\" (see below)"
+			  (buffer-substring from to))))
+	       (t
+		(let ((display (describe-char-display pos char)))
+		  (if (display-graphic-p (selected-frame))
+		      (if display
+			  (concat
+			   "by this font (glyph code)\n"
+			   (format "     %s (#x%02X)"
+				   (car display) (cdr display)))
+			"no font available")
+		    (if display
+			(format "terminal code %s" display)
+		      "not encodable for terminal"))))))
+	    ,@(let ((face
+		     (if (not (or disp-vector composition))
+			 (cond
+			  ((and show-trailing-whitespace
+				(save-excursion (goto-char pos)
+						(looking-at "[ \t]+$")))
+			   'trailing-whitespace)
+			  ((and nobreak-char-display unicode (eq unicode '#xa0))
+			   'nobreak-space)
+			  ((and nobreak-char-display unicode (eq unicode '#xad))
+			   'escape-glyph)
+			  ((and (< char 32) (not (memq char '(9 10))))
+			   'escape-glyph)))))
+		(if face (list (list "hardcoded face"
+				     `(insert-text-button
+				       ,(symbol-name face)
+				       'type 'help-face 'help-args '(,face))))))
+	    ,@(let ((unicodedata (and unicode
+				      (describe-char-unicode-data unicode))))
+		(if unicodedata
+		    (cons (list "Unicode data" " ") unicodedata)))))
+    (setq max-width (apply #'max (mapcar #'(lambda (x)
+					     (if (cadr x) (length (car x)) 0))
+					 item-list)))
+    (with-current-buffer (get-buffer-create "OrgAgendaGotoLog")
+      (goto-char (point-max))
+      (set-buffer-multibyte multibyte-p)
+      (let ((formatter (format "%%%ds:" max-width)))
+	(dolist (elt item-list)
+	  (when (cadr elt)
+	    (insert (format formatter (car elt)))
+	    (dolist (clm (cdr elt))
+	      (if (eq (car-safe clm) 'insert-text-button)
+		  (progn (insert " ") (eval clm))
+		(when (>= (+ (current-column)
+			     (or (string-match "\n" clm)
+				 (string-width clm))
+			     1)
+			  (window-width))
+		  (insert "\n")
+		  (indent-to (1+ max-width)))
+		(insert " " clm)))
+	    (insert "\n"))))
+      
+      (when overlays
+	(save-excursion
+	  (goto-char (point-min))
+	  (re-search-forward "character:[ \t\n]+")
+	  (let* ((end (+ (point) (length char-description))))
+	    (mapc #'(lambda (props)
+		      (let ((o (make-overlay (point) end)))
+			(while props
+			  (overlay-put o (car props) (nth 1 props))
+			  (setq props (cddr props)))))
+		  overlays))))
+      
+      (when disp-vector
+	(insert
+	 "\nThe display table entry is displayed by ")
+	(if (display-graphic-p (selected-frame))
+	    (progn
+	      (insert "these fonts (glyph codes):\n")
+	      (dotimes (i (length disp-vector))
+		(insert (glyph-char (car (aref disp-vector i))) ?:
+			(propertize " " 'display '(space :align-to 5))
+			(if (cdr (aref disp-vector i))
+			    (format "%s (#x%02X)" (cadr (aref disp-vector i))
+				    (cddr (aref disp-vector i)))
+			  "-- no font --")
+			"\n")
+		(let ((face (glyph-face (car (aref disp-vector i)))))
+		  (when face
+		    (insert (propertize " " 'display '(space :align-to 5))
+			    "face: ")
+		    (insert (concat "`" (symbol-name face) "'"))
+		    (insert "\n")))))
+	  (insert "these terminal codes:\n")
+	  (dotimes (i (length disp-vector))
+	    (insert (car (aref disp-vector i))
+		    (propertize " " 'display '(space :align-to 5))
+		    (or (cdr (aref disp-vector i)) "-- not encodable --")
+		    "\n"))))
+      
+      (when composition
+	(insert "\nComposed")
+	(if (car composition)
+	    (if (cadr composition)
+		(insert " with the surrounding characters \""
+			(car composition) "\" and \""
+			(cadr composition) "\"")
+	      (insert " with the preceding character(s) \""
+		      (car composition) "\""))
+	  (if (cadr composition)
+	      (insert " with the following character(s) \""
+		      (cadr composition) "\"")))
+	(insert " by the rule:\n\t("
+		(mapconcat (lambda (x)
+			     (format (if (consp x) "%S" "?%c") x))
+			   (nth 2 composition)
+			   " ")
+		")")
+	(insert  "\nThe component character(s) are displayed by ")
+	(if (display-graphic-p (selected-frame))
+	    (progn
+	      (insert "these fonts (glyph codes):")
+	      (dolist (elt component-chars)
+		(insert "\n " (car elt) ?:
+			(propertize " " 'display '(space :align-to 5))
+			(if (cdr elt)
+			    (format "%s (#x%02X)" (cadr elt) (cddr elt))
+			  "-- no font --"))))
+	  (insert "these terminal codes:")
+	  (dolist (elt component-chars)
+	    (insert "\n  " (car elt) ":"
+		    (propertize " " 'display '(space :align-to 5))
+		    (or (cdr elt) "-- not encodable --"))))
+	(insert "\nSee the variable `reference-point-alist' for "
+		"the meaning of the rule.\n"))
+      
+      (if text-props-desc (insert text-props-desc)))))

+ 235 - 0
CONTRIB/org-depend.el

@@ -0,0 +1,235 @@
+;;; org-depend.el --- TODO dependencies for Org-mode
+
+;; This file is not part of GNU Emacs.
+;;
+;; This file 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 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs 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., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; WARNING: This file is just a PROOF OF CONCEPT, not a supported part
+;;          of Org-mode.
+;;
+;; This is an example implementation of TODO dependencies in Org-mode.
+;; It uses the new hooks in version 5.13 of Org-mode,
+;; `org-trigger-hook' and `org-blocker-hook'.
+;;
+;; It implements the following:
+;;
+;; Triggering
+;; ----------
+;;
+;; 1) If an entry contains a TRIGGER property that contains the string
+;;    "chain-siblings(KEYWORD)", then switching that entry to DONE does
+;;    do the following:
+;;    - The sibling following this entry switched to todo-state KEYWORD.
+;;    - The sibling also gets a TRIGGER property "chain-sibling(KEYWORD)",
+;;      property, to make sure that, when *it* is DONE, the chain will
+;;      continue.
+;;
+;; 2) If the TRIGGER property contains any other words like
+;;    XYZ(KEYWORD), these are treated as entry id's with keywords.  That
+;;    means, Org-mode will search for an entry with the ID property XYZ
+;;    and switch that entry to KEYWORD as well.
+;;
+;; Blocking
+;; --------
+;;
+;; 1) If an entry contains a BLOCKER property that contains the word
+;;    "previous-sibling", the sibling above the current entry is
+;;    checked when you try to mark it DONE.  If it is still in a TODO
+;;    state, the current state change is blocked.
+;;
+;; 2) If the BLOCKER property contains any other words, these are
+;;    treated as entry id's.  That means, Org-mode will search for an
+;;    entry with the ID property exactly equal to this word.  If any
+;;    of these entries is not yet marked DONE, the current state change
+;;    will be blocked.
+;;
+;; 3) Whenever a state change is blocked, an org-mark is pushed, so that
+;;    you can find the offending entry with `C-c &'.
+;;
+;;; Example:
+;;
+;; When trying this example, make sure that the settings for TODO keywords
+;; have been activated, i.e. include the following line and press C-c C-c
+;; on the line before working with the example:
+;;
+;; #+TYP_TODO: TODO NEXT | DONE
+;;
+;; * TODO Win a million in Las Vegas
+;;   The "third" TODO (see above) cannot become a TODO without this money.
+;;
+;;   :PROPERTIES:
+;;     :ID: I-cannot-do-it-without-money
+;;   :END:
+;;
+;; * Do this by doing a chain of TODO's
+;; ** NEXT This is the first in this chain
+;;    :PROPERTIES:
+;;      :TRIGGER: chain-siblings(NEXT)
+;;    :END:
+;; 
+;; ** This is the second in this chain
+;;
+;; ** This is the third in this chain
+;;    :PROPERTIES:
+;;      :BLOCKER: I-cannot-do-it-without-money
+;;    :END:
+;;
+;; ** This is the forth in this chain
+;;    When this is DONE, we will also trigger entry XYZ-is-my-id
+;;   :PROPERTIES:
+;;     :TRIGGER: XYZ-is-my-id(TODO)
+;;   :END:
+;;
+;; ** This is the fifth in this chain
+;; 
+;; * Start writing report
+;;   :PROPERTIES:
+;;     :ID: XYZ-is-my-id
+;;   :END:
+;;
+;;
+
+(require 'org)
+
+(defun org-depend-trigger-todo (change-plist)
+  "Trigger new TODO entries after the current is switched to DONE.
+This does two different kinds of triggers:
+
+- If the current entry contains a TRIGGER property that contains
+  \"chain-siblings(KEYWORD)\", it goes to the next sibling, marks it
+  KEYWORD and also installs the \"chain-sibling\" trigger to continue
+  the chain.
+- Any other word (space-separated) like XYZ(KEYWORD) in the TRIGGER
+  property is seen as an entry id.  Org-mode finds the entry with the
+  corresponding ID property and switches it to the state TODO as well."
+
+  ;; Get information from the plist
+  (let* ((type (plist-get change-plist :type))
+	       (pos (plist-get change-plist :position))
+	 (from (plist-get change-plist :from))
+	 (to (plist-get change-plist :to))
+	 (org-log-done nil) ; IMPROTANT!: no logging during automatic trigger!
+	 trigger triggers tr p1 kwd)
+    (catch 'return
+      (unless (eq type 'todo-state-change)
+	;; We are only handling todo-state-change....
+	(throw 'return t))
+      (unless (and (member from org-not-done-keywords)
+		   (member to org-done-keywords))
+	;; This is not a change from TODO to DONE, ignore it
+	(throw 'return t))
+
+      ;; OK, we just switched from a TODO state to a DONE state
+      ;; Lets see if this entry has a TRIGGER property.
+      ;; If yes, split it up on whitespace.
+      (setq trigger (org-entry-get pos "TRIGGER")
+	    triggers (and trigger (org-split-string trigger "[ \t]+")))
+
+      ;; Go through all the triggers
+      (while (setq tr (pop triggers))
+	(cond
+	 ((string-match "\\`chain-siblings(\\(.*?\\))\\'" tr)
+	  ;; This is a TODO chain of siblings
+	  (setq kwd (match-string 1 tr))
+	  (catch 'exit
+	    (save-excursion
+	      (goto-char pos)
+	      ;; find the sibling, exit if no more siblings
+	      (condition-case nil
+		  (outline-forward-same-level 1)
+		(error (throw 'exit t)))
+	      ;; mark the sibling TODO
+	      (org-todo kwd)
+	      ;; make sure the sibling will continue the chain
+	      (org-entry-add-to-multivalued-property
+	       nil "TRIGGER" (format "chain-siblings(%s)" kwd)))))
+
+	 ((string-match "\\`\\(\\S-+\\)(\\(.*?\\))\\'" tr)
+	  ;; This seems to be ENTRY_ID(KEYWORD)
+	  (setq id (match-string 1 tr)
+		kwd (match-string 2 tr)
+		p1 (org-find-entry-with-id id))
+	  (when p1
+	    ;; there is an entry with this ID, mark it TODO
+	    (save-excursion
+	      (goto-char p1)
+	      (org-todo kwd)))))))))
+
+(defun org-depend-block-todo (change-plist)
+  "Block turning an entry into a TODO.
+This checks for a BLOCKER property in an entry and checks
+all the entries listed there.  If any of them is not done,
+block changing the current entry into a TODO entry.  If the property contains
+the word \"previous-sibling\", the sibling above the current entry is checked.
+Any other words are treated as entry id's. If an entry exists with the
+this ID property, that entry is also checked."
+  ;; Get information from the plist
+  (let* ((type (plist-get change-plist :type))
+	       (pos (plist-get change-plist :position))
+	 (from (plist-get change-plist :from))
+	 (to (plist-get change-plist :to))
+	 (org-log-done nil) ; IMPROTANT!: no logging during automatic trigger
+	 blocker blockers bl p1)
+    (catch 'return
+      (unless (eq type 'todo-state-change)
+	;; We are not handling this kind of change
+	(throw 'return t))
+      (unless (and (not from) (member to org-not-done-keywords))
+	;; This is not a change from nothing to TODO, ignore it
+	(throw 'return t))
+
+      ;; OK, the plan is to switch from nothing to TODO
+      ;; Lets see if we will allow it.  Find the BLOCKER property
+      ;; and split it on whitespace.
+      (setq blocker (org-entry-get pos "BLOCKER")
+	    blockers (and blocker (org-split-string blocker "[ \t]+")))
+
+      ;; go through all the blockers
+      (while (setq bl (pop blockers))
+	(cond
+	 ((equal bl "previous-sibling")
+	  ;; the sibling is required to be DONE.
+	  (catch 'ignore
+	    (save-excursion
+	      (goto-char pos)
+	      ;; find the older sibling, exit if no more siblings
+	      (condition-case nil
+		  (outline-backward-same-level 1)
+		(error (throw 'ignore t)))
+	      ;; Check if this entry is not yet done and block
+	      (unless (org-entry-is-done-p)
+		;; return nil, to indicate that we block the change!
+		(org-mark-ring-push)
+		(throw 'return nil)))))
+
+	 ((setq p1 (org-find-entry-with-id bl))
+	  ;; there is an entry with this ID, check it out
+	  (save-excursion
+	    (goto-char p1)
+	    (unless (org-entry-is-done-p)
+	      ;; return nil, to indicate that we block the change!
+	      (org-mark-ring-push)
+	      (throw 'return nil))))))
+      t ; return t to indicate that we are not blocking
+      )))
+
+(add-hook 'org-trigger-hook 'org-depend-trigger-todo)
+(add-hook 'org-blocker-hook 'org-depend-block-todo)
+
+;;; org-depend.el ends here

+ 33 - 0
CONTRIB/org-export-freemind-0.1.0/ChangeLog

@@ -0,0 +1,33 @@
+2007-06-25  Marco Vezzoli  <noise dot otn at alice dot it>
+
+	* org-export-freemind-install.el (org-export-as-freemind): 
+	- created installation file
+
+2007-06-25  Marco Vezzoli  <noise dot otn at alice dot it>
+
+	* org-export-freemind.el (org-export-as-freemind): 
+	- created customization variables for org-freemind-icons-alist and
+	org-freemind-cloud-alist
+
+	- fixed export bug to handle level jump (e.g. a * followed by a ***)
+
+	- added keybinding 'C-c C-x f' org-export-as-freemind
+
+2007-06-02  Marco Vezzoli  <noise dot otn at alice dot it>
+
+	* org-export-freemind.el (org-export-as-freemind): 
+	
+	- fixed conversion bug: all headings are converted inserting html
+	entities 
+
+	- added configuration with org-freemind-icons-alist: an alist that
+	allows to associate regexp with builtins freemind icons
+
+	- added configuration with org-freemind-cloud-alist: an alist that
+	allows to associate regexp with cloud colors
+
+	- added org-export-as-freemind-agenda-files : exports all agenda
+	files in separate files with the same name and extension .mm
+
+	- added org-export-as-freemind-agenda-files-one-file : do the same
+	but grouping all trees in a single file

+ 50 - 0
CONTRIB/org-export-freemind-0.1.0/README

@@ -0,0 +1,50 @@
+The project
+-----------
+
+This is an extension to emacs Org Mode [1] to export into FreeMind
+[2], two very valuable productivity tools.
+
+This code is donated to both porjects and is distributable under any
+of the copyright notices of these.
+
+Current status of the code is alpha: use it at your own
+risk. Nonetheless I'm happy to support user of this code as far as I
+can.
+
+Install
+-------
+
+Before use this code please verify you have Org Mode correctly
+installed in your emacs.
+
+Installation:
+copy all *.el files into the org installation directory.
+add the following line to your .emacs
+
+(require org-export-freemind-install) 
+
+This will define the following functions:
+
+org-export-as-freemind: export current buffer into a freemind file
+with the same name, placed in the XOXO publishing directory
+
+org-export-as-freemind-agenda-files: export all agenda files into
+separate freemind files, placed on the XOXO publishing directory
+
+org-export-as-freemind-agenda-files-one-file: export all agenda files
+into a single freemind file
+
+also the following variables are set
+
+org-freemind-icons-alist: an alist which associates regexp with
+freemind builtin icons
+
+org-freemind-cloud-alist: an alist which associates regexp with
+freemind cloud colors (rrggbb hex notation)
+
+Todos
+-----
+- try to export html parts
+
+[1] http://staff.science.uva.nl/~dominik/Tools/org/
+[2] http://freemind.sourceforge.net/wiki/index.php/Main_Page

+ 7 - 0
CONTRIB/org-export-freemind-0.1.0/org-export-freemind-install.el

@@ -0,0 +1,7 @@
+(autoload 'org-export-as-freemind "org-export-freemind" 
+  "export a single org file in freemind format" t)
+(autoload 'org-export-as-freemind-agenda-files "org-export-freemind" 
+  "export all agenda files file in freemind format" t)
+(autoload 'org-export-as-freemind-agenda-files-one-file  "org-export-freemind" 
+  "export all agenda files file in freemind format into a single file" t)
+(provide 'org-export-freemind-install)

+ 196 - 0
CONTRIB/org-export-freemind-0.1.0/org-export-freemind.el

@@ -0,0 +1,196 @@
+;;; org-export-freemind - exporting utilities from org-mode to freemind
+
+;; Copyright (C) 2007 Marco Vezzoli
+
+;; Author: marco vezzoli <noise.otn@alice.it>
+;; Created:
+;; Version: 0.1.0
+;; Keywords: org-mode export freemind
+;; Commentary:
+
+;; This file is *not* part of GNU Emacs.
+;; This program 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 of
+;; the License, or (at your option) any later version.
+
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301 USA
+
+;;; Code:
+(defgroup org-export-freemind ()
+  "This group let you customize your own export into freemind format"
+  :group 'org-export)
+
+(defcustom org-freemind-icons-alist
+  '(("TODO" . "button_cancel")
+    ("SPEC" . "pencil")
+    ("WIP"  . "pencil")
+    ("TEST" . "xmag")
+    ("DONE" . "button_ok"))
+  "change the icon according to a regular expression"
+  :type '(alist :key-type regexp 
+		:value-type string)
+  :group 'org-export-freemind)
+
+(defcustom org-freemind-cloud-alist
+  '((":PROJECT:" . "ccffcc")
+    (":MEETING:" . "ccccff"))
+  "create a cloud with the defined color if title match a regexp"
+  :type '(alist :key-type regexp :value-type string)
+  :group 'org-export-freemind)
+
+(defun org-export-as-freemind (&optional buffer outbuffer)
+  "Export the org buffer as FreeMind XML.
+"
+  (interactive (list (current-buffer) ()))
+  ;; A quickie abstraction
+
+  ;; Output everything as FreeMind
+  (with-current-buffer (get-buffer buffer)
+    (goto-char (point-min))  ;; CD:  beginning-of-buffer is not allowed.
+    (let* ((opt-plist (org-combine-plists (org-default-export-plist)
+					(org-infile-export-plist)))
+	   (title       (or (plist-get opt-plist :title)
+			    (file-name-sans-extension
+			     (file-name-nondirectory buffer-file-name))))
+	   (filename (concat (file-name-as-directory
+			      (org-export-directory :xoxo opt-plist))
+			     title
+			     ".mm"))
+	   (out (if (bufferp outbuffer)
+		    outbuffer
+		    (find-file-noselect filename)))
+	   (last-level 0)
+	   (hanging-li nil))
+
+      ;; Check the output buffer is empty.
+      ;; Kick off the output
+      (unless (bufferp outbuffer)
+	  (progn
+	    (with-current-buffer out (erase-buffer))
+	    (org-export-as-xoxo-insert-into out "<map version='0.8.0'>\n")))
+      (org-export-as-xoxo-insert-into out 
+	"<node TEXT='" title "'"
+	(if (bufferp outbuffer)
+	    " FOLDED='true'" "")
+	">\n")
+      (if (bufferp outbuffer)
+	  (org-export-as-xoxo-insert-into out "<cloud COLOR='#ccffff'/>\n"))
+      (while (re-search-forward "^\\(\\*+\\) \\(.+\\)" (point-max) 't)
+        (let* ((hd (match-string-no-properties 1))
+               (level (length hd))
+               (text (match-string-no-properties 2)))
+	  (save-excursion
+	    (goto-char (match-end 0))
+	    (catch 'loop
+	      (while 't
+		(forward-line)
+		(if (looking-at "^[ \t]\\(.*\\)")
+		    ()
+		  (throw 'loop "")))))
+
+          ;; Handle level rendering
+	  (cond
+           ((> level last-level)
+	    (let ((rept (- level last-level 1))
+		  (value ()))
+	      (dotimes (i rept value)
+		(org-export-as-xoxo-insert-into out "<node FOLDED='false' TEXT='.'>\n")))
+            (org-export-as-xoxo-insert-into out "\n<node FOLDED='true' TEXT='"))
+
+           ((< level last-level)
+	    (let ((rept (+ (- last-level level) 1))
+		  (value ()))
+	      (dotimes (i rept value)
+		(org-export-as-xoxo-insert-into out "</node>\n")))
+	    (org-export-as-xoxo-insert-into out "<node FOLDED='true' TEXT='"))
+
+           ((equal level last-level)
+	    (org-export-as-xoxo-insert-into out "</node>\n<node FOLDED='true' TEXT='")))
+
+          (setq last-level level)
+
+          ;; And output the new node
+	  (let* ((heading
+		  (concat "<html><h3>" 
+			  (replace-regexp-in-string 
+			   ":.*:" 
+			   (lambda (x) 
+			     (concat "<font color='red'>" x "</font>")) 
+			   text)
+			  "</h3></html>"))
+		 (html-quoted-heading (org-html-expand heading))
+		 (exp-quote-heading (replace-regexp-in-string "'" "&quot;" html-quoted-heading)))
+	    (org-export-as-xoxo-insert-into out exp-quote-heading "'>\n"))
+
+	  (dolist (rule org-freemind-icons-alist)
+	    (if (string-match (car rule) text)
+		(org-export-as-xoxo-insert-into out "<icon BUILTIN='" (cdr rule) "'/>\n")))
+	  (dolist (rule org-freemind-cloud-alist)
+	    (when (string-match (car rule) text)
+	      (progn
+		(org-export-as-xoxo-insert-into out 
+		  "<cloud COLOR='#" (cdr rule) "'/>\n")
+		(message (cdr rule))
+		)))
+	  ))
+
+      ;; Finally finish off the map
+      (let ((value ()))
+	(org-export-as-xoxo-insert-into out "\n")
+	(dotimes (i last-level value)
+	  (org-export-as-xoxo-insert-into out "</node>\n")))
+      (org-export-as-xoxo-insert-into out "</node>\n")
+
+      ;; Finish the buffer off and clean it up.
+      (unless (bufferp outbuffer)
+	(progn
+	  (org-export-as-xoxo-insert-into out "</map>\n")
+	  (switch-to-buffer-other-window out)
+	  (indent-region (point-min) (point-max) nil)
+	  (save-buffer)
+	  (goto-char (point-min))
+	  )))))
+
+(defun org-export-as-freemind-agenda-files ()
+  "Export all agenda files into Freemind format
+each files is saved with .mm extension
+into the XOXO publishing directory"
+  (interactive)
+  (dolist (file org-agenda-files)
+    (org-check-agenda-file file)
+    (set-buffer (org-get-agenda-file-buffer file))
+    (org-export-as-freemind (current-buffer))
+    ))
+
+(defun org-export-as-freemind-agenda-files-one-file (filename)
+  "Export all agenda files into FreeMind format.
+All results are grouped in a single .mm file"
+  (interactive "FFile to save: ")
+  (let* ((title (file-name-sans-extension
+		 (file-name-nondirectory filename)))
+	 (out (find-file-noselect filename)))
+    (with-current-buffer out (erase-buffer))
+    (org-export-as-xoxo-insert-into out "<map version='0.8.0'><node TEXT='" title "'>\n")
+    (dolist (file org-agenda-files)
+      (org-check-agenda-file file)
+      (set-buffer (org-get-agenda-file-buffer file))
+      (org-export-as-freemind (current-buffer) out)
+      )
+    (org-export-as-xoxo-insert-into out "</node></map>\n")
+    (switch-to-buffer-other-window out)
+    (indent-region (point-min) (point-max) nil)
+    (save-buffer)
+    (goto-char (point-min))
+    ))
+
+(define-key org-mode-map "\C-c\C-xf" 'org-export-as-freemind)
+;;; org-export-freemind ends here

+ 196 - 0
CONTRIB/org-export-freemind.el

@@ -0,0 +1,196 @@
+;;; org-export-freemind - exporting utilities from org-mode to freemind
+
+;; Copyright (C) 2007 Marco Vezzoli
+
+;; Author: marco vezzoli <noise.otn@alice.it>
+;; Created:
+;; Version: 0.1.0
+;; Keywords: org-mode export freemind
+;; Commentary:
+
+;; This file is *not* part of GNU Emacs.
+;; This program 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 of
+;; the License, or (at your option) any later version.
+
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301 USA
+
+;;; Code:
+(defgroup org-export-freemind ()
+  "This group let you customize your own export into freemind format"
+  :group 'org-export)
+
+(defcustom org-freemind-icons-alist
+  '(("TODO" . "button_cancel")
+    ("SPEC" . "pencil")
+    ("WIP"  . "pencil")
+    ("TEST" . "xmag")
+    ("DONE" . "button_ok"))
+  "change the icon according to a regular expression"
+  :type '(alist :key-type regexp 
+		:value-type string)
+  :group 'org-export-freemind)
+
+(defcustom org-freemind-cloud-alist
+  '((":PROJECT:" . "ccffcc")
+    (":MEETING:" . "ccccff"))
+  "create a cloud with the defined color if title match a regexp"
+  :type '(alist :key-type regexp :value-type string)
+  :group 'org-export-freemind)
+
+(defun org-export-as-freemind (&optional buffer outbuffer)
+  "Export the org buffer as FreeMind XML.
+"
+  (interactive (list (current-buffer) ()))
+  ;; A quickie abstraction
+
+  ;; Output everything as FreeMind
+  (with-current-buffer (get-buffer buffer)
+    (goto-char (point-min))  ;; CD:  beginning-of-buffer is not allowed.
+    (let* ((opt-plist (org-combine-plists (org-default-export-plist)
+					(org-infile-export-plist)))
+	   (title       (or (plist-get opt-plist :title)
+			    (file-name-sans-extension
+			     (file-name-nondirectory buffer-file-name))))
+	   (filename (concat (file-name-as-directory
+			      (org-export-directory :xoxo opt-plist))
+			     title
+			     ".mm"))
+	   (out (if (bufferp outbuffer)
+		    outbuffer
+		    (find-file-noselect filename)))
+	   (last-level 0)
+	   (hanging-li nil))
+
+      ;; Check the output buffer is empty.
+      ;; Kick off the output
+      (unless (bufferp outbuffer)
+	  (progn
+	    (with-current-buffer out (erase-buffer))
+	    (org-export-as-xoxo-insert-into out "<map version='0.8.0'>\n")))
+      (org-export-as-xoxo-insert-into out 
+	"<node TEXT='" title "'"
+	(if (bufferp outbuffer)
+	    " FOLDED='true'" "")
+	">\n")
+      (if (bufferp outbuffer)
+	  (org-export-as-xoxo-insert-into out "<cloud COLOR='#ccffff'/>\n"))
+      (while (re-search-forward "^\\(\\*+\\) \\(.+\\)" (point-max) 't)
+        (let* ((hd (match-string-no-properties 1))
+               (level (length hd))
+               (text (match-string-no-properties 2)))
+	  (save-excursion
+	    (goto-char (match-end 0))
+	    (catch 'loop
+	      (while 't
+		(forward-line)
+		(if (looking-at "^[ \t]\\(.*\\)")
+		    ()
+		  (throw 'loop "")))))
+
+          ;; Handle level rendering
+	  (cond
+           ((> level last-level)
+	    (let ((rept (- level last-level 1))
+		  (value ()))
+	      (dotimes (i rept value)
+		(org-export-as-xoxo-insert-into out "<node FOLDED='false' TEXT='.'>\n")))
+            (org-export-as-xoxo-insert-into out "\n<node FOLDED='true' TEXT='"))
+
+           ((< level last-level)
+	    (let ((rept (+ (- last-level level) 1))
+		  (value ()))
+	      (dotimes (i rept value)
+		(org-export-as-xoxo-insert-into out "</node>\n")))
+	    (org-export-as-xoxo-insert-into out "<node FOLDED='true' TEXT='"))
+
+           ((equal level last-level)
+	    (org-export-as-xoxo-insert-into out "</node>\n<node FOLDED='true' TEXT='")))
+
+          (setq last-level level)
+
+          ;; And output the new node
+	  (let* ((heading
+		  (concat "<html><h3>" 
+			  (replace-regexp-in-string 
+			   ":.*:" 
+			   (lambda (x) 
+			     (concat "<font color='red'>" x "</font>")) 
+			   text)
+			  "</h3></html>"))
+		 (html-quoted-heading (org-html-expand heading))
+		 (exp-quote-heading (replace-regexp-in-string "'" "&quot;" html-quoted-heading)))
+	    (org-export-as-xoxo-insert-into out exp-quote-heading "'>\n"))
+
+	  (dolist (rule org-freemind-icons-alist)
+	    (if (string-match (car rule) text)
+		(org-export-as-xoxo-insert-into out "<icon BUILTIN='" (cdr rule) "'/>\n")))
+	  (dolist (rule org-freemind-cloud-alist)
+	    (when (string-match (car rule) text)
+	      (progn
+		(org-export-as-xoxo-insert-into out 
+		  "<cloud COLOR='#" (cdr rule) "'/>\n")
+		(message (cdr rule))
+		)))
+	  ))
+
+      ;; Finally finish off the map
+      (let ((value ()))
+	(org-export-as-xoxo-insert-into out "\n")
+	(dotimes (i last-level value)
+	  (org-export-as-xoxo-insert-into out "</node>\n")))
+      (org-export-as-xoxo-insert-into out "</node>\n")
+
+      ;; Finish the buffer off and clean it up.
+      (unless (bufferp outbuffer)
+	(progn
+	  (org-export-as-xoxo-insert-into out "</map>\n")
+	  (switch-to-buffer-other-window out)
+	  (indent-region (point-min) (point-max) nil)
+	  (save-buffer)
+	  (goto-char (point-min))
+	  )))))
+
+(defun org-export-as-freemind-agenda-files ()
+  "Export all agenda files into Freemind format
+each files is saved with .mm extension
+into the XOXO publishing directory"
+  (interactive)
+  (dolist (file org-agenda-files)
+    (org-check-agenda-file file)
+    (set-buffer (org-get-agenda-file-buffer file))
+    (org-export-as-freemind (current-buffer))
+    ))
+
+(defun org-export-as-freemind-agenda-files-one-file (filename)
+  "Export all agenda files into FreeMind format.
+All results are grouped in a single .mm file"
+  (interactive "FFile to save: ")
+  (let* ((title (file-name-sans-extension
+		 (file-name-nondirectory filename)))
+	 (out (find-file-noselect filename)))
+    (with-current-buffer out (erase-buffer))
+    (org-export-as-xoxo-insert-into out "<map version='0.8.0'><node TEXT='" title "'>\n")
+    (dolist (file org-agenda-files)
+      (org-check-agenda-file file)
+      (set-buffer (org-get-agenda-file-buffer file))
+      (org-export-as-freemind (current-buffer) out)
+      )
+    (org-export-as-xoxo-insert-into out "</node></map>\n")
+    (switch-to-buffer-other-window out)
+    (indent-region (point-min) (point-max) nil)
+    (save-buffer)
+    (goto-char (point-min))
+    ))
+
+(define-key org-mode-map "\C-c\C-xf" 'org-export-as-freemind)
+;;; org-export-freemind ends here

+ 153 - 0
CONTRIB/org-mairix.el

@@ -0,0 +1,153 @@
+;;; org-mairix.el --- 
+
+;; Copyright 2007 Bastien Guerry
+;;
+;; Author: Bastien.Guerry@ens.fr
+;; Version: $Id: org-mairix.el,v 0.0 2007/08/11 17:23:40 guerry Exp $
+;; Keywords: 
+;; X-URL: not distributed yet
+
+;; This program 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 program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; Code and ideas from Carsten Dominik, Adam Spiers and Georg C. F. Greve.
+
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'org-mairix)
+
+;;; Code:
+
+(require 'org)
+
+(defgroup org-mairix nil
+  "Mairix link support for Org."
+  :tag "Org Mairix"
+  :group 'org)
+
+(defcustom mairix-results-group "nnmaildir+index:mfolder"
+  "Gnus groupe where to list mairix search results."
+  :group 'org-mairix
+  :type '(string))
+
+(defun org-add-link-type (type &optional follow publish)
+  "Add TYPE to the list of `org-link-types'.
+Re-compute all regular expressions depending on `org-link-types'."
+  (add-to-list 'org-link-types type t)
+  (setq org-link-re-with-space
+	(concat
+	 "<?\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+	 "\\([^" org-non-link-chars " ]"
+	 "[^" org-non-link-chars "]*"
+	 "[^" org-non-link-chars " ]\\)>?"))
+  (setq org-link-re-with-space2
+	(concat
+	 "<?\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+	 "\\([^" org-non-link-chars " ]"
+	 "[^]\t\n\r]*"
+	 "[^" org-non-link-chars " ]\\)>?"))
+  (setq org-angle-link-re
+	(concat
+	 "<\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+	 "\\([^" org-non-link-chars " ]"
+	 "[^" org-non-link-chars "]*"
+	 "\\)>"))
+  (setq org-plain-link-re
+	(concat
+	 "\\(" (mapconcat 'identity org-link-types "\\|") "\\):"
+	 "\\([^]\t\n\r<>,;() ]+\\)"))
+  (setq org-bracket-link-analytic-regexp
+	(concat
+	 "\\[\\["
+	 "\\(\\(" (mapconcat 'identity org-link-types "\\|") "\\):\\)?"
+	 "\\([^]]+\\)"
+	 "\\]"
+	 "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
+	 "\\]"))
+  (add-hook 'org-follow-link-functions follow)
+  (add-hook 'org-publish-link-functions publish))
+
+(defun org-mairix-follow-link (path)
+  "Follow a Mairix link."
+  (require 'gnus)
+  (funcall (cdr (assq 'gnus org-link-frame-setup)))
+  (if gnus-other-frame-object (select-frame gnus-other-frame-object))
+  (mairix-search path))
+
+(defun org-mairix-publish-link (path)
+  "Convert mairix PATH into a (dummy) raw link."
+  ;; FIXME: should we have a format argument for HTML/LaTeX publishing?
+  (if (string-match org-bracket-link-analytic-regexp path)
+    (match-string 5 path) path))
+
+(defun org-mairix-store-link (path)
+  "Store a mairix link."
+  (when (memq major-mode '(gnus-summary-mode gnus-article-mode))
+    (let* ((group gnus-newsgroup-name)
+	   (article (gnus-summary-article-number))
+	   (header (gnus-summary-article-header article))
+	   (from (mail-header-from header))
+	   (message-id (mail-header-id header))
+	   (date (mail-header-date header))
+	   (subject (gnus-summary-subject-string)))
+      (org-store-link-props :type "mairix" 
+			    :from from 
+			    :subject subject
+			    :message-id message-id 
+			    :group group)
+;; FIXME: what about cpltxt and link vars we used so far?
+;;       (setq cpltxt (org-email-link-description))
+;;       (setq link (org-make-link "mairix:m:" 
+;; 				(substring message-id 1 -1))))))
+      (org-make-link "mairix:m:" (substring message-id 1 -1)))))
+
+;; mairix internals
+(defun mairix-result-evaluate (string)
+  "Display search results of previous mairix process."
+  (let ((mmatches (string-to-number (substring string 7 -8))))
+    (if (eq mmatches 0)
+	(message "Mairix returned no matches, sorry.")
+      (message "Mairix returned %d matches." mmatches)
+      (gnus-group-quick-select-group 0 mairix-results-group)
+      (gnus-summary-reselect-current-group t t))))
+
+
+(org-add-link-type "mairix"
+		   'org-mairix-follow-link 
+		   'org-mairix-publish-link)
+
+(add-hook 'org-store-link-functions 'org-mairix-store-link)
+
+(defun mairix-search (string)
+  "Uses mairix to search through my mail, replacing current search results."
+  (interactive "MMairix search: ")
+  (mairix-result-evaluate
+	(shell-command-to-string (concat "mairix " string))))
+
+(provide 'org-mairix)
+(eval-when-compile
+  (require 'cl))
+
+
+
+;;;;##########################################################################
+;;;;  User Options, Variables
+;;;;##########################################################################
+
+
+
+
+
+;;; org-mairix.el ends here

+ 39 - 0
CONTRIB/org-man.el

@@ -0,0 +1,39 @@
+;;; org-man.el - Support for links to manpages in Org-mode
+
+(require 'org)
+
+(org-add-link-type "man" 'org-man-open)
+(add-hook 'org-store-link-functions 'org-man-store-link)
+
+(defcustom org-man-command 'man
+  "The Emacs command to be used to display a man page."
+  :group 'org-link
+  :type '(choice (const man) (const woman)))
+
+(defun org-man-open (path)
+  "Visit the manpage on PATH.
+PATH should be a topic that can be thrown at the man command."
+  (funcall org-man-command path))
+
+(defun org-man-store-link ()
+  "Store a link to a README file."
+  (when (memq major-mode '(Man-mode woman-mode))
+    ;; This is a man page, we do make this link
+    (let* ((page (org-man-get-page-name))
+           (link (concat "man:" page))
+           (description (format "Manpage for %s" page)))
+      (org-store-link-props
+       :type "man"
+       :link link
+       :description description))))
+
+(defun org-man-get-page-name ()
+  "Extract the page name from the buffer name."
+  ;; This works for both `Man-mode' and `woman-mode'.
+  (if (string-match " \\(\\S-+\\)\\*" (buffer-name))
+      (match-string 1 (buffer-name))
+    (error "Cannot create link to this man page")))
+
+(provide 'org-man)
+
+;;; org-man.el ends here

+ 488 - 0
CONTRIB/org-toc.el

@@ -0,0 +1,488 @@
+;;; org-toc.el --- Table of contents for Org-mode buffer
+
+;; Copyright 2007 Bastien Guerry
+;;
+;; Author: Bastien Guerry <bzg AT altern DOT org>
+;; Keywords: Org table of contents
+;; Homepage: http://www.cognition.ens.fr/~guerry/u/org-toc.el
+;; Version: 0.8
+
+;; This program 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 3, or (at your option)
+;; any later version.
+;;
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; This library implements a browsable table of contents for Org files.
+
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'org-toc)
+
+;;; Code:
+
+(provide 'org-toc)
+(eval-when-compile
+  (require 'cl))
+
+;;; Custom variables:
+(defvar org-toc-base-buffer nil)
+(defvar org-toc-columns-shown nil)
+(defvar org-toc-odd-levels-only nil)
+(defvar org-toc-config-alist nil)
+(defvar org-toc-cycle-global-status nil)
+(defalias 'org-show-table-of-contents 'org-toc-show)
+
+(defgroup org-toc nil
+  "Options concerning the browsable table of contents of Org-mode."
+  :tag "Org TOC"
+  :group 'org)
+
+(defcustom org-toc-default-depth 1
+  "Default depth when invoking `org-toc-show' without argument."
+  :group 'org-toc
+  :type '(choice
+	  (const :tag "same as base buffer" nil)
+	  (integer :tag "level")))
+
+(defcustom org-toc-follow-mode nil
+  "Non-nil means navigating through the table of contents will
+move the point in the Org buffer accordingly."
+  :group 'org-toc
+  :type 'boolean)
+
+(defcustom org-toc-info-mode nil
+  "Non-nil means navigating through the table of contents will
+show the properties for the current headline in the echo-area."
+  :group 'org-toc
+  :type 'boolean)
+
+(defcustom org-toc-show-subtree-mode nil
+  "Non-nil means show subtree when going to headline or following
+it while browsing the table of contents."
+  :group 'org-toc
+  :type '(choice
+	  (const :tag "show subtree" t)
+	  (const :tag "show entry" nil)))
+
+(defcustom org-toc-recenter-mode t
+  "Non-nil means recenter the Org buffer when following the
+headlines in the TOC buffer."
+  :group 'org-toc
+  :type 'boolean)
+
+(defcustom org-toc-recenter 0
+  "Where to recenter the Org buffer when unfolding a subtree.
+This variable is only used when `org-toc-recenter-mode' is set to
+'custom. A value >=1000 will call recenter with no arg."
+  :group 'org-toc
+  :type 'integer)
+
+(defcustom org-toc-info-exclude '("ALLTAGS")
+  "A list of excluded properties when displaying info in the
+echo-area. The COLUMNS property is always exluded."
+  :group 'org-toc
+  :type 'lits)
+
+;;; Org TOC mode:
+(defvar org-toc-mode-map (make-sparse-keymap)
+  "Keymap for `org-toc-mode'.")
+
+(defun org-toc-mode ()
+  "A major mode for browsing the table of contents of an Org buffer.
+
+\\{org-toc-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map org-toc-mode-map)
+  (setq mode-name "Org TOC")
+  (setq major-mode 'org-toc-mode))
+
+;; toggle modes
+(define-key org-toc-mode-map "f" 'org-toc-follow-mode)
+(define-key org-toc-mode-map "S" 'org-toc-show-subtree-mode)
+(define-key org-toc-mode-map "s" 'org-toc-store-config)
+(define-key org-toc-mode-map "g" 'org-toc-restore-config)
+(define-key org-toc-mode-map "i" 'org-toc-info-mode)
+(define-key org-toc-mode-map "r" 'org-toc-recenter-mode)
+
+;; navigation keys
+(define-key org-toc-mode-map "p" 'org-toc-previous)
+(define-key org-toc-mode-map "n" 'org-toc-next)
+(define-key org-toc-mode-map [(left)] 'org-toc-previous)
+(define-key org-toc-mode-map [(right)] 'org-toc-next)
+(define-key org-toc-mode-map [(up)] 'org-toc-previous)
+(define-key org-toc-mode-map [(down)] 'org-toc-next)
+(define-key org-toc-mode-map "1" (lambda() (interactive) (org-toc-show 1 (point))))
+(define-key org-toc-mode-map "2" (lambda() (interactive) (org-toc-show 2 (point))))
+(define-key org-toc-mode-map "3" (lambda() (interactive) (org-toc-show 3 (point))))
+(define-key org-toc-mode-map "4" (lambda() (interactive) (org-toc-show 4 (point))))
+(define-key org-toc-mode-map " " 'org-toc-goto)
+(define-key org-toc-mode-map "q" 'org-toc-quit)
+(define-key org-toc-mode-map "x" 'org-toc-quit)
+;; go to the location and stay in the base buffer
+(define-key org-toc-mode-map [(tab)] 'org-toc-jump)
+(define-key org-toc-mode-map "v" 'org-toc-jump)
+;; go to the location and delete other windows
+(define-key org-toc-mode-map [(return)]
+  (lambda() (interactive) (org-toc-jump t)))
+
+;; special keys
+(define-key org-toc-mode-map "c" 'org-toc-columns)
+(define-key org-toc-mode-map "?" 'org-toc-help)
+(define-key org-toc-mode-map ":" 'org-toc-cycle-subtree)
+(define-key org-toc-mode-map "\C-c\C-o" 'org-open-at-point)
+;; global cycling in the base buffer
+(define-key org-toc-mode-map (kbd "C-S-<iso-lefttab>")
+  'org-toc-cycle-base-buffer)
+;; subtree cycling in the base buffer
+(define-key org-toc-mode-map [(control tab)]
+  (lambda() (interactive) (org-toc-goto nil t)))
+
+;;; Toggle functions:
+(defun org-toc-follow-mode ()
+  "Toggle follow mode in a `org-toc-mode' buffer."
+  (interactive)
+  (setq org-toc-follow-mode (not org-toc-follow-mode))
+  (message "Follow mode is %s"
+	   (if org-toc-follow-mode "on" "off")))
+
+(defun org-toc-info-mode ()
+  "Toggle info mode in a `org-toc-mode' buffer."
+  (interactive)
+  (setq org-toc-info-mode (not org-toc-info-mode))
+  (message "Info mode is %s"
+	   (if org-toc-info-mode "on" "off")))
+
+(defun org-toc-show-subtree-mode ()
+  "Toggle show subtree mode in a `org-toc-mode' buffer."
+  (interactive)
+  (setq org-toc-show-subtree-mode (not org-toc-show-subtree-mode))
+  (message "Show subtree mode is %s"
+	   (if org-toc-show-subtree-mode "on" "off")))
+
+(defun org-toc-recenter-mode (&optional line)
+  "Toggle recenter mode in a `org-toc-mode' buffer. If LINE is
+specified, then make `org-toc-recenter' use this value."
+  (interactive "P")
+  (setq org-toc-recenter-mode (not org-toc-recenter-mode))
+  (when (numberp line)
+    (setq org-toc-recenter-mode t)
+    (setq org-toc-recenter line))
+  (message "Recenter mode is %s"
+	   (if org-toc-recenter-mode
+	       (format "on, line %d" org-toc-recenter) "off")))
+
+(defun org-toc-cycle-subtree ()
+  "Locally cycle a headline through two states: 'children and
+'folded"
+  (interactive)
+  (let ((beg (point))
+	(end (save-excursion (end-of-line) (point)))
+	(ov (car (org-overlays-at (point))))
+	status)
+    (if ov (setq status (org-overlay-get ov 'status))
+      (setq ov (org-make-overlay beg end)))
+    ;; change the folding status of this headline
+    (cond ((or (null status) (eq status 'folded))
+	   (show-children)
+	   (message "CHILDREN")
+	   (org-overlay-put ov 'status 'children))
+	  ((eq status 'children)
+	   (show-branches)
+	   (message "BRANCHES")
+	   (org-overlay-put ov 'status 'branches))
+	  (t (hide-subtree)
+	     (message "FOLDED")
+	     (org-overlay-put ov 'status 'folded)))))
+
+;;; Main show function:
+;; FIXME name this org-before-first-heading-p?
+(defun org-toc-before-first-heading-p ()
+  "Before first heading?"
+  (save-excursion
+    (null (re-search-backward "^\\*+ " nil t))))
+
+;;;###autoload
+(defun org-toc-show (&optional depth position)
+  "Show the table of contents of the current Org-mode buffer."
+  (interactive "P")
+  (if (org-mode-p)
+      (progn (setq org-toc-base-buffer (current-buffer))
+	     (setq org-toc-odd-levels-only org-odd-levels-only))
+    (if (eq major-mode 'org-toc-mode)
+	(switch-to-buffer org-toc-base-buffer)
+      (error "Not in an Org buffer")))
+  ;; create the new window display
+  (let ((pos (or position
+		 (save-excursion
+		   (if (org-toc-before-first-heading-p)
+		       (progn (re-search-forward "^\\*+ " nil t)
+			      (match-beginning 0))
+		     (point))))))
+    (setq org-toc-cycle-global-status org-cycle-global-status)
+    (delete-other-windows)
+    (and (get-buffer "*org-toc*") (kill-buffer "*org-toc*"))
+    (switch-to-buffer-other-window
+     (make-indirect-buffer org-toc-base-buffer "*org-toc*"))
+    ;; make content before 1st headline invisible
+    (goto-char (point-min))
+    (let* ((beg (point-min))
+	   (end (and (re-search-forward "^\\*" nil t)
+		     (1- (match-beginning 0))))
+	   (ov (org-make-overlay beg end))
+	   (help (format "Table of contents for %s (press ? for a quick help):\n"
+			 (buffer-name org-toc-base-buffer))))
+      (org-overlay-put ov 'invisible t)
+      (org-overlay-put ov 'before-string help))
+    ;; build the browsable TOC
+    (cond (depth
+	   (let* ((dpth (if org-toc-odd-levels-only
+			    (1- (* depth 2)) depth)))
+	     (org-content dpth)
+	     (setq org-toc-cycle-global-status
+		   `(org-content ,dpth))))
+	   ((null org-toc-default-depth)
+	    (if (eq org-toc-cycle-global-status 'overview)
+		(progn (org-overview)
+		       (setq org-cycle-global-status 'overview)
+		       (run-hook-with-args 'org-cycle-hook 'overview))
+	      (progn (org-overview)
+		     ;; FIXME org-content to show only headlines?
+		     (org-content)
+		     (setq org-cycle-global-status 'contents)
+		     (run-hook-with-args 'org-cycle-hook 'contents))))
+	   (t (let* ((dpth0 org-toc-default-depth)
+		     (dpth (if org-toc-odd-levels-only
+			       (1- (* dpth0 2)) dpth0)))
+		(org-content dpth)
+		(setq org-toc-cycle-global-status
+		      `(org-content ,dpth)))))
+    (goto-char pos))
+  (move-beginning-of-line nil)
+  (org-toc-mode)
+  (shrink-window-if-larger-than-buffer)
+  (setq buffer-read-only t))
+
+;;; Navigation functions:
+(defun org-toc-goto (&optional jump cycle)
+  "From Org TOC buffer, follow the targeted subtree in the Org window.
+If JUMP is non-nil, go to the base buffer.  
+If JUMP is 'delete, go to the base buffer and delete other windows.
+If CYCLE is non-nil, cycle the targeted subtree in the Org window."
+  (interactive)
+  (let ((pos (point))
+	(toc-buf (current-buffer)))
+    (switch-to-buffer-other-window org-toc-base-buffer)
+    (goto-char pos)
+    (if cycle (org-cycle)
+      (progn (org-overview)
+	     (if org-toc-show-subtree-mode
+		 (org-show-subtree)
+	       (org-show-entry))
+	     (org-show-context)))
+    (if org-toc-recenter-mode
+	(if (>= org-toc-recenter 1000) (recenter)
+	  (recenter org-toc-recenter)))
+    (cond ((null jump)
+	   (switch-to-buffer-other-window toc-buf))
+	  ((eq jump 'delete)
+	   (delete-other-windows)))))
+
+(defun org-toc-cycle-base-buffer ()
+  "Call `org-cycle' with a prefix argument in the base buffer."
+  (interactive)
+  (switch-to-buffer-other-window org-toc-base-buffer)
+  (org-cycle t)
+  (other-window 1))
+
+(defun org-toc-jump (&optional delete)
+  "From Org TOC buffer, jump to the targeted subtree in the Org window.
+If DELETE is non-nil, delete other windows when in the Org buffer."
+  (interactive "P")
+  (if delete (org-toc-goto 'delete)
+    (org-toc-goto t)))
+
+(defun org-toc-previous ()
+  "Go to the previous headline of the TOC."
+  (interactive)
+  (if (save-excursion
+	  (beginning-of-line)
+	  (re-search-backward "^\\*" nil t))
+    (outline-previous-visible-heading 1)
+    (message "No previous heading"))
+  (if org-toc-info-mode (org-toc-info))
+  (if org-toc-follow-mode (org-toc-goto)))
+
+(defun org-toc-next ()
+  "Go to the next headline of the TOC."
+  (interactive)
+  (outline-next-visible-heading 1)
+  (if org-toc-info-mode (org-toc-info))
+  (if org-toc-follow-mode (org-toc-goto)))
+
+(defun org-toc-quit ()
+  "Quit the current Org TOC buffer."
+  (interactive)
+  (kill-this-buffer)
+  (other-window 1)
+  (delete-other-windows))
+
+;;; Special functions:
+(defun org-toc-columns ()
+  "Toggle columns view in the Org buffer from Org TOC."
+  (interactive)
+  (let ((indirect-buffer (current-buffer)))
+    (switch-to-buffer org-toc-base-buffer)
+    (if (not org-toc-columns-shown)
+	(progn (org-columns)
+	       (setq org-toc-columns-shown t))
+      (progn (org-columns-remove-overlays)
+	     (setq org-toc-columns-shown nil)))
+    (switch-to-buffer indirect-buffer)))
+
+(defun org-toc-info ()
+  "Show properties of current subtree in the echo-area."
+  (interactive)
+  (let ((pos (point))
+	(indirect-buffer (current-buffer))
+	props prop msg)
+    (switch-to-buffer org-toc-base-buffer)
+    (goto-char pos)
+    (setq props (org-entry-properties))
+    (while (setq prop (pop props))
+      (unless (or (equal (car prop) "COLUMNS")
+		  (member (car prop) org-toc-info-exclude))
+	(let ((p (car prop))
+	      (v (cdr prop)))
+	  (if (equal p "TAGS")
+	      (setq v (mapconcat 'identity (split-string v ":" t) " ")))
+	  (setq p (concat p ":"))
+	  (add-text-properties 0 (length p) '(face org-special-keyword) p)
+	  (setq msg (concat msg p " " v "  ")))))
+    (switch-to-buffer indirect-buffer)
+    (message msg)))
+
+;;; Store and restore TOC configuration:
+(defun org-toc-store-config ()
+  "Store the current status of the tables of contents in
+`org-toc-config-alist'."
+  (interactive)
+  (let ((file (buffer-file-name org-toc-base-buffer))
+	(pos (point))
+	(hlcfg (org-toc-get-headlines-status)))
+    (setq org-toc-config-alist
+	  (delete (assoc file org-toc-config-alist)
+		  org-toc-config-alist))
+    (add-to-list 'org-toc-config-alist
+		 `(,file ,pos ,org-toc-cycle-global-status ,hlcfg))
+    (message "TOC configuration saved: (%s)"
+	     (if (listp org-toc-cycle-global-status)
+		 (concat "org-content "
+			 (number-to-string
+			  (cadr org-toc-cycle-global-status)))
+	       (symbol-name org-toc-cycle-global-status)))))
+
+(defun org-toc-restore-config ()
+  "Get the stored status in `org-toc-config-alist' and set the
+current table of contents to it."
+  (interactive)
+  (let* ((file (buffer-file-name org-toc-base-buffer))
+	 (conf (cdr (assoc file org-toc-config-alist)))
+	 (pos (car conf))
+	 (status (cadr conf))
+	 (hlcfg (caddr conf)) hlcfg0 ov)
+    (cond ((listp status)
+	   (org-toc-show (cadr status) (point)))
+	  ((eq status 'overview)
+	   (org-overview)
+	   (setq org-cycle-global-status 'overview)
+	   (run-hook-with-args 'org-cycle-hook 'overview))
+	  (t
+	   (org-overview)
+	   (org-content)
+	   (setq org-cycle-global-status 'contents)
+	   (run-hook-with-args 'org-cycle-hook 'contents)))
+    (while (setq hlcfg0 (pop hlcfg))
+      (save-excursion
+	(goto-char (point-min))
+	(when (search-forward (car hlcfg0) nil t)
+	  (unless (org-overlays-at (match-beginning 0))
+	    (setq ov (org-make-overlay (match-beginning 0)
+				       (match-end 0))))
+	  (cond ((eq (cdr hlcfg0) 'children)
+		 (show-children)
+		 (message "CHILDREN")
+		 (org-overlay-put ov 'status 'children))
+		((eq (cdr hlcfg0) 'branches)
+		 (show-branches)
+		 (message "BRANCHES")
+		 (org-overlay-put ov 'status 'branches))))))
+    (goto-char pos)
+    (if org-toc-follow-mode (org-toc-goto))
+    (message "Last TOC configuration restored")
+    (sit-for 1)
+    (if org-toc-info-mode (org-toc-info))))
+
+(defun org-toc-get-headlines-status ()
+  "Return an alist of headlines and their associated folding
+status."
+  (let (output ovs)
+    (save-excursion
+      (goto-char (point-min))
+      (while (and (not (eobp))
+		  (goto-char (next-overlay-change (point))))
+	(when (looking-at "^\\*+ ")
+	  (add-to-list
+	   'output
+	   (cons (buffer-substring-no-properties
+		  (match-beginning 0)
+		  (save-excursion
+		    (end-of-line) (point)))
+		 (overlay-get
+		  (car (overlays-at (point))) 'status))))))
+    ;; return an alist like (("* Headline" . 'status))
+    output))
+
+;; In Org TOC buffer, hide headlines below the first level.
+(defun org-toc-help ()
+  "Display a quick help message in the echo-area for `org-toc-mode'."
+  (interactive)
+  (let ((st-start 0) 
+	(help-message
+	 "\[space\]   show heading                     \[1-4\] hide headlines below this level
+\[TAB\]     jump to heading                  \[f\]   toggle follow mode (currently %s)
+\[return\]  jump and delete others windows   \[i\]   toggle info mode (currently %s)
+\[S-TAB\]   cycle subtree (in Org)           \[S\]   toggle show subtree mode (currently %s)
+\[C-S-TAB\] global cycle (in Org)            \[r\]   toggle recenter mode (currently %s)   
+\[:\]       cycle subtree (in TOC)           \[c\]   toggle column view (currently %s)
+\[n/p\]     next/previous heading            \[s\]   save TOC configuration 
+\[q\]       quit the TOC                     \[g\]   restore last TOC configuration"))
+    (while (string-match "\\[[^]]+\\]" help-message st-start)
+      (add-text-properties (match-beginning 0)
+                           (match-end 0) '(face bold) help-message)
+      (setq st-start (match-end 0)))
+  (message help-message
+    (if org-toc-follow-mode "on" "off")
+    (if org-toc-info-mode "on" "off")
+    (if org-toc-show-subtree-mode "on" "off")
+    (if org-toc-recenter-mode (format "on, line %s" org-toc-recenter) "off")
+    (if org-toc-columns-shown "on" "off"))))
+
+
+;;;;##########################################################################
+;;;;  User Options, Variables
+;;;;##########################################################################
+
+
+
+;;; org-toc.el ends here

+ 37 - 4
ChangeLog

@@ -1,13 +1,46 @@
+2008-01-26  Carsten Dominik  <dominik@science.uva.nl>
+
+	* org.el (org-archive-all-done): Fixed incorrect number of stars
+	in regexp.
+
+2008-01-25  Carsten Dominik  <dominik@science.uva.nl>
+
+	* org.el (org-refile-get-location): New function.
+	(org-refile-goto-last-stored): New function.
+	(org-global-tags-completion-table): Add the value of org-tag-alist
+	in each buffer, to make sure that also unused tags will be
+	available for completion.
+
+2008-01-24  Carsten Dominik  <dominik@carsten-dominiks-macbook-pro.local>
+
+	* org.el (org-columns-edit-value)
+	(org-columns-next-allowed-value): Only update if not in agenda.
+
+2008-01-22  Carsten Dominik  <dominik@science.uva.nl>
+
+	* org.el (org-clocktable-steps): New function.
+	(org-dblock-write:clocktable): Call `org-clocktable-steps'.
+	(org-archive-subtree): Add the outline tree context as a
+	property.
+	(org-closest-date): New optional argument `prefer'.
+	(org-goto-auto-isearch): New option.
+	(org-goto-map, org-get-location): Implement auto-isearch.
+	(org-goto-local-auto-isearch-map): New variable.
+	(org-goto-local-search-forward-headings)
+	(org-goto-local-auto-isearch): New functions
+
+-----------------------------------------------------------------------
+
+Installed as 5.19a
+
+
 2008-01-18  Carsten Dominik  <dominik@science.uva.nl>
 
 	* org.el (org-entry-properties): Include the CLOCKSUM special
 	property.
 	(org-columns-edit-value): Do not allow to edit the special
 	CLOCKSUM property.
-
-2008-01-15  Carsten Dominik  <dominik@science.uva.nl>
-
-	* org.el (org-flag-drawer): Use the original value of
+	(org-flag-drawer): Use the original value of
 	`outline-regexp'.
 	(org-remember-handler): Add invisible-ok flag to call to
 	`org-end-of-subtree'

+ 3 - 0
EXPERIMENTAL/find-links-to-local.el

@@ -0,0 +1,3 @@
+(defun org-find-links ()
+  (let* ((file (buffer-file-name))
+	 (tname (file-truename file)))

+ 328 - 0
EXPERIMENTAL/interactive-query/org-interactive-query.patch.txt

@@ -0,0 +1,328 @@
+--- org-vendor/org.el	2008-01-06 10:30:26.000000000 -0500
++++ org/org.el	2008-01-12 17:19:15.000000000 -0500
+@@ -15078,7 +15078,8 @@
+     (let ((org-last-tags-completion-table
+ 	   (org-global-tags-completion-table)))
+       (setq match (completing-read
+-		   "Match: " 'org-tags-completion-function nil nil nil
++		   "Match: " 'org-tags-completion-function nil nil
++                   org-agenda-query-string
+ 		   'org-tags-history))))
+ 
+   ;; Parse the string and create a lisp form
+@@ -18812,6 +18813,7 @@
+ (defvar org-agenda-follow-mode nil)
+ (defvar org-agenda-show-log nil)
+ (defvar org-agenda-redo-command nil)
++(defvar org-agenda-query-string nil)
+ (defvar org-agenda-mode-hook nil)
+ (defvar org-agenda-type nil)
+ (defvar org-agenda-force-single-file nil)
+@@ -18947,6 +18949,10 @@
+ (org-defkey org-agenda-mode-map [(right)] 'org-agenda-later)
+ (org-defkey org-agenda-mode-map [(left)] 'org-agenda-earlier)
+ (org-defkey org-agenda-mode-map "\C-c\C-x\C-c" 'org-agenda-columns)
++(org-defkey org-agenda-mode-map "=" 'org-agenda-query-clear-cmd)
++(org-defkey org-agenda-mode-map "/" 'org-agenda-query-and-cmd)
++(org-defkey org-agenda-mode-map ";" 'org-agenda-query-or-cmd)
++(org-defkey org-agenda-mode-map "\\" 'org-agenda-query-not-cmd)
+ 
+ (defvar org-agenda-keymap (copy-keymap org-agenda-mode-map)
+   "Local keymap for agenda entries from Org-mode.")
+@@ -20423,9 +20429,10 @@
+     (setq matcher (org-make-tags-matcher match)
+ 	  match (car matcher) matcher (cdr matcher))
+     (org-prepare-agenda (concat "TAGS " match))
++    (setq org-agenda-query-string match)
+     (setq org-agenda-redo-command
+ 	  (list 'org-tags-view (list 'quote todo-only)
+-		(list 'if 'current-prefix-arg nil match)))
++		(list 'if 'current-prefix-arg nil 'org-agenda-query-string)))
+     (setq files (org-agenda-files)
+ 	  rtnall nil)
+     (while (setq file (pop files))
+@@ -20461,7 +20468,7 @@
+       (add-text-properties pos (1- (point)) (list 'face 'org-warning))
+       (setq pos (point))
+       (unless org-agenda-multi
+-	(insert "Press `C-u r' to search again with new search string\n"))
++	(insert "Press `C-u r' to enter new search string; use `/;\\=' to adjust interactively\n"))
+       (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
+     (when rtnall
+       (insert (org-finalize-agenda-entries rtnall) "\n"))
+@@ -20471,6 +20478,275 @@
+     (org-finalize-agenda)
+     (setq buffer-read-only t)))
+ 
++;;; Agenda interactive query manipulation
++
++(defcustom org-agenda-query-selection-single-key t
++  "Non-nil means, query manipulation exits after first change.
++When nil, you have to press RET to exit it.
++During query selection, you can toggle this flag with `C-c'.
++This variable can also have the value `expert'.  In this case, the window
++displaying the tags menu is not even shown, until you press C-c again."
++  :group 'org-agenda
++  :type '(choice
++	  (const :tag "No" nil)
++	  (const :tag "Yes" t)
++	  (const :tag "Expert" expert)))
++
++(defun org-agenda-query-selection (current op table &optional todo-table)
++  "Fast query manipulation with single keys.
++CURRENT is the current query string, OP is the initial
++operator (one of \"+|-=\"), TABLE is an alist of tags and
++corresponding keys, possibly with grouping information.
++TODO-TABLE is a similar table with TODO keywords, should these
++have keys assigned to them.  If the keys are nil, a-z are
++automatically assigned.  Returns the new query string, or nil to
++not change the current one."
++  (let* ((fulltable (append table todo-table))
++	 (maxlen (apply 'max (mapcar
++			      (lambda (x)
++				(if (stringp (car x)) (string-width (car x)) 0))
++			      fulltable)))
++	 (fwidth (+ maxlen 3 1 3))
++	 (ncol (/ (- (window-width) 4) fwidth))
++	 (expert (eq org-agenda-query-selection-single-key 'expert))
++	 (exit-after-next org-agenda-query-selection-single-key)
++	 (done-keywords org-done-keywords)
++         tbl char cnt e groups ingroup
++	 tg c2 c c1 ntable rtn)
++    (save-window-excursion
++      (if expert
++	  (set-buffer (get-buffer-create " *Org tags*"))
++	(delete-other-windows)
++	(split-window-vertically)
++	(org-switch-to-buffer-other-window (get-buffer-create " *Org tags*")))
++      (erase-buffer)
++      (org-set-local 'org-done-keywords done-keywords)
++      (insert "Query:    " current "\n")
++      (org-agenda-query-op-line op)
++      (insert "\n\n")
++      (org-fast-tag-show-exit exit-after-next)
++      (setq tbl fulltable char ?a cnt 0)
++      (while (setq e (pop tbl))
++	(cond
++	 ((equal e '(:startgroup))
++	  (push '() groups) (setq ingroup t)
++	  (when (not (= cnt 0))
++	    (setq cnt 0)
++	    (insert "\n"))
++	  (insert "{ "))
++	 ((equal e '(:endgroup))
++	  (setq ingroup nil cnt 0)
++	  (insert "}\n"))
++	 (t
++	  (setq tg (car e) c2 nil)
++	  (if (cdr e)
++	      (setq c (cdr e))
++	    ;; automatically assign a character.
++	    (setq c1 (string-to-char
++		      (downcase (substring
++				 tg (if (= (string-to-char tg) ?@) 1 0)))))
++	    (if (or (rassoc c1 ntable) (rassoc c1 table))
++		(while (or (rassoc char ntable) (rassoc char table))
++		  (setq char (1+ char)))
++	      (setq c2 c1))
++	    (setq c (or c2 char)))
++	  (if ingroup (push tg (car groups)))
++	  (setq tg (org-add-props tg nil 'face
++				  (cond
++				   ((not (assoc tg table))
++				    (org-get-todo-face tg))
++				   (t nil))))
++	  (if (and (= cnt 0) (not ingroup)) (insert "  "))
++	  (insert "[" c "] " tg (make-string
++				 (- fwidth 4 (length tg)) ?\ ))
++	  (push (cons tg c) ntable)
++	  (when (= (setq cnt (1+ cnt)) ncol)
++	    (insert "\n")
++	    (if ingroup (insert "  "))
++	    (setq cnt 0)))))
++      (setq ntable (nreverse ntable))
++      (insert "\n")
++      (goto-char (point-min))
++      (if (and (not expert) (fboundp 'fit-window-to-buffer))
++	  (fit-window-to-buffer))
++      (setq rtn
++	    (catch 'exit
++	      (while t
++		(message "[a-z..]:Toggle [SPC]:clear [RET]:accept [TAB]:free%s%s"
++			 (if groups " [!] no groups" " [!]groups")
++			 (if expert " [C-c]:window" (if exit-after-next " [C-c]:single" " [C-c]:multi")))
++		(setq c (let ((inhibit-quit t)) (read-char-exclusive)))
++		(cond
++		 ((= c ?\r) (throw 'exit t))
++		 ((= c ?!)
++		  (setq groups (not groups))
++		  (goto-char (point-min))
++		  (while (re-search-forward "[{}]" nil t) (replace-match " ")))
++		 ((= c ?\C-c)
++		  (if (not expert)
++		      (org-fast-tag-show-exit
++		       (setq exit-after-next (not exit-after-next)))
++		    (setq expert nil)
++		    (delete-other-windows)
++		    (split-window-vertically)
++		    (org-switch-to-buffer-other-window " *Org tags*")
++		    (and (fboundp 'fit-window-to-buffer)
++			 (fit-window-to-buffer))))
++		 ((or (= c ?\C-g)
++		      (and (= c ?q) (not (rassoc c ntable))))
++		  (setq quit-flag t))
++		 ((= c ?\ )
++		  (setq current "")
++		  (if exit-after-next (setq exit-after-next 'now)))
++		 ((= c ?\[)             ; clear left
++                  (org-agenda-query-decompose current)
++                  (setq current (concat "/" (match-string 2 current)))
++		  (if exit-after-next (setq exit-after-next 'now)))
++		 ((= c ?\])             ; clear right
++                  (org-agenda-query-decompose current)
++                  (setq current (match-string 1 current))
++		  (if exit-after-next (setq exit-after-next 'now)))
++		 ((= c ?\t)
++		  (condition-case nil
++		      (setq current (read-string "Query: " current))
++		    (quit))
++		  (if exit-after-next (setq exit-after-next 'now)))
++                 ;; operators
++                 ((or (= c ?/) (= c ?+)) (setq op "+"))
++                 ((or (= c ?\;) (= c ?|)) (setq op "|"))
++                 ((or (= c ?\\) (= c ?-)) (setq op "-"))
++                 ((= c ?=) (setq op "="))
++                 ;; todos
++                 ((setq e (rassoc c todo-table) tg (car e))
++                  (setq current (org-agenda-query-manip
++                                 current op groups 'todo tg))
++                  (if exit-after-next (setq exit-after-next 'now)))
++                 ;; tags
++                 ((setq e (rassoc c ntable) tg (car e))
++                  (setq current (org-agenda-query-manip
++                                 current op groups 'tag tg))
++                  (if exit-after-next (setq exit-after-next 'now))))
++		(if (eq exit-after-next 'now) (throw 'exit t))
++		(goto-char (point-min))
++		(beginning-of-line 1)
++		(delete-region (point) (point-at-eol))
++                (insert "Query:    " current)
++                (beginning-of-line 2)
++                (delete-region (point) (point-at-eol))
++                (org-agenda-query-op-line op)
++		(goto-char (point-min)))))
++      (if rtn current nil))))
++
++(defun org-agenda-query-op-line (op)
++  (insert "Operator: "
++          (org-agenda-query-op-entry (equal op "+") "/+" "and")
++          (org-agenda-query-op-entry (equal op "|") ";|" "or")
++          (org-agenda-query-op-entry (equal op "-") "\\-" "not")
++          (org-agenda-query-op-entry (equal op "=") "=" "clear")))
++
++(defun org-agenda-query-op-entry (matchp chars str)
++  (if matchp
++      (org-add-props (format "[%s %s]  " chars (upcase str))
++          nil 'face 'org-todo)
++    (format "[%s]%s   " chars str)))
++
++(defun org-agenda-query-decompose (current)
++  (string-match "\\([^/]*\\)/?\\(.*\\)" current))
++
++(defun org-agenda-query-clear (current prefix tag)
++  (if (string-match (concat prefix "\\b" (regexp-quote tag) "\\b") current)
++      (replace-match "" t t current)
++    current))
++
++(defun org-agenda-query-manip (current op groups kind tag)
++  "Apply an operator to a query string and a tag.
++CURRENT is the current query string, OP is the operator, GROUPS is a
++list of lists of tags that are mutually exclusive.  KIND is 'tag for a
++regular tag, or 'todo for a TODO keyword, and TAG is the tag or
++keyword string."
++  ;; If this tag is already in query string, remove it.
++  (setq current (org-agenda-query-clear current "[-\\+&|]?" tag))
++  (if (equal op "=") current
++    ;; When using AND, also remove mutually exclusive tags.
++    (if (equal op "+")
++        (loop for g in groups do
++              (if (member tag g)
++                  (mapc (lambda (x)
++                          (setq current
++                                (org-agenda-query-clear current "\\+" x)))
++                        g))))
++    ;; Decompose current query into q1 (tags) and q2 (TODOs).
++    (org-agenda-query-decompose current)
++    (let* ((q1 (match-string 1 current))
++           (q2 (match-string 2 current)))
++      (cond
++       ((eq kind 'tag)
++        (concat q1 op tag "/" q2))
++       ;; It's a TODO; when using AND, drop all other TODOs.
++       ((equal op "+")
++        (concat q1 "/+" tag))
++       (t
++        (concat q1 "/" q2 op tag))))))
++
++(defun org-agenda-query-global-todo-keys (&optional files)
++  "Return alist of all TODO keywords and their fast keys, in all FILES."
++  (let (alist)
++    (unless (and files (car files))
++      (setq files (org-agenda-files)))
++    (save-excursion
++      (loop for f in files do
++            (set-buffer (find-file-noselect f))
++            (loop for k in org-todo-key-alist do
++                  (setq alist (org-agenda-query-merge-todo-key
++                               alist k)))))
++    alist))
++
++(defun org-agenda-query-merge-todo-key (alist entry)
++  (let (e)
++    (cond
++     ;; if this is not a keyword (:startgroup, etc), ignore it
++     ((not (stringp (car entry))))
++     ;; if keyword already exists, replace char if it's null
++     ((setq e (assoc (car entry) alist))
++      (when (null (cdr e)) (setcdr e (cdr entry))))
++     ;; if char already exists, prepend keyword but drop char
++     ((rassoc (cdr entry) alist)
++      (error "TRACE POSITION 2")
++      (setq alist (cons (cons (car entry) nil) alist)))
++     ;; else, prepend COPY of entry
++     (t
++      (setq alist (cons (cons (car entry) (cdr entry)) alist)))))
++  alist)
++
++(defun org-agenda-query-generic-cmd (op)
++  "Activate query manipulation with OP as initial operator."
++  (let ((q (org-agenda-query-selection org-agenda-query-string op
++                                       org-tag-alist 
++                                       (org-agenda-query-global-todo-keys))))
++    (when q
++      (setq org-agenda-query-string q)
++      (org-agenda-redo))))
++
++(defun org-agenda-query-clear-cmd ()
++  "Activate query manipulation, to clear a tag from the string."
++  (interactive)
++  (org-agenda-query-generic-cmd "="))
++
++(defun org-agenda-query-and-cmd ()
++  "Activate query manipulation, initially using the AND (+) operator."
++  (interactive)
++  (org-agenda-query-generic-cmd "+"))
++
++(defun org-agenda-query-or-cmd ()
++  "Activate query manipulation, initially using the OR (|) operator."
++  (interactive)
++  (org-agenda-query-generic-cmd "|"))
++
++(defun org-agenda-query-not-cmd ()
++  "Activate query manipulation, initially using the NOT (-) operator."
++  (interactive)
++  (org-agenda-query-generic-cmd "-"))
++
+ ;;; Agenda Finding stuck projects
+ 
+ (defvar org-agenda-skip-regexp nil

File diff suppressed because it is too large
+ 28057 - 0
EXPERIMENTAL/interactive-query/org.el


File diff suppressed because it is too large
+ 8355 - 2555
org_xemacs.el


+ 70 - 0
EXPERIMENTAL/john.el

@@ -0,0 +1,70 @@
+(require 'org-install)
+
+(add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
+
+(define-key mode-specific-map [?a] 'org-agenda)
+
+(eval-after-load "org"
+  '(progn
+     (define-prefix-command 'org-todo-state-map)
+
+     (define-key org-mode-map "\C-cx" 'org-todo-state-map)
+
+     (define-key org-todo-state-map "x"
+       #'(lambda nil (interactive) (org-todo "CANCELLED")))
+     (define-key org-todo-state-map "d"
+       #'(lambda nil (interactive) (org-todo "DONE")))
+     (define-key org-todo-state-map "f"
+       #'(lambda nil (interactive) (org-todo "DEFERRED")))
+     (define-key org-todo-state-map "l"
+       #'(lambda nil (interactive) (org-todo "DELEGATED")))
+     (define-key org-todo-state-map "s"
+       #'(lambda nil (interactive) (org-todo "STARTED")))
+     (define-key org-todo-state-map "w"
+       #'(lambda nil (interactive) (org-todo "WAITING")))
+
+     (define-key org-agenda-mode-map "\C-n" 'next-line)
+     (define-key org-agenda-keymap "\C-n" 'next-line)
+     (define-key org-agenda-mode-map "\C-p" 'previous-line)
+     (define-key org-agenda-keymap "\C-p" 'previous-line)))
+
+(require 'remember)
+
+(add-hook 'remember-mode-hook 'org-remember-apply-template)
+
+(define-key global-map [(control meta ?r)] 'remember)
+
+(custom-set-variables
+ '(org-agenda-files (quote ("~/todo.org")))
+ '(org-default-notes-file "~/notes.org")
+ '(org-agenda-ndays 7)
+ '(org-deadline-warning-days 14)
+ '(org-agenda-show-all-dates t)
+ '(org-agenda-skip-deadline-if-done t)
+ '(org-agenda-skip-scheduled-if-done t)
+ '(org-agenda-start-on-weekday nil)
+ '(org-reverse-note-order t)
+ '(org-fast-tag-selection-single-key (quote expert))
+ '(org-agenda-custom-commands
+   (quote (("d" todo "DELEGATED" nil)
+           ("c" todo "DONE|DEFERRED|CANCELLED" nil)
+           ("w" todo "WAITING" nil)
+           ("W" agenda "" ((org-agenda-ndays 21)))
+           ("A" agenda ""
+            ((org-agenda-skip-function
+              (lambda nil
+                (org-agenda-skip-entry-if (quote notregexp) "\\=.*\\[#A\\]")))
+             (org-agenda-ndays 1)
+             (org-agenda-overriding-header "Today's Priority #A tasks: ")))
+           ("u" alltodo ""
+            ((org-agenda-skip-function
+              (lambda nil
+                (org-agenda-skip-entry-if (quote scheduled) (quote deadline)
+                                          (quote regexp) "<[^>\n]+>")))
+             (org-agenda-overriding-header "Unscheduled TODO entries: "))))))
+ '(org-remember-store-without-prompt t)
+ '(org-remember-templates
+   (quote ((116 "* TODO %?\n  %u" "./todo.txt" "Tasks")
+           (110 "* %u %?" "./notes.txt" "Notes"))))
+ '(remember-annotation-functions (quote (org-remember-annotation)))
+ '(remember-handler-functions (quote (org-remember-handler))))

+ 154 - 0
EXPERIMENTAL/org-bibtex.el

@@ -0,0 +1,154 @@
+;;; org-bibtex.el --- Org links to BibTeX entries
+;;
+;; Copyright 2007 Bastien Guerry
+;;
+;; Author: bzg AT altern DOT org
+;; Version: 0.2
+;; Keywords: org, wp, remember
+;; URL: http://www.cognition.ens.fr/~guerry/u/org-bibtex.el
+;;
+;; This program 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 3, or (at your option)
+;; any later version.
+;;
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+;;; Commentary:
+;;
+;; The Org mode already lets you store/insert links to BibTeX entries.
+;;
+;; But what if you want to insert the author or the title of a BibTeX
+;; item in a *remember* buffer?  This library lets you deal with this 
+;; by adding more properties to the BibTeX link.
+;;
+;; The available properties for each entry are listed here:
+;;
+;; :author        :publisher      :volume      :pages
+;; :editor        :url            :number      :journal
+;; :title         :year           :series      :address
+;; :booktitle     :month          :annote      :abstract
+;; :key           :btype
+;; 
+;; Here is an example of a remember template that use some of this
+;; information (:author :year :title :journal :pages):
+;; 
+;; (setq org-remember-templates 
+;;   '((?b "* READ %?\n\n%a\n\n%:author (%:year): %:title\n   \
+;;          In %:journal, %:pages.")))
+;; 
+;; Let's say you want to remember this BibTeX entry:
+;; 
+;; @Article{dolev83,
+;;   author = 	 {Danny Dolev and Andrew C. Yao},
+;;   title = 	 {On the security of public-key protocols},
+;;   journal = 	 {IEEE Transaction on Information Theory},
+;;   year = 	 1983,
+;;   volume =	 2,
+;;   number =	 29,
+;;   pages =	 {198--208},
+;;   month =	 {Mars}
+;; }
+;; 
+;; M-x `org-remember' on this entry will produce this buffer:
+;; 
+;; =====================================================================
+;; * READ <== [point here]
+;; 
+;; [[file:/file.bib::dolev83][Dolev & Yao 1983: security of public key protocols]]
+;; 
+;; Danny Dolev and Andrew C. Yao (1983): On the security of public-key protocols
+;; In IEEE Transaction on Information Theory, 198--208.
+;; =====================================================================
+;;
+;;; History:
+;; 
+;; This piece of code was inspired by a request of Austin Frank:
+;;   http://article.gmane.org/gmane.emacs.orgmode/4112
+;;
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'org-bibtex)
+
+;;; Code:
+
+(provide 'org-bibtex)
+
+(require 'org)
+
+(defvar description nil) ; dynamically scoped in org.el
+
+(org-add-link-type "bibtex" 'org-bibtex-open)
+(add-hook 'org-store-link-functions 'org-bibtex-store-link)
+
+;; (defun org-bibtex-publish (path)
+;;   "Build the description of the BibTeX entry for publishing."
+;;   (let* ((search (when (string-match "::\\(.+\\)\\'" path)
+;; 		   (match-string 1 path)))
+;; 	 (path (substring path 0 (match-beginning 0)))
+;; 	 key)
+;;     (with-temp-buffer
+;;       (org-open-file path t nil search)
+;;       (setq key (org-create-file-search-functions)))
+;;     (or description key)))
+
+(defun org-bibtex-open (path)
+  "Visit the bibliography entry on PATH."
+  (let* ((search (when (string-match "::\\(.+\\)\\'" path)
+		   (match-string 1 path)))
+	 (path (substring path 0 (match-beginning 0))))
+    (org-open-file path t nil search)))
+
+(defun org-bibtex-store-link ()
+  "Store a link to a BibTeX entry."
+  (when (eq major-mode 'bibtex-mode)
+    (let* ((search (run-hook-with-args-until-success
+		    'org-create-file-search-functions))
+	   (link (concat "file:" (abbreviate-file-name buffer-file-name)
+			 "::" search))
+	   (entry (mapcar ; repair strings enclosed in "..." or {...}
+		   (lambda(c)
+		     (if (string-match
+			  "^\\(?:{\\|\"\\)\\(.*\\)\\(?:}\\|\"\\)$" (cdr c))
+			 (cons (car c) (match-string 1 (cdr c))) c))
+		   (save-excursion
+		     (bibtex-beginning-of-entry)
+		     (bibtex-parse-entry)))))
+      (org-store-link-props
+       :key (cdr (assoc "=key=" entry))
+       :author (or (cdr (assoc "author" entry)) "[no author]")
+       :editor (or (cdr (assoc "editor" entry)) "[no editor]")
+       :title (or (cdr (assoc "title" entry)) "[no title]")
+       :booktitle (or (cdr (assoc "booktitle" entry)) "[no booktitle]")
+       :journal (or (cdr (assoc "journal" entry)) "[no journal]")
+       :publisher (or (cdr (assoc "publisher" entry)) "[no publisher]")
+       :pages (or (cdr (assoc "pages" entry)) "[no pages]")
+       :url (or (cdr (assoc "url" entry)) "[no url]")
+       :year (or (cdr (assoc "year" entry)) "[no year]")
+       :month (or (cdr (assoc "month" entry)) "[no month]")
+       :address (or (cdr (assoc "address" entry)) "[no address]")
+       :volume (or (cdr (assoc "volume" entry)) "[no volume]")
+       :number (or (cdr (assoc "number" entry)) "[no number]")
+       :annote (or (cdr (assoc "annote" entry)) "[no annotation]")
+       :series (or (cdr (assoc "series" entry)) "[no series]")
+       :abstract (or (cdr (assoc "abstract" entry)) "[no abstract]")
+       :btype (or (cdr (assoc "=type=" entry)) "[no type]")
+       :type "bibtex"
+       :link link
+       :description description))))
+
+(provide 'org-bibtex)
+
+
+;;;;##########################################################################
+;;;;  User Options, Variables
+;;;;##########################################################################
+
+
+;;; org-bibtex.el ends here

+ 235 - 0
EXPERIMENTAL/org-depend.el

@@ -0,0 +1,235 @@
+;;; org-depend.el --- TODO dependencies for Org-mode
+
+;; This file is not part of GNU Emacs.
+;;
+;; This file 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 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs 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., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; WARNING: This file is just a PROOF OF CONCEPT, not a supported part
+;;          of Org-mode.
+;;
+;; This is an example implementation of TODO dependencies in Org-mode.
+;; It uses the new hooks in version 5.13 of Org-mode,
+;; `org-trigger-hook' and `org-blocker-hook'.
+;;
+;; It implements the following:
+;;
+;; Triggering
+;; ----------
+;;
+;; 1) If an entry contains a TRIGGER property that contains the string
+;;    "chain-siblings(KEYWORD)", then switching that entry to DONE does
+;;    do the following:
+;;    - The sibling following this entry switched to todo-state KEYWORD.
+;;    - The sibling also gets a TRIGGER property "chain-sibling(KEYWORD)",
+;;      property, to make sure that, when *it* is DONE, the chain will
+;;      continue.
+;;
+;; 2) If the TRIGGER property contains any other words like
+;;    XYZ(KEYWORD), these are treated as entry id's with keywords.  That
+;;    means, Org-mode will search for an entry with the ID property XYZ
+;;    and switch that entry to KEYWORD as well.
+;;
+;; Blocking
+;; --------
+;;
+;; 1) If an entry contains a BLOCKER property that contains the word
+;;    "previous-sibling", the sibling above the current entry is
+;;    checked when you try to mark it DONE.  If it is still in a TODO
+;;    state, the current state change is blocked.
+;;
+;; 2) If the BLOCKER property contains any other words, these are
+;;    treated as entry id's.  That means, Org-mode will search for an
+;;    entry with the ID property exactly equal to this word.  If any
+;;    of these entries is not yet marked DONE, the current state change
+;;    will be blocked.
+;;
+;; 3) Whenever a state change is blocked, an org-mark is pushed, so that
+;;    you can find the offending entry with `C-c &'.
+;;
+;;; Example:
+;;
+;; When trying this example, make sure that the settings for TODO keywords
+;; have been activated, i.e. include the following line and press C-c C-c
+;; on the line before working with the example:
+;;
+;; #+TYP_TODO: TODO NEXT | DONE
+;;
+;; * TODO Win a million in Las Vegas
+;;   The "third" TODO (see above) cannot become a TODO without this money.
+;;
+;;   :PROPERTIES:
+;;     :ID: I-cannot-do-it-without-money
+;;   :END:
+;;
+;; * Do this by doing a chain of TODO's
+;; ** NEXT This is the first in this chain
+;;    :PROPERTIES:
+;;      :TRIGGER: chain-siblings(NEXT)
+;;    :END:
+;; 
+;; ** This is the second in this chain
+;;
+;; ** This is the third in this chain
+;;    :PROPERTIES:
+;;      :BLOCKER: I-cannot-do-it-without-money
+;;    :END:
+;;
+;; ** This is the forth in this chain
+;;    When this is DONE, we will also trigger entry XYZ-is-my-id
+;;   :PROPERTIES:
+;;     :TRIGGER: XYZ-is-my-id(TODO)
+;;   :END:
+;;
+;; ** This is the fifth in this chain
+;; 
+;; * Start writing report
+;;   :PROPERTIES:
+;;     :ID: XYZ-is-my-id
+;;   :END:
+;;
+;;
+
+(require 'org)
+
+(defun org-depend-trigger-todo (change-plist)
+  "Trigger new TODO entries after the current is switched to DONE.
+This does two different kinds of triggers:
+
+- If the current entry contains a TRIGGER property that contains
+  \"chain-siblings(KEYWORD)\", it goes to the next sibling, marks it
+  KEYWORD and also installs the \"chain-sibling\" trigger to continue
+  the chain.
+- Any other word (space-separated) like XYZ(KEYWORD) in the TRIGGER
+  property is seen as an entry id.  Org-mode finds the entry with the
+  corresponding ID property and switches it to the state TODO as well."
+
+  ;; Get information from the plist
+  (let* ((type (plist-get change-plist :type))
+	       (pos (plist-get change-plist :position))
+	 (from (plist-get change-plist :from))
+	 (to (plist-get change-plist :to))
+	 (org-log-done nil) ; IMPROTANT!: no logging during automatic trigger!
+	 trigger triggers tr p1 kwd)
+    (catch 'return
+      (unless (eq type 'todo-state-change)
+	;; We are only handling todo-state-change....
+	(throw 'return t))
+      (unless (and (member from org-not-done-keywords)
+		   (member to org-done-keywords))
+	;; This is not a change from TODO to DONE, ignore it
+	(throw 'return t))
+
+      ;; OK, we just switched from a TODO state to a DONE state
+      ;; Lets see if this entry has a TRIGGER property.
+      ;; If yes, split it up on whitespace.
+      (setq trigger (org-entry-get pos "TRIGGER")
+	    triggers (and trigger (org-split-string trigger "[ \t]+")))
+
+      ;; Go through all the triggers
+      (while (setq tr (pop triggers))
+	(cond
+	 ((string-match "\\`chain-siblings(\\(.*?\\))\\'" tr)
+	  ;; This is a TODO chain of siblings
+	  (setq kwd (match-string 1 tr))
+	  (catch 'exit
+	    (save-excursion
+	      (goto-char pos)
+	      ;; find the sibling, exit if no more siblings
+	      (condition-case nil
+		  (outline-forward-same-level 1)
+		(error (throw 'exit t)))
+	      ;; mark the sibling TODO
+	      (org-todo kwd)
+	      ;; make sure the sibling will continue the chain
+	      (org-entry-add-to-multivalued-property
+	       nil "TRIGGER" (format "chain-siblings(%s)" kwd)))))
+
+	 ((string-match "\\`\\(\\S-+\\)(\\(.*?\\))\\'" tr)
+	  ;; This seems to be ENTRY_ID(KEYWORD)
+	  (setq id (match-string 1 tr)
+		kwd (match-string 2 tr)
+		p1 (org-find-entry-with-id id))
+	  (when p1
+	    ;; there is an entry with this ID, mark it TODO
+	    (save-excursion
+	      (goto-char p1)
+	      (org-todo kwd)))))))))
+
+(defun org-depend-block-todo (change-plist)
+  "Block turning an entry into a TODO.
+This checks for a BLOCKER property in an entry and checks
+all the entries listed there.  If any of them is not done,
+block changing the current entry into a TODO entry.  If the property contains
+the word \"previous-sibling\", the sibling above the current entry is checked.
+Any other words are treated as entry id's. If an entry exists with the
+this ID property, that entry is also checked."
+  ;; Get information from the plist
+  (let* ((type (plist-get change-plist :type))
+	       (pos (plist-get change-plist :position))
+	 (from (plist-get change-plist :from))
+	 (to (plist-get change-plist :to))
+	 (org-log-done nil) ; IMPROTANT!: no logging during automatic trigger
+	 blocker blockers bl p1)
+    (catch 'return
+      (unless (eq type 'todo-state-change)
+	;; We are not handling this kind of change
+	(throw 'return t))
+      (unless (and (not from) (member to org-not-done-keywords))
+	;; This is not a change from nothing to TODO, ignore it
+	(throw 'return t))
+
+      ;; OK, the plan is to switch from nothing to TODO
+      ;; Lets see if we will allow it.  Find the BLOCKER property
+      ;; and split it on whitespace.
+      (setq blocker (org-entry-get pos "BLOCKER")
+	    blockers (and blocker (org-split-string blocker "[ \t]+")))
+
+      ;; go through all the blockers
+      (while (setq bl (pop blockers))
+	(cond
+	 ((equal bl "previous-sibling")
+	  ;; the sibling is required to be DONE.
+	  (catch 'ignore
+	    (save-excursion
+	      (goto-char pos)
+	      ;; find the older sibling, exit if no more siblings
+	      (condition-case nil
+		  (outline-backward-same-level 1)
+		(error (throw 'ignore t)))
+	      ;; Check if this entry is not yet done and block
+	      (unless (org-entry-is-done-p)
+		;; return nil, to indicate that we block the change!
+		(org-mark-ring-push)
+		(throw 'return nil)))))
+
+	 ((setq p1 (org-find-entry-with-id bl))
+	  ;; there is an entry with this ID, check it out
+	  (save-excursion
+	    (goto-char p1)
+	    (unless (org-entry-is-done-p)
+	      ;; return nil, to indicate that we block the change!
+	      (org-mark-ring-push)
+	      (throw 'return nil))))))
+      t ; return t to indicate that we are not blocking
+      )))
+
+(add-hook 'org-trigger-hook 'org-depend-trigger-todo)
+(add-hook 'org-blocker-hook 'org-depend-block-todo)
+
+;;; org-depend.el ends here

+ 158 - 0
EXPERIMENTAL/org-elisp-symbol.el

@@ -0,0 +1,158 @@
+;;; org-elisp-symbol.el --- Org links to emacs-lisp symbols
+;;
+;; Copyright 2007 Bastien Guerry
+;;
+;; Author: bzg AT altern DOT org
+;; Version: 0.2
+;; Keywords: org, remember, lisp
+;; URL: http://www.cognition.ens.fr/~guerry/u/org-elisp-symbol.el
+;;
+;; This program 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 3, or (at your option)
+;; any later version.
+;;
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+;;; Commentary:
+;;
+;; Org-mode already lets you store/insert links to emacs-lisp files,
+;; just like any other file.  This package lets you precisely link to
+;; any emacs-lisp symbol and access uesful information about the symbol.
+;;
+;; Here is the list of available properties when linking from a elisp-symbol:
+;;
+;; :name        The symbol's name.
+;; :stype       The symbol's type (commandp, function, etc.)
+;; :def         The function used to set the symbol's value (defun, etc.)
+;; :keys        The keys associated with the command.
+;; :args        The arguments of the function.
+;; :docstring   The docstring of the symbol.
+;; :doc         The first line of the dostring.
+;; :comment     A comment line just above the sexp, if any.
+;; :fixme       A FIXME comment line just above the sexp, if any.
+;;
+;; Let's say we have a defun like this one:
+;;
+;; ;; FIXME update docstring
+;; (defun org-export-latex-lists ()
+;;   "Convert lists to LaTeX."
+;;   (goto-char (point-min))
+;;   (while (re-search-forward org-export-latex-list-beginning-re nil t)
+;;     (beginning-of-line)
+;;     (insert (org-list-to-latex (org-list-parse-list t)) "\n")))
+;;
+;; And a remember template like:
+;;
+;; (setq org-remember-templates 
+;;   '((?s "* DEBUG `%:name' (%:args)\n\n%?\n\nFixme: %:fixme\n  \
+;;          Doc: \"%:doc\"\n\n%a")))
+;;
+;; Then M-x `org-remember' on this sexp will produce this buffer:
+;;
+;; =====================================================================
+;; * DEBUG `org-export-latex-lists' ()
+;;
+;; <== point
+;;
+;; Fixme: update the docstring
+;; Doc: "Convert lists to LaTeX."
+;;
+;; [[file:~/path/file.el::defun%20org-export-latex-lists][Function: org-export-latex-lists]]
+;; =====================================================================
+;;
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'org-elisp-symbol)
+
+;;; Code:
+
+(provide 'org-elisp-symbol)
+
+(require 'org)
+
+(org-add-link-type "elisp-symbol" 'org-elisp-symbol-open)
+(add-hook 'org-store-link-functions 'org-elisp-symbol-store-link)
+
+(defun org-elisp-symbol-open (path)
+  "Visit the emacs-lisp elisp-symbol at PATH."
+  (let* ((search (when (string-match "::\\(.+\\)\\'" path)
+		   (match-string 1 path)))
+	 (path (substring path 0 (match-beginning 0))))
+    (org-open-file path t nil search)))
+
+(defun org-elisp-symbol-store-link ()
+  "Store a link to an emacs-lisp elisp-symbol."
+  (when (eq major-mode 'emacs-lisp-mode)
+    (save-excursion
+      (or (looking-at "^(") (beginning-of-defun))
+      (looking-at "^(\\([a-z]+\\) \\([^)\n ]+\\) ?\n?[ \t]*\\(?:(\\(.*\\))\\)?")
+      (let* ((end (save-excursion 
+		    (save-match-data 
+		      (end-of-defun) (point))))
+	     (def (match-string 1))
+	     (name (match-string 2))
+	     (sym-name (intern-soft name))
+	     (stype (cond ((commandp sym-name) "Command")
+			  ((functionp sym-name) "Function")
+			  ((user-variable-p sym-name) "User variable")
+			  ((eq def "defvar") "Variable")
+			  ((eq def "defmacro") "Macro")
+			  (t "Symbol")))
+	     (args (if (match-string 3)
+		       (mapconcat (lambda (a) (unless (string-match "^&" a) a))
+				  (split-string (match-string 3)) " ") 
+		     "no arg"))
+	     (docstring (cond ((functionp sym-name)
+			       (documentation sym-name))
+			      ((string-match "[Vv]ariable" stype)
+			       (documentation-property sym-name 
+						       'variable-documentation))
+			      (t "no documentation")))
+	     (doc (and (string-match "^\\([^\n]+\\)$" docstring)
+		       (match-string 1 docstring)))
+	     (fixme (save-excursion
+		      (beginning-of-defun) (end-of-defun)
+		      (if (re-search-forward "^;+ ?FIXME[ :]*\\(.*\\)$" end t)
+			  (match-string 1) "nothing to fix")))
+	     (comment (save-excursion
+			(beginning-of-defun) (end-of-defun)
+			(if (re-search-forward "^;;+ ?\\(.*\\)$" end t)
+			    (match-string 1) "no comment")))
+	     keys keys-desc link description)
+	(if (equal stype "Command")
+	    (setq keys (where-is-internal sym-name)
+		  keys-desc
+		  (if keys (mapconcat 'key-description keys " ") "none")))
+	(setq link (concat "file:" (abbreviate-file-name buffer-file-name)
+			   "::" def " " name))
+	(setq description (concat stype ": " name))
+	(org-store-link-props
+	 :type "elisp-symbol"
+	 :link link 
+	 :description description
+	 :def def
+	 :name name
+	 :stype stype
+	 :args args
+	 :keys keys-desc
+	 :docstring docstring
+	 :doc doc
+	 :fixme fixme
+	 :comment comment)))))
+
+(provide 'org-elisp-symbol)
+
+
+;;;;##########################################################################
+;;;;  User Options, Variables
+;;;;##########################################################################
+
+
+;;; org-elisp-symbol.el ends here

+ 135 - 0
EXPERIMENTAL/org-fastup.el

@@ -0,0 +1,135 @@
+;; Then I don't really thing you would have to be able to customize 
+;; this, as there are only very few operations for which this makes 
+;; sense:
+
+;; A****  Archive
+;; T**** Mark TODO
+;; D**** Mark DONE
+;; N**** Cycle TODO to the next state
+
+;; Can't really think of anything else.
+
+
+;; I prefer configurable, because then people can use numbers. This is
+;; the idea that the editor may have limited UI. I'm using a j2me based
+;; editor called JPE at the moment:
+;; http://my-communicator.com/s80/software/applications.php?fldAuto=556&faq=2
+
+;; But other people may be using something like this: 
+;; http://www.getjar.com/products/3960/TextEditor
+
+;; Or this which i'm currently playing with: 
+;; http://www.bermin.net/index.html
+
+;; As for other things, it depends on what you want emacs to be able to
+;; do with an externally changed org mode file. For me this is about
+;; using org mode in an intelligent way with my mobile phone/pda. I can
+;; imagine wanting to write functions like:
+
+;; * move this huge piece of text and tables down a level
+;; <* move this huge piece of text and tables up a level
+;; M* ask to recategorise this heading when i open org mode
+;; +* remind me about this when i open org mode so i can brain dump on it
+;;    in a real editor.
+;; D* ask me to schedule this as an event when i open org mode.
+;; O* open my mail client to send an email to this email address i just got
+;; C* search bbdb for the contact details of the phone no on this line.
+;; c* search ldap for the contact details of this name
+;; B* open a web browser to this link i wanted to check out when i got back to my machine
+;; R* remind me to look at TheseSearchTags headings when i get back to my machine.
+
+
+(defcustom org-fastup-action-alist
+  '((?A org-archive t)
+    (?T (org-todo 1) nil)
+    (?D (org-todo (length org-todo-keywords)) nil)
+    (?N org-todo nil)
+    (?< org-promote-subtree t)
+    (?> org-demote-subtree t)
+    (?M org-set-tags nil)
+    (?S org-schedule t))
+  "List of fastupdate actions.
+Each entry in this list is a list of 3 items:
+
+- A character representing the fastupdate action
+- A function or form to be executed, with cursor at beginning of headline
+- A flag indicating if execution of this action should normally be confirmed."
+  :group 'org-fastup
+  :type '(repeat
+	  (list  :value (?a  nil t)
+	   (character :tag "Prefix char")
+	   (choice
+	    (const :tag "Archive this subtree" org-archive)
+	    (const :tag "Make TODO" (org-todo 1))
+	    (const :tag "Mark DONE" (org-todo (length org-todo-keywords)))
+	    (const :tag "Cycle TODO" org-todo)