* nndiary.el: new version (0.2-b13).
authorDidier Verna <didier@xemacs.org>
Wed, 12 Sep 2001 14:17:16 +0000 (14:17 +0000)
committerDidier Verna <didier@xemacs.org>
Wed, 12 Sep 2001 14:17:16 +0000 (14:17 +0000)
lisp/ChangeLog
lisp/gnus-diary.el
lisp/nndiary.el

index 83eb191..754cac0 100644 (file)
@@ -1,3 +1,23 @@
+2001-09-12  Didier Verna  <didier@xemacs.org>
+
+       * nndiary.el: new version (0.2-b13).
+       * nndiary.el (nndiary-mail-sources): doc update.
+       * nndiary.el (nndiary-split-methods): ditto.
+       * nndiary.el (nndiary-request-accept-article-hooks): New.
+       * nndiary.el (nndiary-request-accept-article): use it, check
+       message validity.
+       * nndiary.el (nndiary-get-new-mail): changed default to nil.
+       * nndiary.el (nndiary-schedule): fix bug (misplaced
+       condition-case): it didn't return nil on error.
+       * gnus-diary.el: new version.
+       * gnus-diary.el (gnus-diary-summary-line-format): removed %I.
+       * gnus-diary.el (gnus-diary-header-value-history): New.
+       * gnus-diary.el (gnus-diary-narrow-to-headers): New.
+       * gnus-diary.el (gnus-diary-add-header): New.
+       * gnus-diary.el (gnus-diary-check-message): New.
+       * gnus-diary.el (message-mode-map): bind the above to `C-c D c'.
+       * gnus-diary.el (gnus-article-edit-mode-map): ditto.
+
 2001-09-10 TSUCHIYA Masatoshi <tsuchiya@namazu.org>
 
        * gnus-sum.el (gnus-select-newsgroup): Make
@@ -18,8 +38,8 @@
        (mm-attachment-override-types): Add
        application/{x-,}pkcs7-signature.
 
-       * gnus-srvr.el (gnus-server-mode-hook, gnus-server-exit-hook) 
-       (gnus-server-line-format, gnus-server-mode-line-format) 
+       * gnus-srvr.el (gnus-server-mode-hook, gnus-server-exit-hook)
+       (gnus-server-line-format, gnus-server-mode-line-format)
        (gnus-server-browse-in-group-buffer): Customize.
 
 2001-09-08 16:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
@@ -30,7 +50,7 @@
        (nnml-marks-modtime): Use gnus-make-hashtable.
 
        * nnfolder.el (nnfolder-marks-changed-p): Typo.
-       (nnfolder-request-expire-articles, nnfolder-save-marks) 
+       (nnfolder-request-expire-articles, nnfolder-save-marks)
        (nnfolder-open-marks): Typo.
        (nnfolder-save-marks, nnfolder-open-marks): Use gnus-sethash.
        (nnfolder-marks-changed-p): Use gnus-gethash.
 
        * nnml.el (nnml-filenames-are-evil): New variable.
        (nnml-article-to-file-alist): Rename to ...
-       (nnml-current-group-article-to-file-alist): ... this.  
+       (nnml-current-group-article-to-file-alist): ... this.
        Respect `nnml-filenames-are-evil'.
        (nnml-active-number): Update.
        (nnml-update-file-alist): Update.
        (nnml-request-article): Use nnheader-article-to-file-alist.
        (nnml-request-rename-group): Likewise.
-       
+
 2001-09-06  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * gnus-sum.el (gnus-summary-insert-line): Fix.
-       
+
 2001-09-06  Bj\e,Av\e(Brn Torkelsson  <torkel@acc.umu.se>
 
        * gnus-sum.el: Bind g-s-t-s to "W g".
        gets alist from nov database if available.
        (nnml-directory-articles): New function.
        (nnml-article-to-file-alist): New function.
-       
+
 2001-08-30  Andrew Innes  <andrewi@gnu.org>
 
        * mm-decode.el (mm-display-external): Use `name' as filename, if
        `filename' attribute is not present.
-       
+
 2001-08-30  Andrew Innes  <andrewi@gnu.org>
 
        * mail-source.el (mail-source-flash): New defcustom.
        (mail-source-new-mail-p): Ring visible bell if appropriate.
        (mail-source-start-idle-timer): Use unwind-protect to ensure idle
        timer is cleared even if mail check signals an error.
-       
+
 2001-08-29 10:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
        * gnus-sum.el (gnus-summary-move-article): Only update marks of
        * nnml.el (nnml-request-update-info): Fix message.
        (nnml-open-marks): Ditto.
 
-       * nnfolder.el (nnfolder-request-update-info): 
+       * nnfolder.el (nnfolder-request-update-info):
        (nnfolder-open-marks): Fix message.
 
 2001-08-25  Simon Josefsson  <jas@extundo.com>
 
 2001-08-24 16:05:38  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
-       * gnus-spec.el (gnus-compile): Don't compile gnus-version. 
+       * gnus-spec.el (gnus-compile): Don't compile gnus-version.
 
        * gnus-group.el (gnus-update-group-mark-positions): Bind
        gnus-group-update-hook to nil.
 
 2001-08-24 12:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
-       * gnus-sum.el (gnus-summary-insert-line) 
+       * gnus-sum.el (gnus-summary-insert-line)
        (gnus-summary-prepare-threads): gnus-tmp-lines should be a string.
        From Martin Kretzschmar <Martin.Kretzschmar@inf.tu-dresden.de>
 
        * gnus-sum.el (gnus-select-newsgroup): Clean up.
        (gnus-summary-limit-children): Use 'identity instead of `all'.
        (gnus-summary-limit-to-display-predicate): New command and
-       keystroke. 
+       keystroke.
 
 2001-08-23 10:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
 2001-08-22 00:06:52  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
        * gnus.el (gnus-visual-p): Define function before use of
-       function. 
+       function.
 
 2001-08-21 23:28:02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
 2001-08-20 01:34:03  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
        * gnus.el (gnus-expand-group-parameters): Don't alter the variable
-       list. 
+       list.
 
-       * gnus-sum.el (gnus-summary-move-article): Don't select article. 
+       * gnus-sum.el (gnus-summary-move-article): Don't select article.
 
 2001-08-20  Simon Josefsson  <jas@extundo.com>
 
 2001-08-20 01:34:03  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
        * gnus.el (gnus-expand-group-parameters): Return the parameter
-       list. 
+       list.
 
        * gnus-sum.el (gnus-summary-show-article): Doc fix.
        (gnus-summary-show-article): Guess at charset if required.
 
        * mm-view.el (mm-inline-text): Ignore vcard errors.
 
-       * gnus-art.el (gnus-ignored-headers): Added more junk headers. 
+       * gnus-art.el (gnus-ignored-headers): Added more junk headers.
 
        * gnus-score.el (gnus-all-score-files): Use append instead of
-       nconc. 
+       nconc.
 
        * gnus.el (gnus-splash-face): Doc fix.
 
        * mm-decode.el (mm-mailcap-command): Use
-       mm-path-name-rewrite-functions. 
+       mm-path-name-rewrite-functions.
        (mm-path-name-rewrite-functions): New variable.
 
        * gnus-spec.el (gnus-parse-complex-format): React to ?=.
        * gnus-ems.el (gnus-char-width): Moved here.
 
        * gnus-sum.el (gnus-select-newsgroup): Set
-       gnus-newsgroup-articles. 
+       gnus-newsgroup-articles.
        (gnus-unseen-mark): New variable.
        (gnus-newsgroup-unseen): Ditto.
        (gnus-newsgroup-seen): Ditto.
 
 2001-08-17 10:41:14  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
-       * gnus-agent.el (gnus-agent-fetch-group): Go online if offline. 
+       * gnus-agent.el (gnus-agent-fetch-group): Go online if offline.
        (gnus-agent-summary-fetch-group): New command and keystroke.
 
        * gnus-art.el (gnus-insert-mime-button): Tiny clean-up.
        (gnus-mime-display-security): Make it respect
-       gnus-unbuttonized-mime-type-p. 
+       gnus-unbuttonized-mime-type-p.
 
        * gnus-sum.el (gnus-articles-to-read): Comments.
        (gnus-article-marked-p): New function.
 2001-05-21 17:11:46  Lars Magne Ingebrigtsen  <larsi@gnus.org>
 
        * gnus-srvr.el (gnus-server-browse-in-group-buffer): Default to
-       nil. 
+       nil.
 
 2001-08-15  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
 2001-08-15  Simon Josefsson  <jas@extundo.com>
        From Pavel@Janik.cz (Pavel Jan\e,Bm\e(Bk)
 
-       * gnus-agent.el (gnus-agent-make-mode-line-string) 
+       * gnus-agent.el (gnus-agent-make-mode-line-string)
        (gnus-agent-toggle-plugged): Use new API.
 
 2001-08-14  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        Support `recent' mark indicating newly arrived messages (to
        separate from old but unread messages).
-       
+
        * nnimap.el (nnimap-retrieve-groups): Push dummy article into
        `nnmail-split-history' if recent is > 0.
        (nnimap-request-update-info-internal): Update `recent' marks.
 2001-08-12  Simon Josefsson  <jas@extundo.com>
        Suggested by Per Abrahamsen <abraham@dina.kvl.dk>
 
-       * gnus.el (gnus-summary-line-format, gnus-parameters): 
-       * gnus-gl.el (gnus-summary-grouplens-line-format): 
-       * gnus-salt.el (gnus-summary-pick-line-format): 
+       * gnus.el (gnus-summary-line-format, gnus-parameters):
+       * gnus-gl.el (gnus-summary-grouplens-line-format):
+       * gnus-salt.el (gnus-summary-pick-line-format):
        * gnus-spec.el (gnus-format-specs): %n is 23 chars.
 
 2001-08-11 09:40:00  Karl Kleinpaste  <karl@charcoal.com>
        Committed by Kai Gro\e,A_\e(Bjohann.
-       
+
        * gnus-score.el (gnus-score-string): Fix `match' regexp
        for `extra' header case.
 
        * gnus-ml.el (turn-on-gnus-mailing-list-mode): Use
        gnus-group-find-parameter. Suggested by Janne Rinta-Manty
        <rintaman@cs.Helsinki.FI>.
-       
+
        * mail-source.el (mail-source-movemail): The error buffer is
        modified, but nothing in it.
 
        gnus-summary-update-secondary-secondary-mark.
        * gnus-sum.el (gnus-summary-edit-article-done): Ditto.
        * gnus-sum.el (gnus-summary-reparent-thread): Ditto.
-       
+
 2001-08-07 16:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
        * gnus-sum.el (gnus-summary-make-menu-bar): Misc -> Gnus.
-       
+
        * gnus-group.el (gnus-group-make-menu-bar): Ditto.
 
        * mm-uu.el (mm-uu-dissect): Autoload. From Gerd M\e,Av\e(Bllmann
 
        * gnus-msg.el (gnus-post-method): Bind the value of
        `gnus-post-method' to the group parameter if it is defined.
-       
+
 2001-08-02  Simon Josefsson  <jas@extundo.com>
 
        * smime.el (smime-extra-arguments): Removed.
 
 2001-08-01  Gerd Moellmann  <gerd@gnu.org>
 
-       * mm-view.el (autoload): Don't autoload `diff-mode' if it's 
-       already fboundp.  Add INTERACTIVE arg to autoload form. 
+       * mm-view.el (autoload): Don't autoload `diff-mode' if it's
+       already fboundp.  Add INTERACTIVE arg to autoload form.
 
 2001-08-01 09:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
 2001-07-31  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * gnus-msg.el (gnus-post-method): Refer to `gnus-parameters'.
-       
+
 2001-07-31 17:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
        Originally from Pavel Jan\e,Bm\e(Bk <Pavel@Janik.cz>
-       
+
        * gnus-agent.el (gnus-agent-make-mode-line-string): New.
        (gnus-agent-toggle-plugged): Use it.
 
        * mail-source.el (top-level): Require message for message-directory.
        (mail-source-directory): Change default to message-directory.
 
-       * smime.el (smime-keys, smime-CA-directory, smime-CA-file) 
-       (smime-certificate-directory, smime-openssl-program) 
+       * smime.el (smime-keys, smime-CA-directory, smime-CA-file)
+       (smime-certificate-directory, smime-openssl-program)
        (smime-encrypt-cipher, smime-dns-server): Fix doc (leading "*").
        (smime-extra-arguments): New variable.
        (smime-dns-server): Fix customize group.
 
        Support S/MIME decryption.
 
-       * mm-decode.el (mm-inline-media-tests): 
+       * mm-decode.el (mm-inline-media-tests):
        (mm-inlined-types):
        (mm-automatic-display):
        (mm-attachment-override-types): Add application/{x-,}pkcs7-mime.
 
-       * mm-view.el (mm-pkcs7-signed-magic): 
+       * mm-view.el (mm-pkcs7-signed-magic):
        (mm-pkcs7-enveloped-magic): New variables.
        (mm-view-pkcs7-get-type): New function; identify PKCS#7 type.
        (mm-view-pkcs7): New function; mm viewer for PKCS#7 blobs.
 
        * gnus-sum.el (gnus-summary-prepare-threads): If
        gnus-sum-thread-tree-root is nil, use subject instead.
-       (gnus-sum-thread-tree-root, gnus-sum-thread-tree-single-indent) 
-       (gnus-sum-thread-tree-vertical, gnus-sum-thread-tree-indent) 
-       (gnus-sum-thread-tree-leaf-with-other) 
+       (gnus-sum-thread-tree-root, gnus-sum-thread-tree-single-indent)
+       (gnus-sum-thread-tree-vertical, gnus-sum-thread-tree-indent)
+       (gnus-sum-thread-tree-leaf-with-other)
        (gnus-sum-thread-tree-single-leaf): Documentation.
        (gnus-sum-thread-tree-single-indent): Allow nil.
 
        * gnus-art.el (gnus-mime-view-part-as-type): Don't copy cache.
 
 2001-07-25 12:54:00  Danny Siu <dsiu@adobe.com>
-       
+
        * gnus-sum.el (gnus-summary-prepare-threads): Shouldn't do tree
        display (%B) for threads if threading is off.
+
 2001-07-25 14:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
        From Henrik Enberg <henrik@enberg.org>
 
        * nnmail.el (nnmail-split-fancy-with-parent-ignore-groups): New
        variable.
        (nnmail-split-fancy-with-parent): Ignore certain groups.
-       
+
 2001-07-25 11:00:00  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
        * gnus-util.el (gnus-byte-compile): New.
index c329d0d..98ef4e0 100644 (file)
@@ -1,13 +1,13 @@
 ;;; gnus-diary.el --- Wrapper around the NNDiary Gnus backend
 
-;; Copyright (C) 1999 Didier Verna.
+;; Copyright (C) 1999-2001 Didier Verna.
 
-;; PRCS: $Id: gnus-diary.el 1.8 Tue, 04 Sep 2001 11:32:13 +0200 didier $
+;; PRCS: $Id: gnus-diary.el 1.17 Wed, 12 Sep 2001 15:54:36 +0200 didier $
 
 ;; Author:        Didier Verna <didier@xemacs.org>
 ;; Maintainer:    Didier Verna <didier@xemacs.org>
 ;; Created:       Tue Jul 20 10:42:55 1999 under XEmacs 21.2 (beta 18)
-;; Last Revision: Wed Aug  8 14:38:14 2001
+;; Last Revision: Wed Sep 12 12:31:09 2001
 ;; Keywords:      calendar mail news
 
 ;; This file is part of NNDiary.
 ;; ===========
 
 ;; Gnus-Diary is a wrapper around the NNDiary Gnus backend.  It is here to
-;; make your nndiary-user life easier in differnet ways.  So, you don't have
+;; make your nndiary-user life easier in different ways.  So, you don't have
 ;; to use it if you don't want to.  But, really, you should.
 
-;; Gnus-Diary offers the following improvements on top of the NNDiary backend:
+;; Gnus-Diary offers the following features on top of the NNDiary backend:
 
-;; - A nice summary line format:
-;;   Displaying diary messages in standard summary line format (usually
-;;   something like "<From Joe>: <Subject>") is pretty useless.  Most of the
-;;   time, you're the one who wrote the message, and you mostly want to see
-;;   the event's date.  Gnus-Diary offers you a nice summary line format which
-;;   will do this.  By default, a summary line will appear like this:
+;;  - A nice summary line format:
+;;    Displaying diary messages in standard summary line format (usually
+;;    something like "<From Joe>: <Subject>") is pretty useless.  Most of the
+;;    time, you're the one who wrote the message, and you mostly want to see
+;;    the event's date.  Gnus-Diary offers you a nice summary line format
+;;    which will do this.  By default, a summary line will appear like this:
 ;;
 ;;     <Event Date>: <Subject> <Remaining time>
 ;;
 ;;    headers will be inserted automatically (but not filled with proper
 ;;    values yet).
 
+;;  - An interactive mail-to-diary convertion function:
+;;    The function `gnus-diary-check-message' ensures that the current message
+;;    contains all the required diary headers, and prompts you for values /
+;;    correction if needed.  This function is hooked in the nndiary backend so
+;;    that moving an article to an nndiary group will trigger it
+;;    automatically.  It is also bound to `C-c D c' in message-mode and
+;;    article-edit-mode in order to ease the process of converting a usual
+;;    mail to a diary one.  This function takes a prefix argument which will
+;;    force prompting of all diary headers, regardless of their
+;;    presence/validity.  That way, you can very easily reschedule a diary
+;;    message for instance.
+
 
 ;; Usage:
 ;; =====
 ;; Bugs / Todo:
 ;; ===========
 
-;; * Provide `gnus-group-diary-mail' and `gnus-group-post-diary-news' (or
-;;   something like that), that would do just like `gnus-group-mail' and
-;;   `gnus-group-post-news', but also prompt for diary header values with
-;;   completion etc.
-;; * Maybe not actually: we could just have a function that converts *any*
-;;   message to a diary one, by prompting the schedule. You could then forward
-;;   a message and make it a diary one etc.
 
 ;;; Code:
 
 (require 'nndiary)
+(require 'message)
+(require 'gnus-art)
 
 (defgroup gnus-diary nil
   "Utilities on top of the nndiary backend for Gnus.")
 
-(defcustom gnus-diary-summary-line-format "%U%R%z%I %uD: %(%s%) (%ud)\n"
+(defcustom gnus-diary-summary-line-format "%U%R%z %uD: %(%s%) (%ud)\n"
   "*Summary line format for nndiary groups."
   :type 'string
   :group 'gnus-diary
@@ -274,6 +281,8 @@ Optional prefix (or REVERSE argument) means sort in reverse order."
                                     'nndiary)]
                                "Sort by number")))
 
+
+
 ;; Group parameters autosetting =============================================
 
 (defun gnus-diary-update-group-parameters (group)
@@ -325,11 +334,128 @@ Optional prefix (or REVERSE argument) means sort in reverse order."
 (add-hook 'gnus-subscribe-newsgroup-hooks
          'gnus-diary-maybe-update-group-parameters)
 
+
+;; Diary Message Checking ===================================================
+
+(if (fboundp 'kill-entire-line)
+    (defun gnus-diary-kill-entire-line ()
+      (kill-entire-line))
+  (defun gnus-diary-kill-entire-line ()
+    (beginning-of-line)
+    (let ((kill-whole-line t))
+      (kill-line)))
+  )
+
+(defvar gnus-diary-header-value-history nil
+  ;; History variable for header value prompting
+  )
+
+(defun gnus-diary-narrow-to-headers ()
+  "Narrow the current buffer to the header part.
+Point is left at the beginning of the region.
+The buffer is assumed to contain a message, but the format is unknown."
+  (cond ((eq major-mode 'message-mode)
+        (message-narrow-to-headers))
+       (t
+        (goto-char (point-min))
+        (when (search-forward "\n\n" nil t)
+          (narrow-to-region (point-min) (- (point) 1))
+          (goto-char (point-min))))
+       ))
+
+(defun gnus-diary-add-header (str)
+  "Add a header to the current buffer.
+The buffer is assumed to contain a message, but the format is unknown."
+  (cond ((eq major-mode 'message-mode)
+        (message-add-header str))
+       (t
+        (save-restriction
+          (gnus-diary-narrow-to-headers)
+          (goto-char (point-max))
+          (if (string-match "\n$" str)
+              (insert str)
+            (insert str ?\n))))
+       ))
+
+(defun gnus-diary-check-message (arg)
+  "Ensure that the current message is a valid for NNDiary.
+This function checks that all NNDiary required headers are present and
+valid, and prompts for values / correction otherwise.
+
+If ARG (or prefix) is non-nil, force prompting for all fields."
+  (interactive "P")
+  (save-excursion
+    (mapcar
+     (lambda (head)
+       (let ((header (concat "X-Diary-" (car head)))
+            (ask arg)
+            value invalid)
+        ;; First, try to find the header, and checks for validity:
+        (save-restriction
+          (gnus-diary-narrow-to-headers)
+          (when (re-search-forward (concat "^" header ":") nil t)
+            (unless (eq (char-after) ? )
+              (insert " "))
+            (setq value (buffer-substring (point) (point-at-eol)))
+            (and (string-match "[ \t]*\\([^ \t]+\\)[ \t]*" value)
+                 (setq value (match-string 1 value)))
+            (condition-case ()
+                (nndiary-parse-schedule-value value
+                                              (nth 1 head) (nth 2 head))
+              (t
+               (setq invalid t)))
+            ;; #### NOTE: this (along with the `gnus-diary-add-header'
+            ;; function) could be rewritten in a better way, in particular
+            ;; not to blindly remove an already present header and reinsert
+            ;; it somewhere else afterwards.
+            (when (or ask invalid)
+              (gnus-diary-kill-entire-line))
+            ))
+        ;; Now, loop until a valid value is provided:
+        (while (or ask (not value) invalid)
+          (let ((prompt (concat (and invalid
+                                     (prog1 "(current value invalid) "
+                                       (beep)))
+                                header
+                                (and (not value) " (defaults to `*')")
+                                ": ")))
+            (setq value
+                  (if (listp (nth 1 head))
+                      (completing-read prompt (cons '("*" nil) (nth 1 head))
+                                       nil t value
+                                       gnus-diary-header-value-history "*")
+                    (read-string prompt value
+                                 gnus-diary-header-value-history "*"))))
+          (setq ask nil)
+          (setq invalid nil)
+          (condition-case ()
+              (nndiary-parse-schedule-value value
+                                            (nth 1 head) (nth 2 head))
+            (t
+             (setq invalid t))))
+        (gnus-diary-add-header (concat header ": " value))
+        ))
+     nndiary-headers)
+    ))
+
+(add-hook 'nndiary-request-accept-article-hooks
+         (lambda () (gnus-diary-check-message nil)))
+
+(define-key message-mode-map "\C-cDc" 'gnus-diary-check-message)
+(define-key gnus-article-edit-mode-map "\C-cDc" 'gnus-diary-check-message)
+
+
+;; The end ==================================================================
+
 (defun gnus-diary-version ()
   "Current Diary backend version."
   (interactive)
   (message "NNDiary version %s" nndiary-version))
 
+(define-key message-mode-map "\C-cDv" 'gnus-diary-version)
+(define-key gnus-article-edit-mode-map "\C-cDv" 'gnus-diary-version)
+
+
 (provide 'gnus-diary)
 
 ;;; gnus-diary.el ends here
index ecaf5ea..f94bfe3 100644 (file)
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1999-2001 Didier Verna.
 
-;; PRCS: $Id: nndiary.el 1.22 Tue, 04 Sep 2001 11:32:13 +0200 didier $
+;; PRCS: $Id: nndiary.el 1.26 Wed, 12 Sep 2001 15:23:27 +0200 didier $
 
 ;; Author:        Didier Verna <didier@xemacs.org>
 ;; Maintainer:    Didier Verna <didier@xemacs.org>
 ;; Usage:
 ;; =====
 
-;;  1/ Diary messages contain several `X-Diary-*' special headers.  You *must*
-;;     arrange that these messages be split in a private folder *before* Gnus
-;;     treat them.  You need this because Gnus is not able yet to manage
-;;     multiple backends for mail retrieval.  Getting them from a separate
-;;     source will compensate this misfeature to some extent, as we will see.
-;;     As an example, here's my procmailrc entry to store diary files in
-;;     ~/.nndiary (the default nndiary mail source file):
-;;
-;;      :0 HD :
-;;      * ^X-Diary
-;;      .nndiary
+;;  1/ NNDiary has two modes of operation: traditional (the default) and
+;;     autonomous.
+;;     a/ In traditional mode, NNDiary does not get new mail by itself.  You
+;;        have to move mails from your primary mail backend to nndiary
+;;        groups.
+;;     b/ In autonomous mode, NNDiary retrieves its own mail and handles it
+;;        independantly of your primary mail backend.  To use NNDiary in
+;;        autonomous mode, you have several things to do:
+;;           i/ Put (setq nndiary-get-new-mail t) in your gnusrc file.
+;;          ii/ Diary messages contain several `X-Diary-*' special headers.
+;;              You *must* arrange that these messages be split in a private
+;;              folder *before* Gnus treat them.  You need this because Gnus
+;;              is not able yet to manage multiple backends for mail
+;;              retrieval.  Getting them from a separate source will
+;;              compensate this misfeature to some extent, as we will see.
+;;              As an example, here's my procmailrc entry to store diary files
+;;              in ~/.nndiary (the default nndiary mail source file):
 ;;
+;;              :0 HD :
+;;              * ^X-Diary
+;;              .nndiary
+;;         iii/ Customize the variables `nndiary-mail-sources' and
+;;              `nndiary-split-methods'.  These are replacements for the usual
+;;              mail sources and split methods which, and will be used in
+;;              autonomous mode.  `nndiary-mail-sources' defaults to
+;;              '(file :path "~/.nndiary").
 ;;  2/ Install nndiary somewhere Emacs / Gnus can find it.  Normally, you
 ;;     *don't* have to '(require 'nndiary) anywhere.  Gnus will do so when
 ;;     appropriate as long as nndiary is somewhere in the load path.
-;;  3/ Now, customize nndiary: type `M-x customize-group', and then `nndiary'
-;;     at the prompt (note that if you have not restarted Emacs yet, you'll
-;;     have to the load the library by hand before being able to customize it).
-;;     In particular, you should customize the following options:
-;;     - `nndiary-mail-sources', which overrides the normal `mail-sources'
-;;       value for diary messages retrieving.  It defaults to
-;;       '(file :path "~/.nndiary").
-;;     - `nndiary-split-methods', which overrides the normal
-;;       `nnmail-split-methods' value for diary messages splitting.  You can
-;;       have all the diary groups you want (for example, I have a birthdays
-;;       group, and stuff like that).
-;;     - `nndiary-reminders', the list of times when you want to be reminded
-;;       of your appointements (e.g. 3 weeks before, then 2 days before, then
-;;       1 hour before and that's it).
+;;  3/ Now, customize the rest of nndiary.  In particular, you should
+;;     customize `nndiary-reminders', the list of times when you want to be
+;;     reminded of your appointements (e.g. 3 weeks before, then 2 days
+;;     before, then 1 hour before and that's it).
 ;;  4/ You *must* use the group timestamp feature of Gnus.  This adds a
 ;;     timestamp to each groups' parameters (please refer to the Gnus
 ;;     documentation ("Group Timestamp" info node) to see how it's done.
 ;; * Respooling doesn't work because contrary to the request-scan function,
 ;;   Gnus won't allow me to override the split methods when calling the
 ;;   respooling backend functions.
-;; * The time zone mechanism is subject to change.
+;; * There's a bug in the time zone mechanism with variable TZ locations.
 ;; * We could allow a keyword like `ask' in X-Diary-* headers, that would mean
-;;   "ask for value upon reception of the message". Suggested by Jody Klymak.
+;;   "ask for value upon reception of the message".
 ;; * We could add an optional header X-Diary-Reminders to specify a special
 ;;   reminders value for this message. Suggested by Jody Klymak.
-;; * Modify the request-accept-article function to make it prompt for diary
-;;   headers if they're missing.
+;; * We should check messages validity in other circumstances than just
+;;   moving an article from sonwhere else (request-accept). For instance, when
+;;   editing / saving and so on.
+
 
 ;; Remarks:
 ;; =======
   `((file :path ,(expand-file-name "~/.nndiary")))
   "*NNDiary specific mail sources.
 This variable is used by nndiary in place of the standard `mail-sources'
-variable.  These sources must contain diary messages ONLY."
+variable when `nndiary-get-new-mail' is set to non-nil.  These sources
+must contain diary messages ONLY."
   :group 'nndiary
   :group 'mail-source
   :type 'sexp)
@@ -232,7 +239,8 @@ variable.  These sources must contain diary messages ONLY."
 (defcustom nndiary-split-methods '(("diary" ""))
   "*NNDiary specific split methods.
 This variable is used by nndiary in place of the standard
-`nnmail-split-methods' variable."
+`nnmail-split-methods' variable when `nndiary-get-new-mail' is set to
+non-nil."
   :group 'nndiary
   :group 'nnmail-split
   :type '(choice (repeat :tag "Alist" (group (string :tag "Name") regexp))
@@ -304,6 +312,13 @@ The hooks will be called with the full group name as argument."
   :group 'nndiary
   :type 'hook)
 
+(defcustom nndiary-request-accept-article-hooks nil
+  "*Hooks to run before accepting an article.
+Executed near the beginning of `nndiary-request-accept-article'.
+The hooks will be called with the article in the current buffer."
+  :group 'nndiary
+  :type 'hook)
+
 (defcustom nndiary-check-directory-twice t
   "*If t, check directories twice to avoid NFS failures."
   :group 'nndiary
@@ -327,10 +342,11 @@ The hooks will be called with the full group name as argument."
     (expand-file-name "newsgroups" nndiary-directory)
   "Newsgroups description file for the nndiary backend.")
 
-(defvoo nndiary-get-new-mail t
+(defvoo nndiary-get-new-mail nil
   "Whether nndiary gets new mail and split it.
-Contrary to traditional mail backends, this variable should always be
-non-nil because nndiary uses its own mail-sources and split-methods.")
+Contrary to traditional mail backends, this variable can be set to t
+even if your primary mail backend also retreives mail. In such a case,
+NDiary uses its own mail-sources and split-methods.")
 
 (defvoo nndiary-nov-is-evil nil
   "If non-nil, Gnus will never use nov databases for nndiary groups.
@@ -352,7 +368,7 @@ all.  This may very well take some time.")
 ;; $Format: "(defconst nndiary-prcs-major-version \"$ProjectMajorVersion$\")"$
 (defconst nndiary-prcs-major-version "branch-0-2")
 ;; $Format: "(defconst nndiary-prcs-minor-version \"$ProjectMinorVersion$\")"$
-(defconst nndiary-prcs-minor-version "1")
+(defconst nndiary-prcs-minor-version "13")
 (defconst nndiary-version
   (let ((level nndiary-prcs-minor-version)
        major minor status)
@@ -745,31 +761,34 @@ all.  This may very well take some time.")
 (deffoo nndiary-request-accept-article (group &optional server last)
   (nndiary-possibly-change-directory group server)
   (nnmail-check-syntax)
-  (let (result)
-    (when nnmail-cache-accepted-message-ids
-      (nnmail-cache-insert (nnmail-fetch-field "message-id")))
-    (if (stringp group)
+  (run-hooks 'nndiary-request-accept-article-hooks)
+  (when (nndiary-schedule)
+    (let (result)
+      (when nnmail-cache-accepted-message-ids
+       (nnmail-cache-insert (nnmail-fetch-field "message-id")))
+      (if (stringp group)
+         (and
+          (nnmail-activate 'nndiary)
+          (setq result
+                (car (nndiary-save-mail
+                      (list (cons group (nndiary-active-number group))))))
+          (progn
+            (nnmail-save-active nndiary-group-alist nndiary-active-file)
+            (and last (nndiary-save-nov))))
        (and
         (nnmail-activate 'nndiary)
-        (setq result
-              (car (nndiary-save-mail
-                    (list (cons group (nndiary-active-number group))))))
-        (progn
+        (if (and (not (setq result
+                            (nnmail-article-group 'nndiary-active-number)))
+                 (yes-or-no-p "Moved to `junk' group; delete article? "))
+            (setq result 'junk)
+          (setq result (car (nndiary-save-mail result))))
+        (when last
           (nnmail-save-active nndiary-group-alist nndiary-active-file)
-          (and last (nndiary-save-nov))))
-      (and
-       (nnmail-activate 'nndiary)
-       (if (and (not (setq result
-                          (nnmail-article-group 'nndiary-active-number)))
-               (yes-or-no-p "Moved to `junk' group; delete article? "))
-          (setq result 'junk)
-        (setq result (car (nndiary-save-mail result))))
-       (when last
-        (nnmail-save-active nndiary-group-alist nndiary-active-file)
-        (when nnmail-cache-accepted-message-ids
-          (nnmail-cache-close))
-        (nndiary-save-nov))))
-    result))
+          (when nnmail-cache-accepted-message-ids
+            (nnmail-cache-close))
+          (nndiary-save-nov))))
+      result))
+  )
 
 (deffoo nndiary-request-post (&optional server)
   (nnmail-do-request-post 'nndiary-request-accept-article server))
@@ -1285,7 +1304,7 @@ all.  This may very well take some time.")
       val)))
 
 (defun nndiary-parse-schedule-value (str min-or-values max)
-  ;; Parse the schedule string STR.
+  ;; Parse the schedule string STR, or signal an error.
   ;; Signals are caught by `nndary-schedule'.
   (if (string-match "[ \t]*\\*[ \t]*" str)
       ;; unspecifyed
@@ -1339,15 +1358,18 @@ all.  This may very well take some time.")
     ))
 
 (defsubst nndiary-schedule ()
-  (mapcar
-   (lambda (elt)
-     (condition-case arg
-        (nndiary-parse-schedule (nth 0 elt) (nth 1 elt) (nth 2 elt))
-       (t
-       (nnheader-report 'nndiary "X-Diary-%s header parse error: %s."
-                        (car elt) (cdr arg))
-       nil)))
-   nndiary-headers))
+  (let (head)
+    (condition-case arg
+       (mapcar
+        (lambda (elt)
+          (setq head (nth 0 elt))
+          (nndiary-parse-schedule (nth 0 elt) (nth 1 elt) (nth 2 elt)))
+        nndiary-headers)
+      (t
+       (nnheader-report 'nndiary "X-Diary-%s header parse error: %s."
+                       head (cdr arg))
+       nil))
+    ))
 
 (defun nndiary-max (spec)
   ;; Returns the max of specification SPEC, or nil for permanent schedules.