*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 21:32:25 +0000 (21:32 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 21:32:25 +0000 (21:32 +0000)
40 files changed:
GNUS-NEWS
lisp/ChangeLog
lisp/article.el
lisp/dgnushack.el
lisp/gnus-art.el
lisp/gnus-async.el
lisp/gnus-cache.el
lisp/gnus-dup.el
lisp/gnus-ems.el
lisp/gnus-gl.el
lisp/gnus-group.el
lisp/gnus-int.el
lisp/gnus-kill.el
lisp/gnus-msg.el
lisp/gnus-nocem.el
lisp/gnus-score.el
lisp/gnus-spec.el
lisp/gnus-start.el
lisp/gnus-sum.el
lisp/gnus-topic.el
lisp/gnus-util.el
lisp/gnus.el
lisp/message.el
lisp/nnbabyl.el
lisp/nndb.el
lisp/nndejagnus.el
lisp/nneething.el
lisp/nnfolder.el
lisp/nnkiboze.el
lisp/nnmail.el
lisp/nnmbox.el
lisp/nnmh.el
lisp/nnml.el
lisp/nnsoup.el
lisp/nntp.el
lisp/nnweb.el [new file with mode: 0644]
lisp/pop3.el
lisp/smiley.el
texi/ChangeLog
texi/gnus.texi

index 24dc3de..faeb0b8 100644 (file)
--- a/GNUS-NEWS
+++ b/GNUS-NEWS
@@ -70,6 +70,10 @@ the native server.
 even when the NNTP server doesn't allow posting.
 *** Process mark sets can be pushed and popped.
 
+*** A new mail-to-news backend makes it possible to post
+even when the NNTP server doesn't allow posting.
+*** Process mark sets can be pushed and popped.
+
 *** A new mail-to-news backend makes it possible to post
 even when the NNTP server doesn't allow posting.
 
index 4787250..ff4a4b4 100644 (file)
@@ -1,3 +1,178 @@
+Sun Aug 25 00:16:44 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * gnus-util.el (gnus-prin1): New function.
+       (gnus-prin1-to-string): New function.
+
+       * gnus-sum.el (gnus-summary-refer-parent-article): Bugout.
+
+       * nndb.el (nndb-request-accept-article): Use new nntp functions.
+
+       * pop3.el: Make MD5 defined when compiling.
+
+       * article.el (article-strip-blank-lines): Called Gnus functions.
+
+       * nnweb.el (nnweb-init): Create a better buffer name.
+       (nnweb-altavista-search): Wasn't defined.
+       (nnweb-reference-search): Use advanced search.
+
+       * nnfolder.el (nnfolder-request-accept-article): Wrong params to
+       `save-mail'. 
+       * nnbabyl.el (nnbabyl-request-accept-article): Ditto.
+       * nnmbox.el (nnmbox-request-accept-article): Ditto.
+       * nnmh.el (nnmh-request-accept-article): Ditto.
+       * nnml.el (nnml-request-accept-article): Ditto.
+
+Sat Aug 24 23:53:32 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * nnmail.el (nnmail-get-new-mail): Tried calling nonexistsing
+       functions. 
+
+Sat Aug 24 23:30:07 1996  Lars Magne Ingebrigtsen  <larsi@nipling.ifi.uio.no>
+
+       * gnus-group.el (gnus-group-enter-directory): Temporarily bound
+       `nneething-read-only'. 
+
+Fri Aug 23 23:22:16 1996  Katsumi Yamaoka  <yamaoka@ga.sony.co.jp>
+
+       * gnus-ems.el (gnus-ems-redefine): Set
+       `gnus-summary-display-table' to nil.
+
+Fri Aug 23 22:55:09 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-art.el (gnus-summary-save-in-file): Didn't check before
+       creating dir.
+       (gnus-summary-save-in-rmail): Ditto.
+       (gnus-summary-save-body-in-file): Ditto.
+
+       * message.el (message-check-news-syntax): Faulty Newsgroups
+       regexp. 
+
+Thu Aug 22 20:47:48 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * nnmail.el (nnmail-split-hook): New variable.
+
+       * nnmh.el (nnmh-update-gnus-unreads): cl-nged.
+       (nnmh-active-number): Find the largest article number.
+
+Thu Aug 22 20:39:10 1996  Sam Falkner  <sam@steel.central.sun.com>
+
+       * nnmh.el (nnmh-update-gnus-unreads): Check all articles.
+
+Thu Aug 22 16:49:35 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-kill.el (gnus-execute): Ignored read articles.
+
+       * gnus-sum.el (gnus-summary-execute-command): Give a form, not a
+       function. 
+
+       * gnus-kill.el (gnus-execute-1): Evaled functions instead of
+       calling them.
+
+       * nnmail.el (nnmail-move-inbox): Allow continuation after error. 
+
+       * gnus-score.el (gnus-adaptive-word-syntax-table): New variable. 
+       (gnus-score-adaptive): Use it.
+
+       * nnbabyl.el (nnbabyl-request-scan): Change group.
+
+       * nnmbox.el (nnmbox-request-scan): Change group.
+
+       * gnus-score.el (gnus-ignored-adaptive-words): Renamed.
+       (gnus-ignored-adaptive-words): New variable.
+       (gnus-score-adaptive): Use it.
+       (gnus-score-adaptive): Bugged out on undefined symbols.
+       (gnus-summary-score-entry): Accept numerical DATE.
+       (gnus-score-adaptive): Pos in wrong buf.
+       (gnus-score-string): Didn't accept word matches.
+       (gnus-enter-score-words-into-hashtb): Wrong sequence.
+       (gnus-score-string): Word matches inflooped.
+
+Wed Aug 21 15:06:47 1996    <Wesley.Hardaker@sphys.unil.ch>
+
+       * smiley.el (smiley-buffer): Added some additinal extent parameters.
+       (smiley-toggle-extent): rewrote to use above.
+
+Mon Aug 19 20:19:59 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-spec.el (gnus-tilde-cut-form): Cut off wrong part.
+
+Mon Aug 19 20:09:44 1996  Samuel Tardieu  <sam@inf.enst.fr>
+
+       * gnus-cache.el (gnus-cache-write-active): Would try to create
+       existing directory.
+
+Mon Aug 19 00:12:11 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * article.el (article-strip-multiple-blank-lines): New command and
+       keystroke.
+       (article-strip-blank-lines): New command and keystroke.
+
+       * nnmail.el (nnmail-move-inbox): Set file permissions on the
+       Incoming files.
+
+       * gnus-group.el (gnus-group-fetch-faq): Go through the FAQ dirs
+       until we manage to open one.
+
+       * nntp.el (nntp-send-authinfo-function): New variable.
+       (nntp-wait-for): Handle authinfo requests better.
+
+       * gnus-sum.el (gnus-summary-article-posted-p): New command and
+       keystroke. 
+
+       * gnus-topic.el (gnus-topic-display-empty-topics): New variable.
+
+       * gnus-msg.el (gnus-setup-message): Make `gnus-newsgroup-name'
+       local to the message buffers.
+
+       * gnus-int.el (gnus-remove-denial): New function.
+
+       * gnus-sum.el (gnus-summary-refer-parent-article): Allow negative
+       prefixes. 
+       (gnus-summary-refer-parent-article): Allow skipping past canceled
+       articles. 
+
+       * gnus-util.el (gnus-parent-id): Take an optional N ancestor
+       param. 
+
+       * gnus-async.el (gnus-async-prefetch-article): Don't clobber async
+       fetches already in progress.
+
+       * nnmail.el (nnmail-check-duplication): Allow /dev/null mail
+       filing. 
+
+       * gnus-sum.el (gnus-summary-catchup): Didn't do suppression.
+       (gnus-summary-limit-children): Never hide ticked articles.
+       (gnus-highlight-selected-summary): Selected face spans the entire
+       %(-%) area.
+
+Sun Aug 18 22:05:00 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-group.el (gnus-group-restart): Better prompt.
+
+       * gnus-async.el (gnus-async-prefetch-article): Don't try to fetch
+       old-fetched articles.
+
+Sun Aug 18 22:02:17 1996  Raja R. Harinath  <harinath@cs.umn.edu>
+
+       * gnus-gl.el (gnus-grouplens-mode): Make hooks local.
+
+Sun Aug 18 16:53:19 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-group.el (gnus-group-get-new-news): Don't move point.
+
+       * nnweb.el (nndejagnus): Renamed from nndejagnus.
+       (nnweb-remove-markup): New function.
+
+Sun Aug 18 14:53:55 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * gnus.el: Red Gnus v0.13 is released.
+
+Tue Aug 20 17:30:00 1996    <Wesley.Hardaker@sphys.unil.ch>
+
+       * smiley.el (smiley-map): New keymap for smiley's.
+       (smiley-toggle-extent): New function to toggle smiley invisiblity.
+       (smiley-buffer): Use them.
+
 Sun Aug 18 12:46:12 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
 
        * nnoo.el (nnoo-define-skeleton-1): Defined too many functions.
index a429e69..9635649 100644 (file)
@@ -539,6 +539,27 @@ always hide."
        (while (looking-at "[ \t]$")
          (gnus-delete-line))))))
 
+(defun article-strip-multiple-blank-lines ()
+  "Replace consequtive blank lines with one empty line."
+  (interactive)
+  (save-excursion
+    (let (buffer-read-only)
+      ;; First make all blank lines empty.
+      (goto-char (point-min))
+      (while (re-search-forward "^[ \t]+$" nil t)
+       (replace-match "" nil t))
+      ;; Then replace multiple empty lines with a single empty line.
+      (goto-char (point-min))
+      (while (re-search-forward "\n\n+" nil t)
+       (replace-match "\n" nil t)))))
+
+(defun article-strip-blank-lines ()
+  "Strip leading, trailing and multiple blank lines."
+  (interactive)
+  (article-strip-leading-blank-lines)
+  (article-remove-trailing-blank-lines)
+  (article-strip-multiple-blank-lines))
+
 (defvar mime::preview/content-list)
 (defvar mime::preview-content-info/point-min)
 (defun article-narrow-to-signature ()
index e82914f..001af75 100644 (file)
@@ -42,6 +42,9 @@
   (let ((files (directory-files "." nil ".el$"))
        (xemacs (string-match "XEmacs" emacs-version))
        byte-compile-warnings file)
+    (condition-case ()
+       (require 'w3-forms)
+      (error (setq files (delete "nnweb.el" files))))
     (while files
       (setq file (car files)
            files (cdr files))
index 089b7be..6cfcac9 100644 (file)
@@ -179,14 +179,16 @@ If you want to run a special decoding program like nkf, use this hook.")
      article-treat-overstrike
      (article-fill . gnus-article-word-wrap)
      article-remove-cr
-     article-remove-trailing-blank-lines
      article-display-x-face
      article-de-quoted-unreadable
      article-mime-decode-quoted-printable
      article-hide-pgp
      article-hide-pem
      article-hide-signature
+     article-remove-trailing-blank-lines
      article-strip-leading-blank-lines
+     article-strip-multiple-blank-lines
+     article-strip-blank-lines
      article-date-local
      article-date-original
      article-date-lapsed
@@ -297,7 +299,8 @@ Directory to save to is default to `gnus-article-save-directory'."
                   gnus-current-headers gnus-newsgroup-last-rmail)))
     (setq filename (gnus-read-save-file-name
                    "Save %s in rmail file:" default-name filename))
-    (make-directory (file-name-directory filename) t)
+    (unless (file-exists-p (file-name-directory filename))
+      (make-directory (file-name-directory filename) t))
     (gnus-eval-in-buffer-window gnus-original-article-buffer
       (save-excursion
        (save-restriction
@@ -321,7 +324,8 @@ Directory to save to is default to `gnus-article-save-directory'."
          (expand-file-name filename
                            (and default-name
                                 (file-name-directory default-name))))
-    (make-directory (file-name-directory filename) t)
+    (unless (file-exists-p (file-name-directory filename))
+      (make-directory (file-name-directory filename) t))
     (gnus-eval-in-buffer-window gnus-original-article-buffer
       (save-excursion
        (save-restriction
@@ -344,7 +348,8 @@ Directory to save to is default to `gnus-article-save-directory'."
                   gnus-current-headers gnus-newsgroup-last-file)))
     (setq filename (gnus-read-save-file-name
                    "Save %s in file:" default-name filename))
-    (make-directory (file-name-directory filename) t)
+    (unless (file-exists-p (file-name-directory filename))
+      (make-directory (file-name-directory filename) t))
     (gnus-eval-in-buffer-window gnus-original-article-buffer
       (save-excursion
        (save-restriction
@@ -364,7 +369,8 @@ The directory to save in defaults to `gnus-article-save-directory'."
                   gnus-current-headers gnus-newsgroup-last-file)))
     (setq filename (gnus-read-save-file-name
                    "Save %s body in file:" default-name filename))
-    (make-directory (file-name-directory filename) t)
+    (unless (file-exists-p (file-name-directory filename))
+      (make-directory (file-name-directory filename) t))
     (gnus-eval-in-buffer-window gnus-original-article-buffer
       (save-excursion
        (save-restriction
index 3b8b1b7..f3d059e 100644 (file)
@@ -93,50 +93,58 @@ from that group.")
 
 (defun gnus-async-prefetch-article (group article summary &optional next)
   "Possibly prefetch several articles starting with ARTICLE."
-  (when (and (gnus-group-asynchronous-p group)
-            (gnus-buffer-live-p summary)
-            (or (not next)
-                gnus-async-fetch-list))
-    (unwind-protect
-       (progn
-         (gnus-async-get-semaphore 'gnus-async-article-semaphore)
-         (unless next
-           ;; Nix out any outstanding requests.
-           (setq gnus-async-fetch-list nil)
-           ;; Fill in the new list.
-           (let ((n gnus-use-article-prefetch)
-                 (data (gnus-data-find-list article))
-                 d)
-             (while (and (setq d (pop data))
-                         (if (numberp n) 
-                             (natnump (decf n))
-                           n))
-               (unless (gnus-async-prefetched-article-entry
-                        group (setq article (gnus-data-number d)))
-                 ;; Not already fetched -- so we add it to the list.
-                 (push article gnus-async-fetch-list)))
-             (setq gnus-async-fetch-list (nreverse gnus-async-fetch-list))))
-
-         (setq article (pop gnus-async-fetch-list)))
+  (when next
+    (gnus-async-get-semaphore 'gnus-async-article-semaphore)
+    (pop gnus-async-fetch-list)
+    (gnus-async-release-semaphore 'gnus-async-article-semaphore))
+  (let ((do-fetch next))
+    (when (and (gnus-group-asynchronous-p group)
+              (gnus-buffer-live-p summary)
+              (or (not next)
+                  gnus-async-fetch-list))
+      (unwind-protect
+         (progn
+           (gnus-async-get-semaphore 'gnus-async-article-semaphore)
+           (unless next
+             (setq do-fetch (not gnus-async-fetch-list))
+             ;; Nix out any outstanding requests.
+             (setq gnus-async-fetch-list nil)
+             ;; Fill in the new list.
+             (let ((n gnus-use-article-prefetch)
+                   (data (gnus-data-find-list article))
+                   d)
+               (while (and (setq d (pop data))
+                           (if (numberp n) 
+                               (natnump (decf n))
+                             n))
+                 (unless (or (gnus-async-prefetched-article-entry
+                              group (setq article (gnus-data-number d)))
+                             (not (natnump article)))
+                   ;; Not already fetched -- so we add it to the list.
+                   (push article gnus-async-fetch-list)))
+               (setq gnus-async-fetch-list (nreverse gnus-async-fetch-list))))
+
+           (when do-fetch
+             (setq article (pop gnus-async-fetch-list))))
        
-      (gnus-async-release-semaphore 'gnus-async-article-semaphore))
+       (gnus-async-release-semaphore 'gnus-async-article-semaphore))
     
-    (when article
-      ;; We want to fetch some more articles.
-      (save-excursion
-       (set-buffer summary)
-       (let (mark)
-         (gnus-async-set-buffer)
-         (goto-char (point-max))
-         (setq mark (point-marker))
-         (let ((nnheader-callback-function
-                (gnus-make-async-article-function 
-                 group article mark summary next))
-               (nntp-server-buffer (get-buffer
-                                    gnus-async-prefetch-article-buffer)))
-           (gnus-message 7 "Prefetching article %d in group %s"
-                         article group)
-           (gnus-request-article article group)))))))
+      (when article
+       ;; We want to fetch some more articles.
+       (save-excursion
+         (set-buffer summary)
+         (let (mark)
+           (gnus-async-set-buffer)
+           (goto-char (point-max))
+           (setq mark (point-marker))
+           (let ((nnheader-callback-function
+                  (gnus-make-async-article-function 
+                   group article mark summary next))
+                 (nntp-server-buffer (get-buffer
+                                      gnus-async-prefetch-article-buffer)))
+             (gnus-message 7 "Prefetching article %d in group %s"
+                           article group)
+             (gnus-request-article article group))))))))
 
 (defun gnus-make-async-article-function (group article mark summary next)
   "Return a callback function."
index cda82cc..6ef161c 100644 (file)
@@ -144,8 +144,8 @@ variable to \"^nnml\".")
                 (not (file-exists-p (setq file (gnus-cache-file-name
                                                 group number)))))
        ;; Possibly create the cache directory.
-       (or (file-exists-p (setq dir (file-name-directory file)))
-           (make-directory dir t))
+       (unless (file-exists-p (setq dir (file-name-directory file)))
+         (make-directory dir t))
        ;; Save the article in the cache.
        (if (file-exists-p file)
            t                           ; The article already is saved.
@@ -554,7 +554,8 @@ Returns the list of articles removed."
                           (symbol-name sym) (cdr (symbol-value sym))
                           (car (symbol-value sym))))))
        gnus-cache-active-hashtb)
-      (make-directory (file-name-directory gnus-cache-active-file) t)
+      (unless (file-exists-p (file-name-directory gnus-cache-active-file))
+       (make-directory (file-name-directory gnus-cache-active-file) t))
       (write-region 
        (point-min) (point-max) gnus-cache-active-file nil 'silent))
     ;; Mark the active hashtb as unaltered.
index c2cc879..e001c19 100644 (file)
@@ -84,8 +84,7 @@ seen in the same session.")
 (defun gnus-dup-save ()
   "Save the duplicate suppression list."
   (nnheader-temp-write gnus-duplicate-file
-    (prin1 `(setq gnus-duplicate-file ',gnus-duplicate-file)
-          (current-buffer))))
+    (gnus-prin1 `(setq gnus-duplicate-file ',gnus-duplicate-file))))
 
 ;;;
 ;;; Interface functions
index 309bac4..f0a40e6 100644 (file)
@@ -185,7 +185,8 @@ pounce directly on the real variables themselves."))
     ;; Mule definitions
     (defalias 'gnus-truncate-string 'truncate-string)
 
-    (fset 'gnus-summary-make-display-table (lambda () nil))
+    (defvar gnus-summary-display-table nil
+      "Display table used in summary mode buffers.")
     (fset 'gnus-cite-add-face 'gnus-mule-cite-add-face)
     (fset 'gnus-max-width-function 'gnus-mule-max-width-function)
     
index 6a2cea5..e8c9865 100644 (file)
@@ -824,14 +824,10 @@ recommend using both scores and grouplens predictions together."
          (if (null arg) (not gnus-grouplens-mode)
            (> (prefix-numeric-value arg) 0)))
     (when gnus-grouplens-mode
-      (if (not (fboundp 'make-local-hook))
-         (add-hook 'gnus-select-article-hook 'grouplens-do-time)
-       (make-local-hook 'gnus-select-article-hook)
-       (add-hook 'gnus-select-article-hook 'grouplens-do-time nil 'local))
-      (if (not (fboundp 'make-local-hook))
-         (add-hook 'gnus-exit-group-hook 'bbb-put-ratings)
-       (make-local-hook 'gnus-exit-group-hook)
-       (add-hook 'gnus-exit-group-hook 'bbb-put-ratings nil 'local))
+      (gnus-make-local-hook 'gnus-select-article-hook)
+      (gnus-add-hook 'gnus-select-article-hook 'grouplens-do-time nil 'local)
+      (gnus-make-local-hook 'gnus-exit-group-hook)
+      (gnus-add-hook 'gnus-exit-group-hook 'bbb-put-ratings nil 'local)
       (make-local-variable 'gnus-score-find-score-files-function)
       (cond ((eq gnus-grouplens-override-scoring 'combine)
             ;; either add bbb-buld-mid-scores-alist to a list
@@ -851,11 +847,12 @@ recommend using both scores and grouplens predictions together."
            ;; default is to override
            (t (setq gnus-score-find-score-files-function 
                     'bbb-build-mid-scores-alist)))
+
+      ;; Change how summary lines look
       (make-local-variable 'gnus-summary-line-format)
-      (setq gnus-summary-line-format 
-           gnus-summary-grouplens-line-format)
       (make-local-variable 'gnus-summary-line-format-spec)
-      (setq gnus-summary-line-format nil)
+      (setq gnus-summary-line-format gnus-summary-grouplens-line-format)
+      (setq gnus-summary-line-format-spec nil)
       (gnus-update-format-specifications nil 'summary)
       (gnus-update-summary-mark-positions)
 
index 1bd00cd..35daf95 100644 (file)
@@ -346,7 +346,7 @@ variable.")
     "V" gnus-group-make-empty-virtual
     "D" gnus-group-enter-directory
     "f" gnus-group-make-doc-group
-    "n" gnus-group-make-dejagnus-group
+    "n" gnus-group-make-web-group
     "r" gnus-group-rename-group
     "\177" gnus-group-delete-group
     [delete] gnus-group-delete-group)
@@ -650,15 +650,16 @@ The following commands are available:
 Default is all subscribed groups.
 If argument UNREAD is non-nil, groups with no unread articles are also
 listed."
-  (interactive (list (if current-prefix-arg
-                        (prefix-numeric-value current-prefix-arg)
-                      (or
-                       (gnus-group-default-level nil t)
-                       gnus-group-default-list-level
-                       gnus-level-subscribed))))
-  (or level
-      (setq level (car gnus-group-list-mode)
-           unread (cdr gnus-group-list-mode)))
+  (interactive
+   (list (if current-prefix-arg
+            (prefix-numeric-value current-prefix-arg)
+          (or
+           (gnus-group-default-level nil t)
+           gnus-group-default-list-level
+           gnus-level-subscribed))))
+  (unless level
+    (setq level (car gnus-group-list-mode)
+         unread (cdr gnus-group-list-mode)))
   (setq level (gnus-group-default-level level))
   (gnus-group-setup-buffer)            ;May call from out of group buffer
   (gnus-update-format-specifications)
@@ -680,20 +681,22 @@ listed."
          ;; has disappeared in the new listing, try to find the next
          ;; one.        If no next one can be found, just leave point at the
          ;; first newsgroup in the buffer.
-         (if (not (gnus-goto-char
-                   (text-property-any
-                    (point-min) (point-max)
-                    'gnus-group (gnus-intern-safe group gnus-active-hashtb))))
-             (let ((newsrc (cdddr (gnus-gethash group gnus-newsrc-hashtb))))
-               (while (and newsrc
-                           (not (gnus-goto-char
-                                 (text-property-any
-                                  (point-min) (point-max) 'gnus-group
-                                  (gnus-intern-safe
-                                   (caar newsrc) gnus-active-hashtb)))))
-                 (setq newsrc (cdr newsrc)))
-               (or newsrc (progn (goto-char (point-max))
-                                 (forward-line -1)))))))
+         (when (not (gnus-goto-char
+                     (text-property-any
+                      (point-min) (point-max)
+                      'gnus-group (gnus-intern-safe
+                                   group gnus-active-hashtb))))
+           (let ((newsrc (cdddr (gnus-gethash group gnus-newsrc-hashtb))))
+             (while (and newsrc
+                         (not (gnus-goto-char
+                               (text-property-any
+                                (point-min) (point-max) 'gnus-group
+                                (gnus-intern-safe
+                                 (caar newsrc) gnus-active-hashtb)))))
+               (setq newsrc (cdr newsrc)))
+             (unless newsrc
+               (goto-char (point-max))
+               (forward-line -1))))))
       ;; Adjust cursor point.
       (gnus-group-position-point))))
 
@@ -797,7 +800,7 @@ If REGEXP, only list groups matching REGEXP."
           (not (gnus-ephemeral-group-p group))
           (gnus-dribble-enter
            (concat "(gnus-group-set-info '"
-                   (prin1-to-string (nth 2 entry)) ")")))
+                   (gnus-prin1-to-string (nth 2 entry)) ")")))
       (setq gnus-group-indentation (gnus-group-group-indentation))
       (gnus-delete-line)
       (gnus-group-insert-group-line-info group)
@@ -946,7 +949,8 @@ already."
        (let ((entry (gnus-gethash group gnus-newsrc-hashtb)))
          (if (and entry (not (gnus-ephemeral-group-p group)))
              (gnus-dribble-enter
-              (concat "(gnus-group-set-info '" (prin1-to-string (nth 2 entry))
+              (concat "(gnus-group-set-info '" 
+                      (gnus-prin1-to-string (nth 2 entry))
                       ")"))))
        ;; Find all group instances.  If topics are in use, each group
        ;; may be listed in more than once.
@@ -1533,7 +1537,8 @@ ADDRESS."
     (gnus-set-active nname (cons 1 0))
     (or (gnus-ephemeral-group-p name)
        (gnus-dribble-enter
-        (concat "(gnus-group-set-info '" (prin1-to-string (cdr info)) ")")))
+        (concat "(gnus-group-set-info '" 
+                (gnus-prin1-to-string (cdr info)) ")")))
     ;; Insert the line.
     (gnus-group-insert-group-line-info nname)
     (forward-line -1)
@@ -1754,16 +1759,33 @@ and NEW-NAME will be prompted for."
           (list 'nndoc-address file)
           (list 'nndoc-article-type (or type 'guess))))))
 
-(defun gnus-group-make-dejagnus-group (&optional solid)
-  "Create an ephemeral nndejagnus group.
+(defvar nnweb-type-definition)
+(defvar gnus-group-web-type-history nil)
+(defvar gnus-group-web-search-history nil)
+(defun gnus-group-make-web-group (&optional solid)
+  "Create an ephemeral nnweb group.
 If SOLID (the prefix), create a solid group."
   (interactive "P")
+  (require 'nnweb)
   (let* ((group
          (if solid (read-string "Group name: ") (message-unique-id)))
+        (type
+         (completing-read
+          "Search engine type: "
+          (mapcar (lambda (elem) (list (symbol-name (car elem))))
+                  nnweb-type-definition)
+          nil t (cons (or (car gnus-group-web-type-history)
+                          (symbol-name (caar nnweb-type-definition)))
+                      0)
+          'gnus-group-web-type-history))
         (search
-         (read-string "Search string: "))
+         (read-string 
+          "Search string: " 
+          (cons (or (car gnus-group-web-search-history) "") 0)
+          'gnus-group-web-search-history))
         (method
-         `(nndejagnus ,group (nndejagnus-search ,search))))
+         `(nnweb ,group (nnweb-search ,search)
+                 (nnweb-type ,(intern type)))))
     (if solid
        (gnus-group-make-group group method)
       (gnus-group-read-ephemeral-group
@@ -1874,17 +1896,17 @@ score file entries for articles to include in the group."
 (defun gnus-group-enter-directory (dir)
   "Enter an ephemeral nneething group."
   (interactive "DDirectory to read: ")
-  (let* ((method (list 'nneething dir))
+  (let* ((method (list 'nneething dir '(nneething-read-only t)))
         (leaf (gnus-group-prefixed-name
                (file-name-nondirectory (directory-file-name dir))
                method))
         (name (gnus-generate-new-group-name leaf)))
-    (let ((nneething-read-only t))
-      (or (gnus-group-read-ephemeral-group
-          name method t
-          (cons (current-buffer) (if (eq major-mode 'gnus-summary-mode)
-                                     'summary 'group)))
-         (error "Couldn't enter %s" dir)))))
+    (unless (gnus-group-read-ephemeral-group
+            name method t
+            (cons (current-buffer)
+                  (if (eq major-mode 'gnus-summary-mode)
+                      'summary 'group)))
+      (error "Couldn't enter %s" dir))))
 
 ;; Group sorting commands
 ;; Suggested by Joe Hildebrand <hildjj@idaho.fuentez.com>.
@@ -2456,28 +2478,26 @@ If ARG is a number, it specifies which levels you are interested in
 re-scanning.  If ARG is non-nil and not a number, this will force
 \"hard\" re-reading of the active files from all servers."
   (interactive "P")
-  (save-excursion
-    (set-buffer gnus-group-buffer)
-    (run-hooks 'gnus-get-new-news-hook)
-    ;; We might read in new NoCeM messages here.
-    (when (and gnus-use-nocem 
-              (null arg))
-      (gnus-nocem-scan-groups))
-    ;; If ARG is not a number, then we read the active file.
-    (when (and arg (not (numberp arg)))
-      (let ((gnus-read-active-file t))
-       (gnus-read-active-file))
-      (setq arg nil))
-
-    (setq arg (gnus-group-default-level arg t))
-    (if (and gnus-read-active-file (not arg))
-       (progn
-         (gnus-read-active-file)
-         (gnus-get-unread-articles arg))
-      (let ((gnus-read-active-file (if arg nil gnus-read-active-file)))
-       (gnus-get-unread-articles arg)))
-    (run-hooks 'gnus-after-getting-new-news-hook)
-    (gnus-group-list-groups)))
+  (run-hooks 'gnus-get-new-news-hook)
+  ;; We might read in new NoCeM messages here.
+  (when (and gnus-use-nocem 
+            (null arg))
+    (gnus-nocem-scan-groups))
+  ;; If ARG is not a number, then we read the active file.
+  (when (and arg (not (numberp arg)))
+    (let ((gnus-read-active-file t))
+      (gnus-read-active-file))
+    (setq arg nil))
+
+  (setq arg (gnus-group-default-level arg t))
+  (if (and gnus-read-active-file (not arg))
+      (progn
+       (gnus-read-active-file)
+       (gnus-get-unread-articles arg))
+    (let ((gnus-read-active-file (if arg nil gnus-read-active-file)))
+      (gnus-get-unread-articles arg)))
+  (run-hooks 'gnus-after-getting-new-news-hook)
+  (gnus-group-list-groups))
 
 (defun gnus-group-get-new-news-this-group (&optional n)
   "Check for newly arrived news in the current group (and the N-1 next groups).
@@ -2490,6 +2510,8 @@ If N is negative, this group and the N-1 previous groups will be checked."
         group)
     (while (setq group (pop groups))
       (gnus-group-remove-mark group)
+      ;; Bypass any previous denials from the server.
+      (gnus-remove-denial (gnus-find-method-for-group group))
       (if (gnus-activate-group group 'scan)
          (progn
            (gnus-get-unread-articles-in-group
@@ -2508,26 +2530,31 @@ If N is negative, this group and the N-1 previous groups will be checked."
     ret))
 
 (defun gnus-group-fetch-faq (group &optional faq-dir)
-  "Fetch the FAQ for the current group."
+  "Fetch the FAQ for the current group.
+If given a prefix argument, prompt for the FAQ dir
+to use."
   (interactive
    (list
-    (and (gnus-group-group-name)
-        (gnus-group-real-name (gnus-group-group-name)))
+    (gnus-group-group-name)
     (cond (current-prefix-arg
           (completing-read
            "Faq dir: " (and (listp gnus-group-faq-directory)
                             (mapcar (lambda (file) (list file))
                                     gnus-group-faq-directory)))))))
-  (or faq-dir
-      (setq faq-dir (if (listp gnus-group-faq-directory)
-                       (car gnus-group-faq-directory)
-                     gnus-group-faq-directory)))
-  (or group (error "No group name given"))
-  (let ((file (concat (file-name-as-directory faq-dir)
-                     (gnus-group-real-name group))))
-    (if (not (file-exists-p file))
-       (error "No such file: %s" file)
-      (find-file file))))
+  (unless group
+    (error "No group name given"))
+  (let ((dirs (or faq-dir gnus-group-faq-directory))
+       dir found file)
+    (unless (listp dirs)
+      (setq dirs (list dirs)))
+    (while (and (not found)
+               (setq dir (pop dirs)))
+      (setq file (concat (file-name-as-directory dir)
+                        (gnus-group-real-name group)))
+      (if (not (file-exists-p file))
+         (gnus-message 1 "No such file: %s" file)
+       (find-file file)
+       (setq found t)))))
 
 (defun gnus-group-describe-group (force &optional group)
   "Display a description of the current newsgroup."
@@ -2662,8 +2689,7 @@ If FORCE, force saving whether it is necessary or not."
   "Force Gnus to read the .newsrc file."
   (interactive "P")
   (when (gnus-yes-or-no-p
-        (format "Are you sure you want to read %s? "
-                gnus-current-startup-file))
+        (format "Are you sure you want to restart Gnus? "))
     (gnus-save-newsrc-file)
     (gnus-setup-news 'force)
     (gnus-group-list-groups arg)))
index 531fdad..8953df2 100644 (file)
@@ -402,6 +402,16 @@ If GROUP is nil, all groups on METHOD are scanned."
     (when (fboundp func)
       (funcall func))))
 
+(defun gnus-remove-denial (method)
+  (when (stringp method)
+    (setq method (gnus-server-to-method method)))
+  (let* ((elem (assoc method gnus-opened-servers))
+        (status (cadr elem)))
+    ;; If this hasn't been opened before, we add it to the list.
+    (when (eq status 'denied)
+      ;; Set the status of this server.
+      (setcar (cdr elem) 'closed))))
+
 (provide 'gnus-int)
 
 ;;; gnus-int.el ends here
index 4c8d9c0..0e02ca3 100644 (file)
@@ -552,7 +552,7 @@ COMMAND must be a lisp expression or a string representing a key sequence."
          (not (consp (cdr (nth 2 object))))
          (and (eq 'quote (car (nth 2 object)))
               (not (consp (cdadr (nth 2 object))))))
-      (concat "\n" (prin1-to-string object))
+      (concat "\n" (gnus-prin1-to-string object))
     (save-excursion
       (set-buffer (get-buffer-create "*Gnus PP*"))
       (buffer-disable-undo (current-buffer))
@@ -562,7 +562,7 @@ COMMAND must be a lisp expression or a string representing a key sequence."
            (first t))
        (while klist
          (insert (if first (progn (setq first nil) "")  "\n    ")
-                 (prin1-to-string (car klist)))
+                 (gnus-prin1-to-string (car klist)))
          (setq klist (cdr klist))))
       (insert ")")
       (and (nth 3 object)
@@ -570,7 +570,7 @@ COMMAND must be a lisp expression or a string representing a key sequence."
                   (if (and (consp (nth 3 object))
                            (not (eq 'quote (car (nth 3 object))))) 
                       "'" "")
-                  (prin1-to-string (nth 3 object))))
+                  (gnus-prin1-to-string (nth 3 object))))
       (and (nth 4 object)
           (insert "\n  t"))
       (insert ")")
@@ -591,7 +591,7 @@ COMMAND must be a lisp expression or a string representing a key sequence."
                     (setq value (funcall function header))
                     ;; Number (Lines:) or symbol must be converted to string.
                     (or (stringp value)
-                        (setq value (prin1-to-string value)))
+                        (setq value (gnus-prin1-to-string value)))
                     (setq did-kill (string-match regexp value)))
                   (cond ((stringp form)        ;Keyboard macro.
                          (execute-kbd-macro form))
@@ -648,7 +648,7 @@ marked as read or ticked are ignored."
              ;; Find later articles.
              (setq article 
                    (gnus-summary-search-forward 
-                    (not ignore-marked) nil backward)))
+                    ignore-marked nil backward)))
        (and (or (null gnus-newsgroup-kill-headers)
                 (memq article gnus-newsgroup-kill-headers))
             (vectorp (setq header (gnus-summary-article-header article)))
index 4f85c0f..8952478 100644 (file)
@@ -162,6 +162,7 @@ Thank you for your help in stamping out bugs.
        ,@forms
        (gnus-inews-add-send-actions ,winconf ,buffer ,article)
        (setq gnus-message-buffer (current-buffer))
+       (make-local-variable 'gnus-newsgroup-name)
        (gnus-configure-windows ,config t))))
     
 (defun gnus-inews-add-send-actions (winconf buffer article)
@@ -470,8 +471,7 @@ If SILENT, don't prompt the user."
                                  gnus-inews-sent-ids))
            (setcdr end nil))
          (nnheader-temp-write gnus-sent-message-ids-file
-           (prin1 `(setq gnus-inews-sent-ids ',gnus-inews-sent-ids)
-                  (current-buffer)))
+           (gnus-prin1 `(setq gnus-inews-sent-ids ',gnus-inews-sent-ids)))
          nil)))))
 
 \f
index 2b18ec7..f1c9290 100644 (file)
@@ -202,13 +202,13 @@ isn't bound, the message will be used unconditionally.")
   (when (and gnus-nocem-alist
             gnus-nocem-touched-alist)
     (nnheader-temp-write (gnus-nocem-cache-file)
-      (prin1 `(setq gnus-nocem-alist ',gnus-nocem-alist) (current-buffer)))
+      (gnus-prin1 `(setq gnus-nocem-alist ',gnus-nocem-alist)))
     (setq gnus-nocem-touched-alist nil)))
 
 (defun gnus-nocem-save-active ()
   "Save the NoCeM active file."
   (nnheader-temp-write (gnus-nocem-active-file)
-    (prin1 `(setq gnus-nocem-active ',gnus-nocem-active) (current-buffer))))
+    (gnus-prin1 `(setq gnus-nocem-active ',gnus-nocem-active))))
 
 (defun gnus-nocem-alist-to-hashtb ()
   "Create a hashtable from the Message-IDs we have."
index a2d5988..9732f6f 100644 (file)
@@ -165,7 +165,10 @@ This variable allows the same syntax as `gnus-home-score-file'.")
     (gnus-del-mark (from -2) (subject -15)))
 "*Alist of marks and scores.")
 
-(defvar gnus-ignored-adaptive-words
+(defvar gnus-ignored-adaptive-words nil
+  "*List of words to be ignored when doing adaptive word scoring.")
+
+(defvar gnus-default-ignored-adaptive-words
   '("a" "i" "the" "to" "of" "and" "in" "is" "it" "for" "that" "if" "you"
     "this" "be" "on" "with" "not" "have" "are" "or" "as" "from" "can"
     "but" "by" "at" "an" "will" "no" "all" "was" "do" "there" "my" "one"
@@ -179,9 +182,19 @@ This variable allows the same syntax as `gnus-home-score-file'.")
     "right" "before" "our" "without" "too" "those" "why" "must" "part"
     "being" "current" "back" "still" "go" "point" "value" "each" "did"
     "both" "true" "off" "say" "another" "state" "might" "under" "start"
-    "try")
-  "List of words to be ignored when doing adaptive word scoring.")
-  
+    "try"
+
+    "re")
+  "Default list of words to be ignored when doing adaptive word scoring.")
+
+(defvar gnus-adaptive-word-syntax-table
+  (let ((table (copy-syntax-table (standard-syntax-table)))
+       (numbers '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)))
+    (while numbers
+      (modify-syntax-entry (pop numbers) " " table))
+    table)
+  "Syntax table used when doing adaptive word scoring.")
+
 (defvar gnus-default-adaptive-word-score-alist  
   `((,gnus-read-mark . 30)
     (,gnus-catchup-mark . -10)
@@ -591,8 +604,8 @@ used as score."
                  gnus-score-alist
                  (gnus-newsgroup-score-alist)))))
 
-(defun gnus-summary-score-entry 
-  (header match type score date &optional prompt silent)
+(defun gnus-summary-score-entry (header match type score date
+                                       &optional prompt silent)
   "Enter score file entry.
 HEADER is the header being scored.
 MATCH is the string we are looking for.
@@ -654,7 +667,11 @@ If optional argument `SILENT' is nil, show effect of score entry."
            elem)
        (setq new
              (cond 
-              (type (list match score (and date (gnus-day-number date)) type))
+              (type
+               (list match score
+                     (and date (if (numberp date) date
+                                 (gnus-day-number date)))
+                     type))
               (date (list match score (gnus-day-number date)))
               (score (list match score))
               (t (list match))))
@@ -1163,7 +1180,7 @@ SCORE is the score to add."
                ;; This is an adaptive score file, so we do not run
                ;; it through `pp'.  These files can get huge, and
                ;; are not meant to be edited by human hands.
-               (prin1 score (current-buffer))
+               (gnus-prin1 score)
              ;; This is a normal score file, so we print it very
              ;; prettily. 
              (pp score (current-buffer))))
@@ -1745,6 +1762,7 @@ SCORE is the score to add."
               (search-func 
                (cond ((= dmt ?r) 're-search-forward)
                      ((or (= dmt ?e) (= dmt ?s) (= dmt ?f)) 'search-forward)
+                     ((= dmt ?w) nil)
                      (t (error "Illegal match type: %s" type)))))
          (cond
           ;; Fuzzy matches.  We save these for later.
@@ -1872,6 +1890,7 @@ SCORE is the score to add."
                 (date (nth 2 kill))
                 found)
            (when (setq arts (intern-soft (nth 0 kill) hashtb))
+             (setq arts (symbol-value arts))
              (setq found t)
              (if trace
                  (while (setq art (pop arts))
@@ -1895,23 +1914,32 @@ SCORE is the score to add."
             ((and expire (< date expire)) 
              (gnus-score-set 'touched '(t) alist)
              (setcdr (car words) (cddar words))))
-           (setq fuzzies (cdr fuzzies))))))
+           (setq words (cdr words))))))
     nil))
 
 (defun gnus-enter-score-words-into-hashtb (hashtb)
   ;; Find all the words in the buffer and enter them into
   ;; the hashtable.
-  (let (word)
+  (let ((syntab (syntax-table))
+        word val)
     (goto-char (point-min))
-    (while (re-search-forward "\\b\\w+\\b" nil t)
-      (gnus-sethash
-       (setq word (downcase (buffer-substring
-                            (match-beginning 0) (match-end 0))))
-       (append (get-text-property (gnus-point-at-eol) 'articles)
-              (gnus-gethash word hashtb))
-       hashtb))
+    (unwind-protect
+       (progn
+         (set-syntax-table gnus-adaptive-word-syntax-table)
+         (while (re-search-forward "\\b\\w+\\b" nil t)
+           (setq val
+                 (gnus-gethash 
+                  (setq word (downcase (buffer-substring
+                                        (match-beginning 0) (match-end 0))))
+                  hashtb))
+           (gnus-sethash
+            word
+            (append (get-text-property (gnus-point-at-eol) 'articles) val)
+            hashtb)))
+      (set-syntax-table syntab))
     ;; Make all the ignorable words ignored.
-    (let ((ignored gnus-ignored-adaptive-words))
+    (let ((ignored (append gnus-ignored-adaptive-words
+                          gnus-default-ignored-adaptive-words)))
       (while ignored
        (gnus-sethash (pop ignored) nil hashtb)))))
 
@@ -2002,37 +2030,46 @@ SCORE is the score to add."
      ((memq 'word gnus-use-adaptive-scoring)
       (nnheader-temp-write nil
        (let* ((hashtb (gnus-make-hashtable 1000))
-              (date (current-time-string))
+              (date (gnus-day-number (current-time-string)))
               (data gnus-newsgroup-data)
-              word d score)
-         ;; Go through all articles.
-         (while (setq d (pop data))
-           (when (setq score (cdr (assq 
+              (syntab (syntax-table))
+              word d score val)
+         (unwind-protect
+             (progn
+               (set-syntax-table syntab)
+               ;; Go through all articles.
+               (while (setq d (pop data))
+                 (when (setq score
+                             (cdr (assq 
                                    (gnus-data-mark d)
                                    gnus-default-adaptive-word-score-alist)))
-             ;; This article has a mark that should lead to
-             ;; adaptive word rules, so we insert the subject
-             ;; and find all words in that string.
-             (insert (mail-header-subject (gnus-data-header d)))
-             (downcase-region (point-min) (point-max))
-             (goto-char (point-min))
-             (while (re-search-forward "\\b\\w+\\b" nil t)
-               ;; Put the word and score into the hashtb.
-               (gnus-sethash (setq word (match-string 0))
-                             (+ (or (gnus-gethash word hashtb) 0) score)
-                             hashtb))
-             (erase-buffer)))
+                   ;; This article has a mark that should lead to
+                   ;; adaptive word rules, so we insert the subject
+                   ;; and find all words in that string.
+                   (insert (mail-header-subject (gnus-data-header d)))
+                   (downcase-region (point-min) (point-max))
+                   (goto-char (point-min))
+                   (while (re-search-forward "\\b\\w+\\b" nil t)
+                     ;; Put the word and score into the hashtb.
+                     (setq val (gnus-gethash (setq word (match-string 0))
+                                             hashtb))
+                     (gnus-sethash word (+ (or val 0) score) hashtb))
+                   (erase-buffer))))
+           (set-syntax-table syntab))
          ;; Make all the ignorable words ignored.
-         (let ((ignored gnus-ignored-adaptive-words))
+         (let ((ignored (append gnus-ignored-adaptive-words
+                                gnus-default-ignored-adaptive-words)))
            (while ignored
              (gnus-sethash (pop ignored) nil hashtb)))
          ;; Now we have all the words and scores, so we
          ;; add these rules to the ADAPT file.
+         (set-buffer gnus-summary-buffer)
          (mapatoms
           (lambda (word)
-            (gnus-summary-score-entry
-             "subject" (symbol-name word) 'w (symbol-value word)
-             date))
+            (when (symbol-value word)
+              (gnus-summary-score-entry
+               "subject" (symbol-name word) 'w (symbol-value word)
+               date nil t)))
           hashtb)))))))
 
 (defun gnus-score-edit-done ()
index 4d8086f..1938377 100644 (file)
         (if (> (length val) ,cut)
             ,(if (< cut-width 0)
                  `(substring val 0 (- (length val) ,cut))
-               `(substring val ,cut))
+               `(substring val ,cut))
           val)))))
 
 (defun gnus-tilde-ignore-form (el ignore-value)
              t)
             (t
              nil)))
+       ;; User-defined spec -- find the spec name.
        (when (= (setq spec (following-char)) ?u)
          (forward-char 1)
          (setq user-defined (following-char)))
index 78beaf2..0061d01 100644 (file)
@@ -721,9 +721,9 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
 
     ;; If we don't read the complete active file, we fill in the
     ;; hashtb here.
-    (if (or (null gnus-read-active-file)
-           (eq gnus-read-active-file 'some))
-       (gnus-update-active-hashtb-from-killed))
+    (when (or (null gnus-read-active-file)
+             (eq gnus-read-active-file 'some))
+      (gnus-update-active-hashtb-from-killed))
 
     ;; Read the active file and create `gnus-active-hashtb'.
     ;; If `gnus-read-active-file' is nil, then we just create an empty
@@ -733,8 +733,8 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
         (not level)
         (gnus-read-active-file))
 
-    (or gnus-active-hashtb
-       (setq gnus-active-hashtb (make-vector 4095 0)))
+    (unless gnus-active-hashtb
+      (setq gnus-active-hashtb (make-vector 4095 0)))
 
     ;; Initialize the cache.
     (when gnus-use-cache
@@ -750,16 +750,16 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
     (gnus-update-format-specifications)
 
     ;; See whether we need to read the description file.
-    (if (and (string-match "%[-,0-9]*D" gnus-group-line-format)
-            (not gnus-description-hashtb)
-            (not dont-connect)
-            gnus-read-active-file)
-       (gnus-read-all-descriptions-files))
+    (when (and (string-match "%[-,0-9]*D" gnus-group-line-format)
+              (not gnus-description-hashtb)
+              (not dont-connect)
+              gnus-read-active-file)
+      (gnus-read-all-descriptions-files))
 
     ;; Find new newsgroups and treat them.
-    (if (and init gnus-check-new-newsgroups (not level)
-            (gnus-check-server gnus-select-method))
-       (gnus-find-new-newsgroups))
+    (when (and init gnus-check-new-newsgroups (not level)
+              (gnus-check-server gnus-select-method))
+      (gnus-find-new-newsgroups))
 
     ;; We might read in new NoCeM messages here.
     (when (and gnus-use-nocem 
@@ -771,10 +771,10 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
     (let ((gnus-read-active-file (and (not level) gnus-read-active-file)))
       (gnus-get-unread-articles level))
 
-    (if (and init gnus-check-bogus-newsgroups
-            gnus-read-active-file (not level)
-            (gnus-server-opened gnus-select-method))
-       (gnus-check-bogus-newsgroups))))
+    (when (and init gnus-check-bogus-newsgroups
+              gnus-read-active-file (not level)
+              (gnus-server-opened gnus-select-method))
+      (gnus-check-bogus-newsgroups))))
 
 (defun gnus-find-new-newsgroups (&optional arg)
   "Search for new newsgroups and add them.
@@ -2087,31 +2087,33 @@ If FORCE is non-nil, the .newsrc file is read."
 
 (defun gnus-gnus-to-quick-newsrc-format ()
   "Insert Gnus variables such as gnus-newsrc-alist in lisp format."
-  (insert ";; Gnus startup file.\n")
-  (insert ";; Never delete this file - touch .newsrc instead to force Gnus\n")
-  (insert ";; to read .newsrc.\n")
-  (insert "(setq gnus-newsrc-file-version "
-         (prin1-to-string gnus-version) ")\n")
-  (let* ((gnus-killed-list
-         (if (and gnus-save-killed-list
-                  (stringp gnus-save-killed-list))
-             (gnus-strip-killed-list)
-           gnus-killed-list))
-        (variables
-         (if gnus-save-killed-list gnus-variable-list
-           ;; Remove the `gnus-killed-list' from the list of variables
-           ;; to be saved, if required.
-           (delq 'gnus-killed-list (copy-sequence gnus-variable-list))))
-        ;; Peel off the "dummy" group.
-        (gnus-newsrc-alist (cdr gnus-newsrc-alist))
-        variable)
-    ;; Insert the variables into the file.
-    (while variables
-      (when (and (boundp (setq variable (pop variables)))
-                (symbol-value variable))
-       (insert "(setq " (symbol-name variable) " '")
-       (prin1 (symbol-value variable) (current-buffer))
-       (insert ")\n")))))
+  (let ((print-quoted t))
+    (insert ";; Gnus startup file.\n")
+    (insert
+     ";; Never delete this file - touch .newsrc instead to force Gnus\n")
+    (insert ";; to read .newsrc.\n")
+    (insert "(setq gnus-newsrc-file-version "
+           (prin1-to-string gnus-version) ")\n")
+    (let* ((gnus-killed-list
+           (if (and gnus-save-killed-list
+                    (stringp gnus-save-killed-list))
+               (gnus-strip-killed-list)
+             gnus-killed-list))
+          (variables
+           (if gnus-save-killed-list gnus-variable-list
+             ;; Remove the `gnus-killed-list' from the list of variables
+             ;; to be saved, if required.
+             (delq 'gnus-killed-list (copy-sequence gnus-variable-list))))
+          ;; Peel off the "dummy" group.
+          (gnus-newsrc-alist (cdr gnus-newsrc-alist))
+          variable)
+      ;; Insert the variables into the file.
+      (while variables
+       (when (and (boundp (setq variable (pop variables)))
+                  (symbol-value variable))
+         (insert "(setq " (symbol-name variable) " '")
+         (prin1 (symbol-value variable) (current-buffer))
+         (insert ")\n"))))))
 
 (defun gnus-strip-killed-list ()
   "Return the killed list minus the groups that match `gnus-save-killed-list'."
index cd3831e..ab459e3 100644 (file)
@@ -1015,7 +1015,6 @@ increase the score of each group you read."
     "e" gnus-article-emphasize
     "w" gnus-article-fill-cited-article
     "c" gnus-article-remove-cr
-    "L" gnus-article-remove-trailing-blank-lines
     "q" gnus-article-de-quoted-unreadable
     "f" gnus-article-display-x-face
     "l" gnus-summary-stop-page-breaking
@@ -1047,6 +1046,12 @@ increase the score of each group you read."
     "e" gnus-article-date-lapsed
     "o" gnus-article-date-original)
 
+  (gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
+    "t" gnus-article-remove-trailing-blank-lines
+    "l" gnus-article-strip-leading-blank-lines
+    "m" gnus-article-strip-multiple-blank-lines
+    "a" gnus-article-strip-blank-lines)
+
   (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
     "v" gnus-version
     "f" gnus-summary-fetch-faq
@@ -1065,7 +1070,8 @@ increase the score of each group you read."
     "c" gnus-summary-copy-article
     "B" gnus-summary-crosspost-article
     "q" gnus-summary-respool-query
-    "i" gnus-summary-import-article)
+    "i" gnus-summary-import-article
+    "p" gnus-summary-article-posted-p)
 
   (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
     "o" gnus-summary-save-article
@@ -1076,8 +1082,7 @@ increase the score of each group you read."
     "h" gnus-summary-save-article-folder
     "v" gnus-summary-save-article-vm
     "p" gnus-summary-pipe-output
-    "s" gnus-soup-add-article)
-  )
+    "s" gnus-soup-add-article))
 
 (defun gnus-summary-make-menu-bar ()
   (gnus-turn-off-edit-menu 'summary)
@@ -1241,11 +1246,15 @@ increase the score of each group you read."
        ["Original" gnus-article-date-original t]
        ["Lapsed" gnus-article-date-lapsed t])
        ("Filter"
+       ("Remove Blanks"
+        ["Leading" gnus-article-strip-leading-blank-lines t]
+        ["Multiple" gnus-article-strip-multiple-blank-lines t]
+        ["Trailing" gnus-article-remove-trailing-blank-lines t]
+        ["All of the above" gnus-article-strip-blank-lines t])
        ["Overstrike" gnus-article-treat-overstrike t]
        ["Emphasis" gnus-article-emphasize t]
        ["Word wrap" gnus-article-fill-cited-article t]
        ["CR" gnus-article-remove-cr t]
-       ["Trailing blank lines" gnus-article-remove-trailing-blank-lines t]
        ["Show X-Face" gnus-article-display-x-face t]
        ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
        ["Rot 13" gnus-summary-caesar-message t]
@@ -1275,6 +1284,7 @@ increase the score of each group you read."
         (gnus-check-backend-function
          'request-replace-article gnus-newsgroup-name)]
        ["Import file..." gnus-summary-import-article t]
+       ["Chek if posted" gnus-summary-article-posted-p t]
        ["Edit article" gnus-summary-edit-article
         (not (gnus-group-read-only-p))]
        ["Delete article" gnus-summary-delete-article
@@ -3288,7 +3298,9 @@ If READ-ALL is non-nil, all articles in the group are selected."
          ;; are no unread articles.
          (if (or read-all
                  (and (zerop (length gnus-newsgroup-marked))
-                      (zerop (length gnus-newsgroup-unreads))))
+                      (zerop (length gnus-newsgroup-unreads)))
+                 (eq (gnus-group-find-parameter group 'display)
+                     'all))
              (gnus-uncompress-range (gnus-active group))
            (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked
                          (copy-sequence gnus-newsgroup-unreads))
@@ -5383,43 +5395,47 @@ fetch-old-headers verbiage, and so on."
             0))
          (number (mail-header-number (car thread)))
          score)
-      (if (or
-          ;; If this article is dormant and has absolutely no visible
-          ;; children, then this article isn't visible.
-          (and (memq number gnus-newsgroup-dormant)
-               (= children 0))
-          ;; If this is "fetch-old-headered" and there is only one
-          ;; visible child (or less), then we don't want this article.
-          (and (eq gnus-fetch-old-headers 'some)
-               (memq number gnus-newsgroup-ancient)
-               (zerop children))
-          ;; If this is a sparsely inserted article with no children,
-          ;; we don't want it.
-          (and (eq gnus-build-sparse-threads 'some)
-               (memq number gnus-newsgroup-sparse)
-               (zerop children))
-          ;; If we use expunging, and this article is really
-          ;; low-scored, then we don't want this article.
-          (when (and gnus-summary-expunge-below
-                     (< (setq score
-                              (or (cdr (assq number gnus-newsgroup-scored))
-                                  gnus-summary-default-score))
-                        gnus-summary-expunge-below))
-            ;; We increase the expunge-tally here, but that has
-            ;; nothing to do with the limits, really.
-            (incf gnus-newsgroup-expunged-tally)
-            ;; We also mark as read here, if that's wanted.
-            (when (and gnus-summary-mark-below
-                       (< score gnus-summary-mark-below))
-              (setq gnus-newsgroup-unreads
-                    (delq number gnus-newsgroup-unreads))
-              (if gnus-newsgroup-auto-expire
-                  (push number gnus-newsgroup-expirable)
-                (push (cons number gnus-low-score-mark)
-                      gnus-newsgroup-reads)))
-            t)
-          (and gnus-use-nocem
-               (gnus-nocem-unwanted-article-p (mail-header-id (car thread)))))
+      (if (and
+          (not (memq number gnus-newsgroup-marked))
+          (or
+           ;; If this article is dormant and has absolutely no visible
+           ;; children, then this article isn't visible.
+           (and (memq number gnus-newsgroup-dormant)
+                (= children 0))
+           ;; If this is "fetch-old-headered" and there is only one
+           ;; visible child (or less), then we don't want this article.
+           (and (eq gnus-fetch-old-headers 'some)
+                (memq number gnus-newsgroup-ancient)
+                (zerop children))
+           ;; If this is a sparsely inserted article with no children,
+           ;; we don't want it.
+           (and (eq gnus-build-sparse-threads 'some)
+                (memq number gnus-newsgroup-sparse)
+                (zerop children))
+           ;; If we use expunging, and this article is really
+           ;; low-scored, then we don't want this article.
+           (when (and gnus-summary-expunge-below
+                      (< (setq score
+                               (or (cdr (assq number gnus-newsgroup-scored))
+                                   gnus-summary-default-score))
+                         gnus-summary-expunge-below))
+             ;; We increase the expunge-tally here, but that has
+             ;; nothing to do with the limits, really.
+             (incf gnus-newsgroup-expunged-tally)
+             ;; We also mark as read here, if that's wanted.
+             (when (and gnus-summary-mark-below
+                        (< score gnus-summary-mark-below))
+               (setq gnus-newsgroup-unreads
+                     (delq number gnus-newsgroup-unreads))
+               (if gnus-newsgroup-auto-expire
+                   (push number gnus-newsgroup-expirable)
+                 (push (cons number gnus-low-score-mark)
+                       gnus-newsgroup-reads)))
+             t)
+           ;; Check NoCeM things.
+           (and gnus-use-nocem
+                (gnus-nocem-unwanted-article-p
+                 (mail-header-id (car thread))))))
          ;; Nope, invisible article.
          0
        ;; Ok, this article is to be visible, so we add it to the limit
@@ -5445,41 +5461,46 @@ fetch-old-headers verbiage, and so on."
 
 (defun gnus-summary-refer-parent-article (n)
   "Refer parent article N times.
+If N is negative, go to ancestor -N instead.
 The difference between N and the number of articles fetched is returned."
   (interactive "p")
   (gnus-set-global-variables)
-  (while
-      (and
-       (> n 0)
-       (let* ((header (gnus-summary-article-header))
-             (ref
-              ;; If we try to find the parent of the currently
-              ;; displayed article, then we take a look at the actual
-              ;; References header, since this is slightly more
-              ;; reliable than the References field we got from the
-              ;; server.
-              (if (and (eq (mail-header-number header)
-                           (cdr gnus-article-current))
-                       (equal gnus-newsgroup-name
-                              (car gnus-article-current)))
-                  (save-excursion
-                    (set-buffer gnus-original-article-buffer)
-                    (nnheader-narrow-to-headers)
-                    (prog1
-                        (message-fetch-field "references")
-                      (widen)))
-                ;; It's not the current article, so we take a bet on
-                ;; the value we got from the server.
-                (mail-header-references header))))
-        (if (setq ref (or ref (mail-header-references header)))
-            (or (gnus-summary-refer-article (gnus-parent-id ref))
-                (gnus-message 1 "Couldn't find parent"))
-          (gnus-message 1 "No references in article %d"
-                        (gnus-summary-article-number))
-          nil)))
-    (setq n (1- n)))
-  (gnus-summary-position-point)
-  n)
+  (let ((skip 1)
+       error header ref)
+    (when (not (natnump n))
+      (setq skip (abs n)
+           n 1))
+    (while (and (> n 0)
+               (not error))
+      (setq header (gnus-summary-article-header))
+      (setq ref
+           ;; If we try to find the parent of the currently
+           ;; displayed article, then we take a look at the actual
+           ;; References header, since this is slightly more
+           ;; reliable than the References field we got from the
+           ;; server.
+           (if (and (eq (mail-header-number header)
+                        (cdr gnus-article-current))
+                    (equal gnus-newsgroup-name
+                           (car gnus-article-current)))
+               (save-excursion
+                 (set-buffer gnus-original-article-buffer)
+                 (nnheader-narrow-to-headers)
+                 (prog1
+                     (message-fetch-field "references")
+                   (widen)))
+             ;; It's not the current article, so we take a bet on
+             ;; the value we got from the server.
+             (mail-header-references header)))
+      (if ref 
+         (unless (gnus-summary-refer-article (gnus-parent-id ref skip))
+           (gnus-message 1 "Couldn't find parent"))
+       (gnus-message 1 "No references in article %d"
+                     (gnus-summary-article-number))
+       (setq error t))
+      (decf n))
+    (gnus-summary-position-point)
+    n))
 
 (defun gnus-summary-refer-references ()
   "Fetch all articles mentioned in the References header.
@@ -5761,7 +5782,7 @@ article.  If BACKWARD (the prefix) is non-nil, search backward instead."
       (gnus-message 6 "Executing %s..." (key-description command))
       ;; We'd like to execute COMMAND interactively so as to give arguments.
       (gnus-execute header regexp
-                   `(lambda () (call-interactively ',(key-binding command)))
+                   `(call-interactively ',(key-binding command))
                    backward)
       (gnus-message 6 "Executing %s...done" (key-description command)))))
 
@@ -6161,6 +6182,20 @@ latter case, they will be copied into the relevant groups."
       (gnus-request-accept-article group nil t)
       (kill-buffer (current-buffer)))))
 
+(defun gnus-summary-article-posted-p ()
+  "Say whether the current (mail) article is available from `gnus-select-method' as well.
+This will be the case if the article has both been mailed and posted."
+  (interactive)
+  (let ((id (mail-header-references (gnus-summary-article-header)))
+       (gnus-override-method
+        (or gnus-refer-article-method gnus-select-method)))
+    (if (gnus-request-head id "")
+       (gnus-message 2 "The current message was found on %s"
+                     gnus-override-method)
+      (gnus-message 2 "The current message couldn't be found on %s"
+                   gnus-override-method)
+      nil)))
+
 (defun gnus-summary-expire-articles (&optional now)
   "Expire all articles that are marked as expirable in the current group."
   (interactive)
@@ -6932,7 +6967,8 @@ The number of articles marked as read is returned."
                   "Mark all unread articles as read? ")))
        (if (and not-mark
                 (not gnus-newsgroup-adaptive)
-                (not gnus-newsgroup-auto-expire))
+                (not gnus-newsgroup-auto-expire)
+                (not gnus-suppress-duplicates))
            (progn
              (when all
                (setq gnus-newsgroup-marked nil
@@ -7765,15 +7801,15 @@ save those articles instead."
             ;; Fix by Mike Dugan <dugan@bucrf16.bu.edu>.
             (from (if (get-text-property beg gnus-mouse-face-prop) 
                       beg
-                    (1+ (or (next-single-property-change 
-                             beg gnus-mouse-face-prop nil end) 
-                            beg))))
+                    (or (next-single-property-change 
+                         beg gnus-mouse-face-prop nil end) 
+                        beg)))
             (to
              (if (= from end)
                  (- from 2)
-               (1- (or (next-single-property-change
-                        from gnus-mouse-face-prop nil end)
-                       end)))))
+               (or (next-single-property-change
+                    from gnus-mouse-face-prop nil end)
+                   end))))
        ;; If no mouse-face prop on line we will have to = from = end,
        ;; so we highlight the entire line instead.
        (when (= (+ to 2) from)
index 2d6cbbd..fd27326 100644 (file)
@@ -53,6 +53,9 @@ with some simple extensions.
 (defvar gnus-topic-indent-level 2
   "*How much each subtopic should be indented.")
 
+(defvar gnus-topic-display-empty-topics t
+  "*If non-nil, display the topic lines even of topics that have no unread articles.")
+
 ;; Internal variables.
 
 (defvar gnus-topic-active-topology nil)
@@ -413,7 +416,9 @@ articles in the topic and its subtopics."
        (incf unread (car entry))))
     (goto-char beg)
     ;; Insert the topic line.
-    (unless silent
+    (when (and (not silent)
+              (or gnus-topic-display-empty-topics
+                  (not (zerop unread))))
       (gnus-extent-start-open (point))
       (gnus-topic-insert-topic-line 
        (car type) visiblep
index d6bb699..8fc3812 100644 (file)
@@ -407,11 +407,11 @@ jabbering all the time.")
        (sit-for duration))))
   nil)
 
-(defun gnus-parent-id (references)
-  "Return the last Message-ID in REFERENCES."
-  (when (and references
-            (string-match "\\(<[^\n<>]+>\\)[ \t\n]*\\'" references))
-    (substring references (match-beginning 1) (match-end 1))))
+(defun gnus-parent-id (references &optional n)
+  "Return the last Message-ID in REFERENCES.
+If N, return the Nth ancestor instead."
+  (let ((ids (gnus-split-references references)))
+    (car (last ids (or n 1)))))
 
 (defun gnus-split-references (references)
   "Return a list of Message-IDs in REFERENCES."
@@ -524,6 +524,16 @@ Timezone package is used."
   "Turn off edit meny in `gnus-TYPE-mode-map'."
   (define-key (symbol-value (intern (format "gnus-%s-mode-map" type)))
     [menu-bar edit] 'undefined))
+
+(defun gnus-prin1 (form)
+  "Use `prin1' on FORM in the current buffer.
+Bind `print-quoted' to t while printing."
+  (let ((print-quoted t))
+    (prin1 form (current-buffer))))
+
+(defun gnus-prin1-to-string (form)
+  "The same as `prin1', but but `print-quoted' to t."
+  (prin1-to-string form))
  
 (provide 'gnus-util)
 
index 1f2679c..51fb590 100644 (file)
@@ -28,7 +28,7 @@
 
 (eval '(run-hooks 'gnus-load-hook))
 
-(defconst gnus-version-number "0.13"
+(defconst gnus-version-number "0.14"
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Red Gnus v%s" gnus-version-number)
index 2c8abc9..4f3dc08 100644 (file)
@@ -1659,7 +1659,7 @@ the user from the mailer."
               (if (or
                    (not 
                     (string-match
-                     "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-.a-zA-Z0-9]+\\)*\\'"
+                     "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-+_&.a-zA-Z0-9]+\\)*\\'"
                      header))
                    (memq 
                     nil (mapcar 
index 4f299eb..c3c0266 100644 (file)
                         (car active) (cdr active) group))))))
 
 (deffoo nnbabyl-request-scan (&optional group server)
+  (nnbabyl-possibly-change-newsgroup group server)
   (nnbabyl-read-mbox)
   (nnmail-get-new-mail 
    'nnbabyl 
        (save-excursion
         (while (re-search-backward "^X-Gnus-Newsgroup: " beg t)
           (delete-region (point) (progn (forward-line 1) (point)))))
-       (let ((nnmail-split-methods
-             (if (stringp group) (list (list group "")) 
-               nnmail-split-methods)))
-        (setq result (car (nnbabyl-save-mail))))
+       (setq result (car (nnbabyl-save-mail
+                         (if (stringp group)
+                             (list (cons group (nnbabyl-active-number group)))
+                           (nnmail-article-group 'nnbabyl-active-number)))))
        (set-buffer nnbabyl-mbox-buffer)
        (goto-char (point-max))
        (search-backward "\n\^_")
        (insert (format "Lines: %d\n" lines))
        chars))))
 
-(defun nnbabyl-save-mail ()
+(defun nnbabyl-save-mail (group-art)
   ;; Called narrowed to an article.
-  (let ((group-art (nreverse (nnmail-article-group 'nnbabyl-active-number))))
-    (nnbabyl-insert-lines)
-    (nnmail-insert-xref group-art)
-    (nnbabyl-insert-newsgroup-line group-art)
-    (run-hooks 'nnbabyl-prepare-save-mail-hook)
-    group-art))
+  (nnbabyl-insert-lines)
+  (nnmail-insert-xref group-art)
+  (nnbabyl-insert-newsgroup-line group-art)
+  (run-hooks 'nnbabyl-prepare-save-mail-hook)
+  group-art)
 
 (defun nnbabyl-insert-newsgroup-line (group-art)
   (save-excursion
            (save-excursion
              (save-restriction
                (narrow-to-region (goto-char start) end)
-               (nnbabyl-save-mail)
+               (nnbabyl-save-mail 
+                (nnmail-article-group 'nnbabyl-active-number))
                (setq end (point-max)))))
          (goto-char (setq start end)))
        (when (buffer-modified-p (current-buffer))
              (delete-region (progn (beginning-of-line) (point))
                             (progn (forward-line 1) (point)))
              (nnheader-message 7 "Moving %s..." id)
-             (nnbabyl-save-mail))
+             (nnbabyl-save-mail
+              (nnmail-article-group 'nnbabyl-active-number)))
          (intern id idents)))
       (when (buffer-modified-p (current-buffer))
        (save-buffer))
index fdd3a0a..8c62d70 100644 (file)
 If FORCE, delete regardless of exiration date, otherwise use normal
 expiry mechanism."
   (let (msg art)
-    (nntp-possibly-change-server group server) ;;-
+    (nntp-possibly-change-group group server) ;;-
     (while articles
       (setq art (pop articles))
       (nntp-send-command "^\\([23]\\|^423\\).*\n" "DATE" art)
@@ -183,15 +183,12 @@ Optional LAST is ignored."
   
 (deffoo nndb-request-accept-article (group server &optional last)
   "The article in the current buffer is put into GROUP."
-  (nntp-possibly-change-server group server) ;;-
+  (nntp-possibly-change-group group server) ;;-
   (let (art statmsg)
     (when (nntp-send-command "^[23].*\r?\n" "ACCEPT" group)
       (nnheader-insert "")
       (nntp-encode-text)
-      (nntp-send-region-to-server (point-min) (point-max))
-      ;; 1.2a NNTP's post command is buggy. "^M" (\r) is not
-      ;;  appended to end of the status message.
-      (nntp-wait-for-response "^[23].*\n")
+      (nntp-send-buffer "^[23].*\n")
       (setq statmsg (nntp-status-message))
       (or (string-match "^\\([0-9]+\\)" statmsg)
           (error "nndb: %s" statmsg))
@@ -209,10 +206,7 @@ with the contents of the BUFFER."
     (when (nntp-send-command "^[23].*\r?\n" "REPLACE" (int-to-string article))
       (nnheader-insert "")
       (nntp-encode-text)
-      (nntp-send-region-to-server (point-min) (point-max))
-      ;; 1.2a NNTP's post command is buggy. "^M" (\r) is not
-      ;;  appended to end of the status message.
-      (nntp-wait-for-response "^[23].*\n")
+      (nntp-send-buffer "^[23].*\n")
 ;      (setq statmsg (nntp-status-message))
 ;      (or (string-match "^\\([0-9]+\\)" statmsg)
 ;          (error "nndb: %s" statmsg))
index 560a8bc..e69de29 100644 (file)
@@ -1,286 +0,0 @@
-;;; nndejagnus.el --- retrieving articles via DejaNews
-;; Copyright (C) 1996 Free Software Foundation, Inc.
-
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
-;; Keywords: news
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs 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.
-
-;; 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., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; Note: You need to have `url' and `w3' installed for this
-;; backend to work.
-
-;;; Code:
-
-(require 'nnoo)
-(require 'message)
-(require 'gnus-util)
-(require 'w3-forms)
-(require 'url)
-
-(nnoo-declare nndejagnus)
-
-(defvoo nndejagnus-address "http://www.dejagnus.com/"
-  "Base URL of the DejaNews search engine.")
-
-(defvoo nndejagnus-search nil
-  "Search string to feed to DejaNews.")
-
-(defvoo nndejagnus-max-hits 100
-  "Maximum number of hits to display.")
-
-;;; Internal variables
-
-(defvoo nndejagnus-articles nil)
-(defvoo nndejagnus-buffer nil)
-(defvoo nndejagnus-async-buffer nil)
-(defvar nndejagnus-callback-function nil)
-(defvar nndejagnus-to-buffer nil)
-(defvar nndejagnus-start-point nil)
-(defvar nndejagnus-inside-change-function nil)
-
-;;; Interface functions
-
-(nnoo-define-basics nndejagnus)
-
-(deffoo nndejagnus-retrieve-headers (articles &optional group server fetch-old)
-  (nndejagnus-possibly-change-server server)
-  (save-excursion
-    (set-buffer nntp-server-buffer)
-    (erase-buffer)
-    (let (article header)
-      (while (setq article (pop articles))
-       (when (setq header (cadr (assq article nndejagnus-articles)))
-         (nnheader-insert-nov header)))
-      'nov)))
-
-(deffoo nndejagnus-request-group (group &optional server dont-check)
-  (nndejagnus-possibly-change-server server)
-  (when (or (not dont-check)
-           (not nndejagnus-articles))
-    (nndejagnus-create-mapping group))
-  (cond
-   ((not nndejagnus-articles)
-    (nnheader-report 'nndejagnus "Couldn't request search"))
-   (t
-    (nnheader-report 'nndejagnus "Opened group %s" group)
-    (nnheader-insert
-     "211 %d %d %d %s\n" (length nndejagnus-articles)
-     (caar nndejagnus-articles) (caar (last nndejagnus-articles))
-      group))))
-
-(deffoo nndejagnus-request-article (article &optional group server buffer)
-  (nndejagnus-possibly-change-server server)
-  (save-excursion
-    (set-buffer (or buffer nntp-server-buffer))
-    (let ((url (caddr (assq article nndejagnus-articles))))
-      (when (and url
-                (nndejagnus-fetch-url url))
-       (unless nnheader-callback-function
-         (nndejagnus-decode-article)
-         (nndejagnus-decode-entities))
-       (nnheader-report 'nndejagnus "Fetched article %s" article)
-       t))))
-
-(deffoo nndejagnus-close-server (&optional server)
-  (when (nndejagnus-server-opened server)
-    (gnus-kill-buffer nndejagnus-buffer))
-  (nnoo-close-server 'nndejagnus server))
-
-(deffoo nndejagnus-request-update-info (group info &optional server)
-  (nndejagnus-possibly-change-server server)
-  (setcar (cddr info) nil))
-
-(deffoo nndejagnus-asynchronous-p ()
-  t)
-
-(nnoo-define-skeleton nndejagnus)
-
-;;; Internal functions
-
-(defun nndejagnus-possibly-change-server (&optional server)
-  (nndejagnus-init server)
-  (when server
-    (unless (nndejagnus-server-opened server)
-      (nndejagnus-open-server server))))
-
-(defun nndejagnus-init (server)
-  "Initialize buffers and such."
-  (unless (gnus-buffer-live-p nndejagnus-buffer)
-    (setq nndejagnus-buffer
-         (save-excursion
-           (nnheader-set-temp-buffer
-            (format " *nndejagnus %s*" server))))))
-
-(defun nndejagnus-create-mapping (group)
-  "Perform the search and create an number-to-url alist."
-  (save-excursion
-    (set-buffer nndejagnus-buffer)
-    (erase-buffer)
-    (when (nndejagnus-fetch-search nndejagnus-search)
-      (let ((i 0)
-           (more t)
-           Subject Score Date Newsgroup Author
-           map url)
-       (while more
-         ;; Go through all the article hits on this page.
-         (goto-char (point-min))
-         (nndejagnus-decode-entities)
-         (goto-char (point-min))
-         (while (re-search-forward "^ +[0-9]+\\." nil t)
-           (narrow-to-region 
-            (point) 
-            (if (re-search-forward "^ +[0-9]+\\." nil t)
-                (match-beginning 0)
-              (point-max)))
-           (goto-char (point-min))
-           (when (looking-at ".*HREF=\"\\([^\"]+\\)\"")
-             (setq url (match-string 1)))
-           (while (re-search-forward "<[^>]+>" nil t)
-             (replace-match "" t t))
-           (goto-char (point-min))
-           (while (search-forward "\t" nil t)
-             (replace-match " "))
-           (goto-char (point-min))
-           (while (re-search-forward "^ +\\([^:]+\\): +\\(.*\\)$" nil t)
-             (set (intern (match-string 1)) (match-string 2)))
-           (widen)
-           (when (string-match "#[0-9]+/[0-9]+ *$" Subject)
-             (setq Subject (substring Subject 0 (match-beginning 0))))
-           (push
-            (list
-             (incf i)
-             (make-full-mail-header
-              i (concat  "(" Newsgroup ") " Subject) Author Date
-              (concat "<" (message-unique-id) "-" (int-to-string i)
-                      "@dejanews>")
-              nil 0 (string-to-int Score) nil)
-             url)
-            map))
-         ;; See whether there is a "Get next 20 hits" button here.
-         (if (or (not (re-search-forward
-                       "HREF=\"\\([^\"]+\\)\">Get next" nil t))
-                 (> i nndejagnus-max-hits))
-             (setq more nil)
-           ;; Yup -- fetch it.
-           (setq more (match-string 1))
-           (erase-buffer)
-           (url-insert-file-contents more)))
-       ;; Return the articles in the right order.
-       (setq nndejagnus-articles (nreverse map))))))
-
-(defun nndejagnus-fetch-url (url)
-  (save-excursion
-    (if (not nnheader-callback-function)
-       (let ((buf (current-buffer)))
-         (save-excursion
-           (set-buffer nndejagnus-buffer)
-           (erase-buffer)
-           (prog1
-               (url-insert-file-contents url)
-             (copy-to-buffer buf (point-min) (point-max)))))
-      (nndejagnus-url-retrieve-asynch
-       url 'nndejanews-callback (current-buffer) nnheader-callback-function)
-      t)))
-
-(defun nndejanews-callback (buffer callback)
-  (save-excursion
-    (set-buffer url-working-buffer)
-    (nndejagnus-decode-article)
-    (nndejagnus-decode-entities)
-    (set-buffer buffer)
-    (goto-char (point-max))
-    (insert-buffer-substring url-working-buffer))
-  (funcall callback t)
-  (gnus-kill-buffer url-working-buffer))
-
-(defun nndejagnus-url-retrieve-asynch (url callback &rest data)
-  (let ((url-request-method "GET")
-       (old-asynch url-be-asynchronous)
-       (url-request-data nil)
-       (url-request-extra-headers nil)
-       (url-working-buffer (generate-new-buffer-name " *dejanews*")))
-    (setq-default url-be-asynchronous t)
-    (save-excursion
-      (set-buffer (get-buffer-create url-working-buffer))
-      (setq url-current-callback-data data
-           url-be-asynchronous t
-           url-current-callback-func callback)
-      (url-retrieve url))
-    (setq-default url-be-asynchronous old-asynch)))
-
-(defun nndejagnus-decode-article ()
-  (goto-char (point-min))
-  (re-search-forward "<PRE>" nil t)
-  (delete-region (point-min) (point))
-  (re-search-forward "</PRE>" nil t)
-  (delete-region (point) (point-max))
-  (goto-char (point-min))
-  (while (re-search-forward "<[^>]+>" nil t)
-    (replace-match "" t t))
-  (goto-char (point-min))
-  (while (looking-at " *$")
-    (gnus-delete-line))
-  (while (looking-at "\\(^[^ ]+:\\) *")
-    (replace-match "\\1 " t)
-    (forward-line 1))
-  (when (re-search-forward "\n\n+" nil t)
-    (replace-match "\n" t t)))
-
-(defun nndejagnus-encode-www-form-urlencoded (pairs)
-  "Return PAIRS encoded for forms."
-  (mapconcat 
-    (function
-      (lambda (data)
-        (concat (w3-form-encode-xwfu (car data)) "="
-                (w3-form-encode-xwfu (cdr data))))) pairs "&"))
-
-(defun nndejagnus-fetch-form (url pairs)
-  (let ((url-request-data (nndejagnus-encode-www-form-urlencoded pairs))
-       (url-request-method 'POST)
-       (url-request-extra-headers 
-        '(("Content-type" . "application/x-www-form-urlencoded"))))
-    (url-insert-file-contents url)))
-
-(defun nndejagnus-fetch-search (search)
-  (nndejagnus-fetch-form 
-   "http://xp6.dejanews.com/dnquery.xp"
-   `(("query" . ,search)
-     ("defaultOp" . "AND")
-     ("svcclass" . "dncurrent")
-     ("maxhits" . "25")
-     ("format" . "verbose")
-     ("threaded" . "0")
-     ("showsort" . "score")
-     ("agesign" . "1")
-     ("ageweight" . "1"))))
-
-(defun nndejagnus-decode-entities ()
-  (goto-char (point-min))
-  (while (re-search-forward "&\\([a-z]+\\);" nil t)
-    (replace-match (char-to-string (or (cdr (assq (intern (match-string 1))
-                                                 w3-html-entities ))
-                                      ?#))
-                  t t)))
-
-;              "^ +\\([0-9]+\\)\\. +\\([0-9]+\\)/+\\([0-9]+\\)/+\\([0-9]+\\) +\\([0-9]+\\).+HREF=\"\\([^\"]+\\)\">\\([^<]+\\)<.*<B> *\\(.*\\)</B>.+>\\([^<>]+\\)</A> *$"
-
-(provide 'nndejagnus)
-
-;;; nndejagnus.el ends here
index bcf013f..60626b4 100644 (file)
@@ -245,13 +245,12 @@ If this variable is nil, no files will be excluded.")
       (setq files (cdr files)))
     (when (and touched 
               (not nneething-read-only))
-      (save-excursion
-       (nnheader-set-temp-buffer " *nneething map*")
-       (insert "(setq nneething-map '" (prin1-to-string nneething-map) ")\n"
-               "(setq nneething-active '" (prin1-to-string nneething-active)
-               ")\n")
-       (write-region (point-min) (point-max) map-file nil 'nomesg)
-       (kill-buffer (current-buffer))))))
+      (nnheader-temp-write map-file
+       (insert "(setq nneething-map '")
+       (gnus-prin1 nneething-map)
+       (insert ")\n(setq nneething-active '")
+       (gnus-prin1 nneething-active)
+       (insert ")\n")))))
 
 (defun nneething-insert-head (file)
   "Insert the head of FILE."
index 558ac21..ea72817 100644 (file)
@@ -388,7 +388,11 @@ time saver for large mailboxes.")
        (forward-line -1)
        (while (re-search-backward (concat "^" nnfolder-article-marker) nil t)
         (delete-region (point) (progn (forward-line 1) (point))))
-       (setq result (car (nnfolder-save-mail (and (stringp group) group)))))
+       (setq result
+            (car (nnfolder-save-mail
+                  (if (stringp group)
+                      (list (cons group (nnfolder-active-number group)))
+                    (nnmail-article-group 'nnfolder-active-number))))))
      (save-excursion
        (set-buffer nnfolder-current-buffer)
        (and last (nnfolder-save-buffer))))
@@ -538,13 +542,9 @@ time saver for large mailboxes.")
                            nnfolder-buffer-alist))))))))
     (setq nnfolder-current-group group)))
 
-(defun nnfolder-save-mail (&optional group)
+(defun nnfolder-save-mail (group-art-list)
   "Called narrowed to an article."
-  (let* ((nnmail-split-methods 
-         (if group (list (list group "")) nnmail-split-methods))
-        (group-art-list
-         (nreverse (nnmail-article-group 'nnfolder-active-number)))
-        (delim (concat "^" message-unix-mail-delimiter))
+  (let* ((delim (concat "^" message-unix-mail-delimiter))
         save-list group-art)
     (goto-char (point-min))
     ;; The From line may have been quoted by movemail.
index b6ec28e..594052a 100644 (file)
@@ -324,13 +324,10 @@ Finds out what articles are to be part of the nnkiboze groups."
     (save-buffer)
     (kill-buffer (current-buffer))
     ;; We save the kiboze newsrc for this group.
-    (set-buffer (get-buffer-create "*nnkiboze work*"))
-    (buffer-disable-undo (current-buffer))
-    (erase-buffer)
-    (insert "(setq nnkiboze-newsrc '" (prin1-to-string nnkiboze-newsrc)
-           ")\n")
-    (write-file newsrc-file)
-    (kill-buffer (current-buffer))
+    (nnheader-temp-write newsrc-file
+      (insert "(setq nnkiboze-newsrc '")
+      (gnus-prin1 nnkiboze-newsrc)
+      (insert ")\n"))
     (switch-to-buffer gnus-group-buffer)
     (gnus-group-list-groups 5 nil)))
     
index d9cd825..a27464a 100644 (file)
@@ -184,6 +184,12 @@ The hook is run in a buffer with all the new, incoming mail.")
 (defvar nnmail-post-get-new-mail-hook nil
   "Hook called just after finishing handling new incoming mail.")
 
+(defvar nnmail-split-hook nil
+  "Hook called before deciding where to split an article.
+The functions in this hook are free to modify the buffer
+contents in any way they choose -- the buffer contents are
+discarded after running the split process.")
+
 ;; Suggested by Mejia Pablo J <pjm9806@usl.edu>.
 (defvar nnmail-tmp-directory nil
   "*If non-nil, use this directory for temporary storage when reading incoming mail.")
@@ -280,7 +286,6 @@ parameter.  It should return nil, `warn' or `delete'.")
   ;; support the %-hack
   (modify-syntax-entry ?\% "." nnmail-split-fancy-syntax-table))
 
-
 (defvar nnmail-prepare-save-mail-hook nil
   "Hook called before saving mail.")
 
@@ -434,22 +439,29 @@ parameter.  It should return nil, `warn' or `delete'.")
                    (list nnmail-internal-password)))))
              (if (not (buffer-modified-p errors))
                  ;; No output => movemail won
-                 (push inbox nnmail-moved-inboxes)
+                 (progn
+                   (set-file-modes inbox nnmail-default-file-modes)
+                   (push inbox nnmail-moved-inboxes))
                (set-buffer errors)
                ;; There may be a warning about older revisions.  We
                ;; ignore those.
                (goto-char (point-min))
                (if (search-forward "older revision" nil t)
-                   (push inbox nnmail-moved-inboxes)
+                   (progn
+                     (set-file-modes inbox nnmail-default-file-modes)
+                     (push inbox nnmail-moved-inboxes))
                  ;; Probably a real error.
                  (subst-char-in-region (point-min) (point-max) ?\n ?\  )
                  (goto-char (point-max))
                  (skip-chars-backward " \t")
                  (delete-region (point) (point-max))
                  (goto-char (point-min))
-                 (if (looking-at "movemail: ")
-                     (delete-region (point-min) (match-end 0)))
-                 (error (concat "movemail: " (buffer-string)))
+                 (when (looking-at "movemail: ")
+                   (delete-region (point-min) (match-end 0)))
+                 (unless (yes-or-no-p
+                          (format "movemail: %s.  Continue? "
+                                  (buffer-string)))
+                   (error "%s" (buffer-string)))
                  (setq tofile nil)))))))
       (and errors
           (buffer-name errors)
@@ -506,7 +518,7 @@ nn*-request-list should have been called before calling this function."
             group))
     group))
 
-(defun nnmail-process-babyl-mail-format (func)
+(defun nnmail-process-babyl-mail-format (func artnum-func)
   (let ((case-fold-search t)
        start message-id content-length do-search end)
     (while (not (eobp))
@@ -566,7 +578,7 @@ nn*-request-list should have been called before calling this function."
        (save-restriction
          (narrow-to-region start (point))
          (goto-char (point-min))
-         (nnmail-check-duplication message-id func)
+         (nnmail-check-duplication message-id func artnum-func)
          (setq end (point-max))))
       (goto-char end))))
 
@@ -585,7 +597,7 @@ nn*-request-list should have been called before calling this function."
        (setq found 'no)))
     (eq found 'yes)))
 
-(defun nnmail-process-unix-mail-format (func)
+(defun nnmail-process-unix-mail-format (func artnum-func)
   (let ((case-fold-search t)
        (delim (concat "^" message-unix-mail-delimiter))
        start message-id content-length end skip head-end)
@@ -666,11 +678,11 @@ nn*-request-list should have been called before calling this function."
          (save-restriction
            (narrow-to-region start (point))
            (goto-char (point-min))
-           (nnmail-check-duplication message-id func)
+           (nnmail-check-duplication message-id func artnum-func)
            (setq end (point-max))))
        (goto-char end)))))
 
-(defun nnmail-process-mmdf-mail-format (func)
+(defun nnmail-process-mmdf-mail-format (func artnum-func)
   (let ((delim "^\^A\^A\^A\^A$")
        (case-fold-search t)
        start message-id end)
@@ -715,12 +727,13 @@ nn*-request-list should have been called before calling this function."
          (save-restriction
            (narrow-to-region start (point))
            (goto-char (point-min))
-           (nnmail-check-duplication message-id func)
+           (nnmail-check-duplication message-id func artnum-func)
            (setq end (point-max))))
        (goto-char end)
        (forward-line 2)))))
 
-(defun nnmail-split-incoming (incoming func &optional exit-func group)
+(defun nnmail-split-incoming (incoming func &optional exit-func
+                                      group artnum-func)
   "Go through the entire INCOMING file and pick out each individual mail.
 FUNC will be called with the buffer narrowed to each mail."
   (let (;; If this is a group-specific split, we bind the split
@@ -745,11 +758,11 @@ FUNC will be called with the buffer narrowed to each mail."
        ;; fetches from a file.
        (cond ((or (looking-at "\^L")
                   (looking-at "BABYL OPTIONS:"))
-              (nnmail-process-babyl-mail-format func))
+              (nnmail-process-babyl-mail-format func artnum-func))
              ((looking-at "\^A\^A\^A\^A")
-              (nnmail-process-mmdf-mail-format func))
+              (nnmail-process-mmdf-mail-format func artnum-func))
              (t
-              (nnmail-process-unix-mail-format func))))
+              (nnmail-process-unix-mail-format func artnum-func))))
       (if exit-func (funcall exit-func))
       (kill-buffer (current-buffer)))))
 
@@ -779,6 +792,8 @@ FUNC will be called with the group name to determine the article number."
        (goto-char (point-min))
        (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
          (replace-match " " t t))
+       ;; Allow washing.
+       (run-hooks 'nnmail-split-hook)
        (if (and (symbolp nnmail-split-methods)
                 (fboundp nnmail-split-methods))
            ;; `nnmail-split-methods' is a function, so we just call 
@@ -818,7 +833,10 @@ FUNC will be called with the group name to determine the article number."
                (setq group-art 
                      (list (cons (car method) 
                                  (funcall func (car method)))))))))
-       group-art))))
+       ;; See whether the split methods returned `junk'.
+       (if (equal group-art '(junk))
+           nil
+         (nreverse (delq 'junk group-art)))))))
 
 (defun nnmail-insert-lines ()
   "Insert how many lines there are in the body of the mail.
@@ -878,42 +896,44 @@ See the documentation for the variable `nnmail-split-fancy' for documentation."
 
 (defun nnmail-split-it (split)
   ;; Return a list of groups matching SPLIT.
-  (cond ((stringp split)
-        ;; A group.
-        (list split))
-       ((eq (car split) '&)
-        (apply 'nconc (mapcar 'nnmail-split-it (cdr split))))
-       ((eq (car split) '|)
-        (let (done)
-          (while (and (not done) (cdr split))
-            (setq split (cdr split)
-                  done (nnmail-split-it (car split))))
-          done))
-       ((assq split nnmail-split-cache)
-        ;; A compiled match expression.
-        (goto-char (point-max))
-        (if (re-search-backward (cdr (assq split nnmail-split-cache)) nil t)
-            (nnmail-split-it (nth 2 split))))
-       (t
-        ;; An uncompiled match.
-        (let* ((field (nth 0 split))
-               (value (nth 1 split))
-               (regexp (concat "^\\(" 
-                               (if (symbolp field)
-                                   (cdr (assq field 
-                                              nnmail-split-abbrev-alist))
-                                 field)
-                               "\\):.*\\<\\("
-                               (if (symbolp value)
-                                   (cdr (assq value
-                                              nnmail-split-abbrev-alist))
-                                 value)
-                               "\\)\\>")))
-          (setq nnmail-split-cache 
-                (cons (cons split regexp) nnmail-split-cache))
-          (goto-char (point-max))
-          (if (re-search-backward regexp nil t)
-              (nnmail-split-it (nth 2 split)))))))
+  (cond
+   ((stringp split)
+    ;; A group.
+    (list split))
+   ((eq split 'junk)
+    ;; Junk this.
+    (list 'junk))
+   ((eq (car split) '&)
+    (apply 'nconc (mapcar 'nnmail-split-it (cdr split))))
+   ((eq (car split) '|)
+    (let (done)
+      (while (and (not done) (cdr split))
+       (setq split (cdr split)
+             done (nnmail-split-it (car split))))
+      done))
+   ((assq split nnmail-split-cache)
+    ;; A compiled match expression.
+    (goto-char (point-max))
+    (if (re-search-backward (cdr (assq split nnmail-split-cache)) nil t)
+       (nnmail-split-it (nth 2 split))))
+   (t
+    ;; An uncompiled match.
+    (let* ((field (nth 0 split))
+          (value (nth 1 split))
+          (regexp (concat "^\\(" 
+                          (if (symbolp field)
+                              (cdr (assq field nnmail-split-abbrev-alist))
+                            field)
+                          "\\):.*\\<\\("
+                          (if (symbolp value)
+                              (cdr (assq value nnmail-split-abbrev-alist))
+                            value)
+                          "\\)\\>")))
+      (setq nnmail-split-cache 
+           (cons (cons split regexp) nnmail-split-cache))
+      (goto-char (point-max))
+      (if (re-search-backward regexp nil t)
+         (nnmail-split-it (nth 2 split)))))))
 
 ;; Get a list of spool files to read.
 (defun nnmail-get-spool-files (&optional group)
@@ -1056,7 +1076,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation."
       (goto-char (point-max))
       (search-backward id nil t))))
 
-(defun nnmail-check-duplication (message-id func)
+(defun nnmail-check-duplication (message-id func artnum-func)
   ;; If this is a duplicate message, then we do not save it.
   (let* ((duplication (nnmail-cache-id-exists-p message-id))
         (action (when duplication
@@ -1066,11 +1086,14 @@ See the documentation for the variable `nnmail-split-fancy' for documentation."
                    ((nnheader-functionp nnmail-treat-duplicates)
                     (funcall nnmail-treat-duplicates message-id))
                    (t
-                    nnmail-treat-duplicates)))))
+                    nnmail-treat-duplicates))))
+        (group-art (nreverse (nnmail-article-group artnum-func))))
     (cond
+     ((null group-art)
+      (delete-region (point-min) (point-max)))
      ((not duplication)
       (nnmail-cache-insert message-id)
-      (funcall func))
+      (funcall func group-art))
      ((eq action 'delete)
       (delete-region (point-min) (point-max)))
      ((eq action 'warn)
@@ -1086,9 +1109,9 @@ See the documentation for the variable `nnmail-split-fancy' for documentation."
         "Message-ID: " newid "\n"
         "Gnus-Warning: This is a duplicate of message " message-id "\n")
        (nnmail-cache-insert newid)
-       (funcall func)))
+       (funcall func group-art)))
      (t
-      (funcall func)))))
+      (funcall func group-art)))))
 
 ;;; Get new mail.
 
@@ -1130,7 +1153,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation."
            ;; We split the mail
            (nnmail-split-incoming 
             nnmail-crash-box (intern (format "%s-save-mail" method)) 
-            spool-func group)
+            spool-func group (intern (format "%s-active-number" method)))
            ;; Check whether the inbox is to be moved to the special tmp dir. 
            (setq incoming
                  (nnmail-make-complex-temp-name 
index 01b08e6..9fdde2c 100644 (file)
                       (car active) (cdr active) group)))))
 
 (deffoo nnmbox-request-scan (&optional group server)
+  (nnmbox-possibly-change-newsgroup group server)
   (nnmbox-read-mbox)
   (nnmail-get-new-mail 
    'nnmbox 
        (forward-line -1)
        (while (re-search-backward "^X-Gnus-Newsgroup: " nil t)
         (delete-region (point) (progn (forward-line 1) (point))))
-       (setq result (nnmbox-save-mail (and (stringp group) group))))
+       (setq result (nnmbox-save-mail
+                    (if (stringp group)
+                        (list (cons group (nnmbox-active-number group)))
+                      (nnmail-article-group 'nnmbox-active-number)))))
      (save-excursion
        (set-buffer nnmbox-mbox-buffer)
        (goto-char (point-max))
               (string-to-int
                (buffer-substring (match-beginning 2) (match-end 2)))))))
 
-(defun nnmbox-save-mail (&optional group)
+(defun nnmbox-save-mail (group-art)
   "Called narrowed to an article."
-  (let* ((nnmail-split-methods 
-         (if group (list (list group "")) nnmail-split-methods))
-        (group-art (nreverse (nnmail-article-group 'nnmbox-active-number)))
-        (delim (concat "^" message-unix-mail-delimiter)))
+  (let ((delim (concat "^" message-unix-mail-delimiter)))
     (goto-char (point-min))
     ;; This might come from somewhere else.
     (unless (looking-at delim)
              (save-excursion
                (save-restriction
                  (narrow-to-region start end)
-                 (nnmbox-save-mail))))
+                 (nnmbox-save-mail 
+                  (nnmail-article-group 'nnmbox-active-number)))))
          (goto-char end))))))
 
 (provide 'nnmbox)
index cad9cb4..21bf30c 100644 (file)
   (if (stringp group)
       (and 
        (nnmail-activate 'nnmh)
-       ;; We trick the choosing function into believing that only one
-       ;; group is available.  
-       (let ((nnmail-split-methods (list (list group ""))))
-        (car (nnmh-save-mail noinsert))))
+       (car (nnmh-save-mail 
+            (list (cons group (nnmh-active-number group)))
+            noinsert)))
     (and
      (nnmail-activate 'nnmh)
-     (car (nnmh-save-mail noinsert)))))
+     (car (nnmh-save-mail (nnmail-article-group 'nnmh-active-number)
+                         noinsert)))))
 
 (deffoo nnmh-request-replace-article (article group buffer)
   (nnmh-possibly-change-directory group)
 
 (deffoo nnmh-request-create-group (group &optional server) 
   (nnmail-activate 'nnmh)
-  (or (assoc group nnmh-group-alist)
-      (let (active)
-       (setq nnmh-group-alist (cons (list group (setq active (cons 1 0)))
-                                    nnmh-group-alist))
-       (nnmh-possibly-create-directory group)
-       (nnmh-possibly-change-directory group server)
-       (let ((articles (mapcar
-                        (lambda (file)
-                          (string-to-int file))
-                        (directory-files 
-                         nnmh-current-directory nil "^[0-9]+$"))))
-         (and articles
-              (progn
-                (setcar active (apply 'min articles))
-                (setcdr active (apply 'max articles)))))))
+  (unless (assoc group nnmh-group-alist)
+    (let (active)
+      (push (list group (setq active (cons 1 0)))
+           nnmh-group-alist)
+      (nnmh-possibly-create-directory group)
+      (nnmh-possibly-change-directory group server)
+      (let ((articles (mapcar
+                      (lambda (file)
+                        (string-to-int file))
+                      (directory-files 
+                       nnmh-current-directory nil "^[0-9]+$"))))
+       (when articles
+         (setcar active (apply 'min articles))
+         (setcdr active (apply 'max articles))))))
   t)
 
 (deffoo nnmh-request-delete-group (group &optional force server)
       (nnheader-message 5 "Creating mail directory %s" (car dirs))
       (setq dirs (cdr dirs)))))
             
-(defun nnmh-save-mail (&optional noinsert)
+(defun nnmh-save-mail (group-art &optional noinsert)
   "Called narrowed to an article."
-  (let ((group-art (nreverse (nnmail-article-group 'nnmh-active-number))))
-    (unless noinsert
-      (nnmail-insert-lines)
-      (nnmail-insert-xref group-art))
-    (run-hooks 'nnmail-prepare-save-mail-hook)
-    (run-hooks 'nnmh-prepare-save-mail-hook)
-    (goto-char (point-min))
-    (while (looking-at "From ")
-      (replace-match "X-From-Line: ")
-      (forward-line 1))
-    ;; We save the article in all the newsgroups it belongs in.
-    (let ((ga group-art)
-         first)
-      (while ga
-       (nnmh-possibly-create-directory (caar ga))
-       (let ((file (concat (nnmail-group-pathname 
-                            (caar ga) nnmh-directory) 
-                           (int-to-string (cdar ga)))))
-         (if first
-             ;; It was already saved, so we just make a hard link.
-             (funcall nnmail-crosspost-link-function first file t)
-           ;; Save the article.
-           (nnmail-write-region (point-min) (point-max) file nil nil)
-           (setq first file)))
-       (setq ga (cdr ga))))
-    group-art))
+  (unless noinsert
+    (nnmail-insert-lines)
+    (nnmail-insert-xref group-art))
+  (run-hooks 'nnmail-prepare-save-mail-hook)
+  (run-hooks 'nnmh-prepare-save-mail-hook)
+  (goto-char (point-min))
+  (while (looking-at "From ")
+    (replace-match "X-From-Line: ")
+    (forward-line 1))
+  ;; We save the article in all the newsgroups it belongs in.
+  (let ((ga group-art)
+       first)
+    (while ga
+      (nnmh-possibly-create-directory (caar ga))
+      (let ((file (concat (nnmail-group-pathname 
+                          (caar ga) nnmh-directory) 
+                         (int-to-string (cdar ga)))))
+       (if first
+           ;; It was already saved, so we just make a hard link.
+           (funcall nnmail-crosspost-link-function first file t)
+         ;; Save the article.
+         (nnmail-write-region (point-min) (point-max) file nil nil)
+         (setq first file)))
+      (setq ga (cdr ga))))
+  group-art)
 
 (defun nnmh-active-number (group)
   "Compute the next article number in GROUP."
   (let ((active (cadr (assoc group nnmh-group-alist))))
-    ;; The group wasn't known to nnmh, so we just create an active
-    ;; entry for it.   
-    (or active
-       (progn
-         (setq active (cons 1 0))
-         (setq nnmh-group-alist (cons (list group active) nnmh-group-alist))))
+    (unless active
+      ;; The group wasn't known to nnmh, so we just create an active
+      ;; entry for it.   
+      (setq active (cons 1 0))
+      (push (list group active) nnmh-group-alist)
+      ;; Find the highest number in the group.
+      (let ((files (sort
+                   (mapcar
+                    (lambda (f)
+                      (string-to-int f))
+                    (directory-files
+                     (nnmail-group-pathname group nnmh-directory)
+                     nil "^[0-9]+$")
+                    '>))))
+       (when files
+         (setcdr active (car files)))))
     (setcdr active (1+ (cdr active)))
     (while (file-exists-p
            (concat (nnmail-group-pathname group nnmh-directory)
         (nnmh-file (concat dir ".nnmh-articles"))
         new articles)
     ;; Load the .nnmh-articles file.
-    (if (file-exists-p nnmh-file)
-       (setq articles 
-             (let (nnmh-newsgroup-articles)
-               (condition-case nil (load nnmh-file nil t t) (error nil))
-               nnmh-newsgroup-articles)))
+    (when (file-exists-p nnmh-file)
+      (setq articles 
+           (let (nnmh-newsgroup-articles)
+             (condition-case nil (load nnmh-file nil t t) (error nil))
+             nnmh-newsgroup-articles)))
     ;; Add all new articles to the `new' list.
     (let ((art files))
       (while art
-       (if (not (assq (car art) articles)) (setq new (cons (car art) new)))
+       (unless (assq (car art) articles)
+         (setq new (cons (car art) new)))
        (setq art (cdr art))))
     ;; Remove all deleted articles.
     (let ((art articles))
       (while art
-       (if (not (memq (caar art) files))
-           (setq articles (delq (car art) articles)))
-       (setq art (cdr art))))
-    ;; Check whether the highest-numbered articles really are the ones
-    ;; that Gnus thinks they are by looking at the time-stamps.
-    (let ((art articles))
-      (while (and art 
-                 (not (equal 
-                       (nth 5 (file-attributes 
-                               (concat dir (int-to-string (caar art)))))
-                       (cdar art))))
-       (setq articles (delq (car art) articles))
-       (setq new (cons (caar art) new))
+       (unless (memq (caar art) files)
+         (setq articles (delq (car art) articles)))
        (setq art (cdr art))))
+    ;; Check whether the articles really are the ones that Gnus thinks
+    ;; they are by looking at the time-stamps.
+    (let ((arts articles)
+         art)
+      (while (setq art (pop arts))
+       (when (not (equal
+                   (nth 5 (file-attributes 
+                           (concat dir (int-to-string (car art)))))
+                   (cdr art)))
+         (setq articles (delq art articles))
+         (push (car art) new))))
     ;; Go through all the new articles and add them, and their
-    ;; time-stamps to the list.
-    (let ((n new))
-      (while n
-       (setq articles 
-             (cons (cons 
-                    (car n)
-                    (nth 5 (file-attributes 
-                            (concat dir (int-to-string (car n))))))
-                   articles))
-       (setq n (cdr n))))
+    ;; time-stamps, to the list.
+    (setq articles
+         (nconc articles
+                (mapcar
+                 (lambda (art)
+                   (cons art
+                         (nth 5 (file-attributes
+                                 (concat dir (int-to-string art))))))
+                 new)))
     ;; Make Gnus mark all new articles as unread.
-    (or (zerop (length new))
-       (gnus-make-articles-unread 
-        (gnus-group-prefixed-name group (list 'nnmh ""))
-        (setq new (sort new '<))))
+    (when new
+      (gnus-make-articles-unread 
+       (gnus-group-prefixed-name group (list 'nnmh ""))
+       (setq new (sort new '<))))
     ;; Sort the article list with highest numbers first.
     (setq articles (sort articles (lambda (art1 art2) 
                                    (> (car art1) (car art2)))))
     ;; Finally write this list back to the .nnmh-articles file.
-    (save-excursion
-      (set-buffer (get-buffer-create "*nnmh out*"))
+    (nnheader-temp-write nnmh-file
       (insert ";; Gnus article active file for " group "\n\n")
       (insert "(setq nnmh-newsgroup-articles '")
-      (insert (prin1-to-string articles) ")\n")
-      (nnmail-write-region (point-min) (point-max) nnmh-file nil 'nomesg)
-      (kill-buffer (current-buffer)))))
+      (gnus-prin1 articles)
+      (insert ")\n"))))
 
 (defun nnmh-deletable-article-p (group article)
   "Say whether ARTICLE in GROUP can be deleted."
index a836216..dad6681 100644 (file)
@@ -322,16 +322,15 @@ all. This may very well take some time.")
     (if (stringp group)
        (and 
         (nnmail-activate 'nnml)
-        ;; We trick the choosing function into believing that only one
-        ;; group is available.  
-        (let ((nnmail-split-methods (list (list group ""))))
-          (setq result (car (nnml-save-mail))))
+        (setq result (car (nnml-save-mail 
+                           (list (cons group (nnml-active-number group))))))
         (progn
           (nnmail-save-active nnml-group-alist nnml-active-file)
           (and last (nnml-save-nov))))
       (and
        (nnmail-activate 'nnml)
-       (setq result (car (nnml-save-mail)))
+       (setq result (car (nnml-save-mail
+                         (nnmail-article-group 'nnml-active-number))))
        (progn
         (nnmail-save-active nnml-group-alist nnml-active-file)
         (and last (nnml-save-nov)))))
@@ -569,10 +568,9 @@ all. This may very well take some time.")
       (nnheader-message 5 "Creating mail directory %s" (car dirs))
       (setq dirs (cdr dirs)))))
             
-(defun nnml-save-mail ()
+(defun nnml-save-mail (group-art)
   "Called narrowed to an article."
-  (let ((group-art (nreverse (nnmail-article-group 'nnml-active-number)))
-       chars headers)
+  (let (chars headers)
     (setq chars (nnmail-insert-lines))
     (nnmail-insert-xref group-art)
     (run-hooks 'nnmail-prepare-save-mail-hook)
index 31ef601..fae954d 100644 (file)
@@ -369,11 +369,10 @@ The SOUP packet file name will be inserted at the %s.")
                 nnsoup-group-alist-touched))
     (setq nnsoup-group-alist-touched nil)
     (nnheader-temp-write nnsoup-active-file
-      (let ((standard-output (current-buffer)))
-       (prin1 `(setq nnsoup-group-alist ',nnsoup-group-alist))
-       (insert "\n")
-       (prin1 `(setq nnsoup-current-prefix ,nnsoup-current-prefix))
-       (insert "\n")))))
+      (gnus-prin1 `(setq nnsoup-group-alist ',nnsoup-group-alist))
+      (insert "\n")
+      (gnus-prin1 `(setq nnsoup-current-prefix ,nnsoup-current-prefix))
+      (insert "\n"))))
 
 (defun nnsoup-next-prefix ()
   "Return the next free prefix."
index a47f9f6..d54b4a4 100644 (file)
@@ -50,6 +50,9 @@ to allow posting from the server.  Note that this is only necessary to
 do on servers that use strict access control.")  
 (add-hook 'nntp-server-opened-hook 'nntp-send-mode-reader)
 
+(defvoo nntp-authinfo-function 'nntp-send-authinfo
+  "Function used to send AUTHINFO to the server.")
+
 (defvoo nntp-server-action-alist 
   '(("nntpd 1\\.5\\.11t" 
      (remove-hook 'nntp-server-opened-hook 'nntp-send-mode-reader)))
@@ -586,9 +589,12 @@ It will prompt for a password."
       (if (and (= beg (point-min))
               (memq (char-after beg) '(?4 ?5)))
          ;; Report back error messages.
-         (progn
-           (nntp-snarf-error-message)
-           (funcall nntp-process-callback nil))
+         (save-excursion
+           (goto-char beg)
+           (if (looking-at "480")
+               (funcall nntp-authinfo-function)
+             (nntp-snarf-error-message)
+             (funcall nntp-process-callback nil)))
        (goto-char end)
        (when (and (> (point) nntp-process-start-point)
                   (re-search-backward nntp-process-wait-for
@@ -654,7 +660,11 @@ It will prompt for a password."
   (save-excursion
     (set-buffer (process-buffer process))
     (goto-char (point-min))
-    (while (not (looking-at "[2345]"))
+    (while (or (not (memq (following-char) '(?2 ?3 ?4 ?5)))
+              (looking-at "480"))
+      (when (looking-at "480")
+       (erase-buffer)
+       (funcall nntp-authinfo-function))
       (nntp-accept-process-output process)
       (goto-char (point-min)))
     (prog1
diff --git a/lisp/nnweb.el b/lisp/nnweb.el
new file mode 100644 (file)
index 0000000..d5bd81a
--- /dev/null
@@ -0,0 +1,522 @@
+;;; nnweb.el --- retrieving articles via web search engines
+;; Copyright (C) 1996 Free Software Foundation, Inc.
+
+;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Keywords: news
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; 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., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Note: You need to have `url' and `w3' installed for this
+;; backend to work.
+
+;;; Code:
+
+(require 'nnoo)
+(require 'message)
+(require 'gnus-util)
+(require 'w3-forms)
+(require 'url)
+
+(nnoo-declare nnweb)
+
+(defvoo nnweb-type 'dejanews
+  "What search engine type is being used.")
+
+(defvar nnweb-type-definition
+  '((dejanews
+     (article . nnweb-dejanews-wash-article)
+     (map . nnweb-dejanews-create-mapping)
+     (search . nnweb-dejanews-search)
+     (address . "http://search.dejanews.com/dnquery.xp"))
+    (reference
+     (article . nnweb-reference-wash-article)
+     (map . nnweb-reference-create-mapping)
+     (search . nnweb-reference-search)
+     (address . "http://www.reference.com/cgi-bin/pn/go"))
+    (altavista
+     (article . nnweb-altavista-wash-article)
+     (map . nnweb-altavista-create-mapping)
+     (search . nnweb-altavista-search)
+     (address . "http://www.altavista.digital.com/cgi-bin/query")
+     (id . "/cgi-bin/news?id@%s")))
+  "Type-definition alist.")
+
+(defvoo nnweb-search nil
+  "Search string to feed to DejaNews.")
+
+(defvoo nnweb-max-hits 100
+  "Maximum number of hits to display.")
+
+;;; Internal variables
+
+(defvoo nnweb-articles nil)
+(defvoo nnweb-buffer nil)
+
+;;; Interface functions
+
+(nnoo-define-basics nnweb)
+
+(deffoo nnweb-retrieve-headers (articles &optional group server fetch-old)
+  (nnweb-possibly-change-server server)
+  (save-excursion
+    (set-buffer nntp-server-buffer)
+    (erase-buffer)
+    (let (article header)
+      (while (setq article (pop articles))
+       (when (setq header (cadr (assq article nnweb-articles)))
+         (nnheader-insert-nov header)))
+      'nov)))
+
+(deffoo nnweb-request-group (group &optional server dont-check)
+  (nnweb-possibly-change-server server)
+  (when (or (not dont-check)
+           (not nnweb-articles))
+    (funcall (nnweb-definition 'map)))
+  (cond
+   ((not nnweb-articles)
+    (nnheader-report 'nnweb "Couldn't request search"))
+   (t
+    (nnheader-report 'nnweb "Opened group %s" group)
+    (nnheader-insert
+     "211 %d %d %d %s\n" (length nnweb-articles)
+     (caar nnweb-articles) (caar (last nnweb-articles))
+      group))))
+
+(deffoo nnweb-request-article (article &optional group server buffer)
+  (nnweb-possibly-change-server server)
+  (save-excursion
+    (set-buffer (or buffer nntp-server-buffer))
+    (let ((url (caddr (assq article nnweb-articles))))
+      (when (or (and url
+                    (nnweb-fetch-url url))
+               (and (stringp article)
+                    (let ((fetch (nnweb-definition 'id))
+                          art)
+                      (when (string-match "^<\\(.*\\)>$" article)
+                        (setq art (match-string 1 article)))
+                      (and fetch
+                           art
+                           (nnweb-fetch-url
+                            (format fetch article))))))
+       (unless nnheader-callback-function
+         (funcall (nnweb-definition 'article))
+         (nnweb-decode-entities))
+       (nnheader-report 'nnweb "Fetched article %s" article)
+       t))))
+
+(deffoo nnweb-close-server (&optional server)
+  (when (nnweb-server-opened server)
+    (gnus-kill-buffer nnweb-buffer))
+  (nnoo-close-server 'nnweb server))
+
+(deffoo nnweb-request-update-info (group info &optional server)
+  (nnweb-possibly-change-server server)
+  (setcar (cddr info) nil))
+
+(deffoo nnweb-asynchronous-p ()
+  t)
+
+(nnoo-define-skeleton nnweb)
+
+;;; Internal functions
+
+(defun nnweb-definition (type)
+  "Return the definition of TYPE."
+  (let ((def (cdr (assq type (assq nnweb-type nnweb-type-definition)))))
+    (unless def
+      (error "Undefined definition %s" type))
+    def))
+
+(defun nnweb-possibly-change-server (&optional server)
+  (nnweb-init server)
+  (when server
+    (unless (nnweb-server-opened server)
+      (nnweb-open-server server))))
+
+(defun nnweb-init (server)
+  "Initialize buffers and such."
+  (unless (gnus-buffer-live-p nnweb-buffer)
+    (setq nnweb-buffer
+         (save-excursion
+           (nnheader-set-temp-buffer
+            (format " *nnweb %s %s %s*" nnweb-type nnweb-search server))))))
+
+(defun nnweb-fetch-url (url)
+  (save-excursion
+    (if (not nnheader-callback-function)
+       (let ((buf (current-buffer)))
+         (save-excursion
+           (set-buffer nnweb-buffer)
+           (erase-buffer)
+           (prog1
+               (url-insert-file-contents url)
+             (copy-to-buffer buf (point-min) (point-max)))))
+      (nnweb-url-retrieve-asynch
+       url 'nnweb-callback (current-buffer) nnheader-callback-function)
+      t)))
+
+(defun nnweb-callback (buffer callback)
+  (save-excursion
+    (set-buffer url-working-buffer)
+    (funcall (nnweb-definition 'article))
+    (nnweb-decode-entities)
+    (set-buffer buffer)
+    (goto-char (point-max))
+    (insert-buffer-substring url-working-buffer))
+  (funcall callback t)
+  (gnus-kill-buffer url-working-buffer))
+
+(defun nnweb-url-retrieve-asynch (url callback &rest data)
+  (let ((url-request-method "GET")
+       (old-asynch url-be-asynchronous)
+       (url-request-data nil)
+       (url-request-extra-headers nil)
+       (url-working-buffer (generate-new-buffer-name " *dejanews*")))
+    (setq-default url-be-asynchronous t)
+    (save-excursion
+      (set-buffer (get-buffer-create url-working-buffer))
+      (setq url-current-callback-data data
+           url-be-asynchronous t
+           url-current-callback-func callback)
+      (url-retrieve url))
+    (setq-default url-be-asynchronous old-asynch)))
+
+(defun nnweb-encode-www-form-urlencoded (pairs)
+  "Return PAIRS encoded for forms."
+  (mapconcat 
+    (function
+      (lambda (data)
+        (concat (w3-form-encode-xwfu (car data)) "="
+                (w3-form-encode-xwfu (cdr data))))) pairs "&"))
+
+(defun nnweb-fetch-form (url pairs)
+  (let ((url-request-data (nnweb-encode-www-form-urlencoded pairs))
+       (url-request-method 'POST)
+       (url-request-extra-headers 
+        '(("Content-type" . "application/x-www-form-urlencoded"))))
+    (url-insert-file-contents url)))
+
+(defun nnweb-decode-entities ()
+  (goto-char (point-min))
+  (while (re-search-forward "&\\([a-z]+\\);" nil t)
+    (replace-match (char-to-string (or (cdr (assq (intern (match-string 1))
+                                                 w3-html-entities ))
+                                      ?#))
+                  t t)))
+
+(defun nnweb-remove-markup ()
+  (goto-char (point-min))
+  (while (search-forward "<!--" nil t)
+    (delete-region (match-beginning 0)
+                  (or (search-forward "-->" nil t)
+                      (point-max))))
+  (goto-char (point-min))
+  (while (re-search-forward "<[^>]+>" nil t)
+    (replace-match "" t t)))
+
+;;;
+;;; DejaNews functions.
+;;;
+
+(defun nnweb-dejanews-create-mapping ()
+  "Perform the search and create an number-to-url alist."
+  (save-excursion
+    (set-buffer nnweb-buffer)
+    (erase-buffer)
+    (when (funcall (nnweb-definition 'search) nnweb-search)
+      (let ((i 0)
+           (more t)
+           Subject Score Date Newsgroup Author
+           map url)
+       (while more
+         ;; Go through all the article hits on this page.
+         (goto-char (point-min))
+         (nnweb-decode-entities)
+         (goto-char (point-min))
+         (while (re-search-forward "^ +[0-9]+\\." nil t)
+           (narrow-to-region 
+            (point) 
+            (if (re-search-forward "^ +[0-9]+\\." nil t)
+                (match-beginning 0)
+              (point-max)))
+           (goto-char (point-min))
+           (when (looking-at ".*HREF=\"\\([^\"]+\\)\"")
+             (setq url (match-string 1)))
+           (nnweb-remove-markup)
+           (goto-char (point-min))
+           (while (search-forward "\t" nil t)
+             (replace-match " "))
+           (goto-char (point-min))
+           (while (re-search-forward "^ +\\([^:]+\\): +\\(.*\\)$" nil t)
+             (set (intern (match-string 1)) (match-string 2)))
+           (widen)
+           (when (string-match "#[0-9]+/[0-9]+ *$" Subject)
+             (setq Subject (substring Subject 0 (match-beginning 0))))
+           (push
+            (list
+             (incf i)
+             (make-full-mail-header
+              i (concat  "(" Newsgroup ") " Subject) Author Date
+              (concat "<" (message-unique-id) "-" (int-to-string i)
+                      "@dejanews>")
+              nil 0 (string-to-int Score) nil)
+             url)
+            map))
+         ;; See whether there is a "Get next 20 hits" button here.
+         (if (or (not (re-search-forward
+                       "HREF=\"\\([^\"]+\\)\">Get next" nil t))
+                 (> i nnweb-max-hits))
+             (setq more nil)
+           ;; Yup -- fetch it.
+           (setq more (match-string 1))
+           (erase-buffer)
+           (url-insert-file-contents more)))
+       ;; Return the articles in the right order.
+       (setq nnweb-articles (nreverse map))))))
+
+(defun nnweb-dejanews-wash-article ()
+  (goto-char (point-min))
+  (re-search-forward "<PRE>" nil t)
+  (delete-region (point-min) (point))
+  (re-search-forward "</PRE>" nil t)
+  (delete-region (point) (point-max))
+  (nnweb-remove-markup)
+  (goto-char (point-min))
+  (while (and (looking-at " *$")
+             (not (eobp)))
+    (gnus-delete-line))
+  (while (looking-at "\\(^[^ ]+:\\) *")
+    (replace-match "\\1 " t)
+    (forward-line 1))
+  (when (re-search-forward "\n\n+" nil t)
+    (replace-match "\n" t t)))
+
+(defun nnweb-dejanews-search (search)
+  (nnweb-fetch-form 
+   (nnweb-definition 'address)
+   `(("query" . ,search)
+     ("defaultOp" . "AND")
+     ("svcclass" . "dncurrent")
+     ("maxhits" . "100")
+     ("format" . "verbose")
+     ("threaded" . "0")
+     ("showsort" . "score")
+     ("agesign" . "1")
+     ("ageweight" . "1"))))
+
+;;;
+;;; InReference
+;;;
+
+(defun nnweb-reference-create-mapping ()
+  "Perform the search and create an number-to-url alist."
+  (save-excursion
+    (set-buffer nnweb-buffer)
+    (erase-buffer)
+    (when (funcall (nnweb-definition 'search) nnweb-search)
+      (let ((i 0)
+           (more t)
+           Subject Score Date Newsgroups From Message-ID
+           map url)
+       (while more
+         ;; Go through all the article hits on this page.
+         (goto-char (point-min))
+         (search-forward "</pre><hr>" nil t)
+         (delete-region (point-min) (point))
+         ;(nnweb-decode-entities)
+         (goto-char (point-min))
+         (while (re-search-forward "^ +[0-9]+\\." nil t)
+           (narrow-to-region 
+            (point) 
+            (if (re-search-forward "^$" nil t)
+                (match-beginning 0)
+              (point-max)))
+           (goto-char (point-min))
+           (when (looking-at ".*href=\"\\([^\"]+\\)\"")
+             (setq url (match-string 1)))
+           (nnweb-remove-markup)
+           (goto-char (point-min))
+           (while (search-forward "\t" nil t)
+             (replace-match " "))
+           (goto-char (point-min))
+           (while (re-search-forward "^\\([^:]+\\): \\(.*\\)$" nil t)
+             (set (intern (match-string 1)) (match-string 2)))
+           (widen)
+           (search-forward "</pre>" nil t)
+           (push
+            (list
+             (incf i)
+             (make-full-mail-header
+              i (concat  "(" Newsgroups ") " Subject) From Date
+              Message-ID
+              nil 0 (string-to-int Score) nil)
+             url)
+            map))
+         (setq more nil))
+       ;; Return the articles in the right order.
+       (setq nnweb-articles (nreverse map))))))
+
+(defun nnweb-reference-wash-article ()
+  (goto-char (point-min))
+  (re-search-forward "^</center><hr>" nil t)
+  (delete-region (point-min) (point))
+  (search-forward "<pre>" nil t)
+  (forward-line -1)
+  (let ((body (point-marker)))
+    (search-forward "</pre>" nil t)
+    (delete-region (point) (point-max))
+    (nnweb-remove-markup)
+    (goto-char (point-min))
+    (while (looking-at " *$")
+      (gnus-delete-line))
+    (narrow-to-region (point-min) body)
+    (while (and (re-search-forward "^$" nil t)
+               (not (eobp)))
+      (gnus-delete-line))
+    (goto-char (point-min))
+    (while (looking-at "\\(^[^ ]+:\\) *")
+      (replace-match "\\1 " t)
+      (forward-line 1))
+    (goto-char (point-min))
+    (when (re-search-forward "^References:" nil t)
+      (narrow-to-region
+       (point) (if (re-search-forward "^$\\|^[^:]+:" nil t)
+                  (match-beginning 0)
+                (point-max)))
+      (goto-char (point-min))
+      (while (not (eobp))
+       (unless (looking-at "References")
+         (insert "\t")
+         (forward-line 1)))
+      (goto-char (point-min))
+      (while (search-forward "," nil t)
+       (replace-match " " t t)))
+    (widen)
+    (set-marker body nil)))
+
+(defun nnweb-reference-search (search)
+  (url-insert-file-contents
+   (concat 
+    (nnweb-definition 'address)
+    "?"
+    (nnweb-encode-www-form-urlencoded 
+     `(("search" . "advanced")
+       ("querytext" . ,search)
+       ("subj" . "")
+       ("name" . "")
+       ("login" . "")
+       ("host" . "")
+       ("organization" . "")
+       ("groups" . "")
+       ("keywords" . "")
+       ("choice" . "Search")
+       ("startmonth" . "Jul")
+       ("startday" . "25")
+       ("startyear" . "1996")
+       ("endmonth" . "Aug")
+       ("endday" . "24")
+       ("endyear" . "1996")
+       ("mode" . "Quick")
+       ("verbosity" . "Verbose")
+       ("ranking" . "Relevance")
+       ("first" . "1")
+       ("last" . "25")
+       ("score" . "50"))))))
+
+;;;
+;;; Alta Vista
+;;;
+
+(defun nnweb-altavista-create-mapping ()
+  "Perform the search and create an number-to-url alist."
+  (save-excursion
+    (set-buffer nnweb-buffer)
+    (erase-buffer)
+    (when (funcall (nnweb-definition 'search) nnweb-search)
+      (let ((i 0)
+           (more t)
+           Subject Score Date Newsgroups From Message-ID
+           map url)
+       (while more
+         ;; Go through all the article hits on this page.
+         (goto-char (point-min))
+         (search-forward "<dt>" nil t)
+         (delete-region (point-min) (match-beginning 0))
+         (goto-char (point-min))
+         (while (search-forward "<dt>" nil t)
+           (replace-match "\n<blubb>"))
+         (nnweb-decode-entities)
+         (goto-char (point-min))
+         (while (re-search-forward "<blubb>.*href=\"\\([^\"]+\\)\"><strong>\\([^>]*\\)</strong></a><dd>\\([^-]+\\)- <b>\\([^<]+\\)<.*href=\"news:\\([^\"]+\\)\">.*\">\\(.+\\)</a><P>"
+                                   nil t)
+           (setq url (match-string 1)
+                 subject (match-string 2)
+                 date (match-string 3)
+                 group (match-string 4)
+                 id (concat "<" (match-string 5) ">")
+                 from (match-string 6))
+           (push
+            (list
+             (incf i)
+             (make-full-mail-header
+              i (concat  "(" group ") " subject) from date
+              id nil 0 0 nil)
+             url)
+            map))
+         (setq more nil))
+       ;; Return the articles in the right order.
+       (setq nnweb-articles (nreverse map))))))
+
+(defun nnweb-altavista-wash-article ()
+  (goto-char (point-min))
+  (let (subject)
+    (when (re-search-forward "<H1>\\(.*\\)</H1>" nil t)
+      (setq subject (match-string 1)))
+    (re-search-forward "^<strong>" nil t)
+    (delete-region (point-min) (match-beginning 0))
+    (goto-char (point-min))
+    (while (looking-at "<strong>\\([^ ]+\\) +</strong> +\\(.*\\)$")
+      (replace-match "\\1: \\2" t)
+      (forward-line 1))
+    (when (re-search-backward "^References:" nil t)
+      (narrow-to-region (point) (progn (forward-line 1) (point)))
+      (goto-char (point-min))
+      (while (re-search-forward "<A.*\\?id@\\([^\"]+\\)\">[0-9]+</A>" nil t)
+       (replace-match "&lt;\\1&gt; " t))
+      (widen)
+      (nnweb-remove-markup))))
+
+(defun nnweb-altavista-search (search)
+  (url-insert-file-contents
+   (concat 
+    (nnweb-definition 'address)
+    "?"
+    (nnweb-encode-www-form-urlencoded 
+     `(("pg" . "aq")
+       ("what" . "news")
+       ("fmt" . "d")
+       ("q" . ,search)
+       ("r" . "")
+       ("d0" . "")
+       ("d1" . ""))))))
+
+(provide 'nnweb)
+
+;;; nnweb.el ends here
index f7c9867..66ec474 100644 (file)
@@ -253,6 +253,9 @@ Return the response string if optional second argument is non-nil."
                (pop3-quit process)))))
     ))
 
+(eval-and-compile
+  (if (not (fboundp 'md5)) (autoload 'md5 "md5")))
+
 (defun pop3-apop (process user)
   "Send alternate authentication information to the server."
   (if (not (fboundp 'md5)) (autoload 'md5 "md5"))
index edd3285..6f71d05 100644 (file)
@@ -103,6 +103,11 @@ If this is a symbol, take its value.")
 (defvar smiley-glyph-cache nil)
 (defvar smiley-running-xemacs (string-match "XEmacs" emacs-version))
 
+(defvar smiley-map (make-sparse-keymap "smiley-keys")
+ "keymap to toggle smiley states")
+
+(define-key smiley-map [(button2)] 'smiley-toggle-extent)
+
 (defun smiley-create-glyph (smiley pixmap)
   (and
    smiley-running-xemacs
@@ -128,6 +133,23 @@ If this is a symbol, take its value.")
   (interactive "r")
   (smiley-buffer (current-buffer) beg end))
 
+(defun smiley-toggle-extent (event)
+  "Toggle smiley at given point"
+  (interactive "e")
+  (let* ((ant (event-glyph-extent event))
+        (pt (event-closest-point event))
+        ext)
+    (if (annotationp ant)
+       (when (extentp (setq ext (extent-property ant 'smiley-extent)))
+         (set-extent-property ext 'invisible nil)
+         (hide-annotation ant))
+      (if pt
+         (while (setq ext (extent-at pt (event-buffer event) nil ext 'at))
+           (when (annotationp (setq ant 
+                                    (extent-property ext 'smiley-annotation)))
+             (reveal-annotation ant)
+             (set-extent-property ext 'invisible t)))))))
+
 ;;;###autoload
 (defun smiley-buffer (&optional buffer st nd)
   (interactive)
@@ -155,11 +177,20 @@ If this is a symbol, take its value.")
                                               file)))
              (when glyph
                (mapcar 'delete-annotation (annotations-at end))
-               (let ((ext (make-extent start end)))
+               (let ((ext (make-extent start end))
+                     (ant (make-annotation glyph end 'text)))
+                 ;; set text extent params
                  (set-extent-property ext 'invisible t)
                  (set-extent-property ext 'end-open t)
-                 (set-extent-property ext 'intangible t))
-               (make-annotation glyph end 'text)
+                 (set-extent-property ext 'keymap smiley-map)
+                 (set-extent-property ext 'mouse-face gnus-article-mouse-face)
+;                (set-extent-property ext 'intangible t)
+                 ;; set annotation params
+                 (set-extent-property ant 'mouse-face gnus-article-mouse-face)
+                 (set-extent-property ant 'keymap smiley-map)
+                 ;; remember each other
+                 (set-extent-property ant 'smiley-extent ext)
+                 (set-extent-property ext 'smiley-annotation ant))
                (when (smiley-end-paren-p start end)
                  (make-annotation ")" end 'text))
                (goto-char end)))))))))
index 213e7d2..1d19cd3 100644 (file)
@@ -3,6 +3,30 @@ Sat Aug 17 22:24:34 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
        * gnus.texi (Startup Files): Addition.
        (Anything Groups): Addition.
 
+Thu Aug 22 17:27:31 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (Adaptive Scoring): Addition.
+       (Adaptive Scoring): Addition.
+
+Mon Aug 19 00:30:07 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (Fancy Mail Splitting): Addition.
+       (Splitting Mail): Addition.
+       (Group Parameters): Addition.
+       (Topic Variables): Addition.
+       (Mail Group Commands): Addition.
+       (Group Information): Addition.
+       (Article Washing): Addition.
+
+Sun Aug 18 18:06:49 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (Web Searches): Change and addition.
+
+Sat Aug 17 22:24:34 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (Startup Files): Addition.
+       (Anything Groups): Addition.
+
 Thu Aug 15 17:59:12 1996  Lars Magne Ingebrigtsen  <lars@eyesore.no>
 
        * gnus.texi (Followups To Yourself): Addition.
index 03d7a4f..c65d5a2 100644 (file)
@@ -1650,12 +1650,16 @@ guess at the file type.  @xref{Document Groups}.
 
 @item G n
 @kindex G n (Group)
-@findex gnus-group-make-dejagnus-group
+@findex gnus-group-make-web-group
 @cindex DejaNews
-Make an ephemeral group based on a DejaNews search
-(@code{gnus-group-make-dejagnus-group}).  If you give a prefix to this
+@cindex Alta Vista
+@cindex InReference
+Make an ephemeral group based on a web search
+(@code{gnus-group-make-web-group}).  If you give a prefix to this
 command, make a solid group instead.  You will be prompted for the
-search.  @xref{DejaNews Searches}.
+search engine type and the search string.  Legal search engine types
+include @code{dejanews}, @code{altavista} and @code{reference}.
+@xref{Web Searches}.
 
 @item G DEL
 @kindex G DEL (Group)
@@ -1800,6 +1804,19 @@ unsubscription notice to the mailing list itself.  Instead, you'd send
 messages to the administrative address.  This parameter allows you to
 put the admin address somewhere convenient.
 
+@item display
+Elements that look like @code{(display . MODE)} says which articles to
+display on entering the group.  Legal values are:
+
+@table @code
+@item all
+Display all articles, both read and unread.
+
+@item default
+Display the default visible articles, which normally includes unread and
+ticked articles.
+@end table
+
 @item comment
 This parameter allows you to enter a arbitrary comment on the group.
 
@@ -2248,6 +2265,10 @@ The default is @code{2}.
 @vindex gnus-topic-mode-hook
 @code{gnus-topic-mode-hook} is called in topic minor mode buffers. 
 
+@vindex gnus-topic-display-empty-topics
+The @code{gnus-topic-display-empty-topics} says whether to display even
+topics that have no unread articles in them.  The default is @code{t}.
+
 
 @node Topic Commands
 @subsection Topic Commands
@@ -2571,12 +2592,19 @@ news.
 @item M-f
 @kindex M-f (Group)
 @findex gnus-group-fetch-faq
+@vindex gnus-group-faq-directory
 @cindex FAQ
 @cindex ange-ftp
 Try to fetch the FAQ for the current group
 (@code{gnus-group-fetch-faq}).  Gnus will try to get the FAQ from
 @code{gnus-group-faq-directory}, which is usually a directory on a
-remote machine.  @code{ange-ftp} will be used for fetching the file.
+remote machine.  This variable can also be a list of directories.  In
+that case, giving a prefix to this command will allow you to choose
+between the various sites.  @code{ange-ftp} will be used for fetching
+the file.  
+
+If fetching from the first site is unsuccessful, Gnus will attempt to go
+through @code{gnus-group-faq-directory} and try to open them one by one.
 
 @item D
 @kindex D (Group)
@@ -5413,12 +5441,6 @@ late and certainly after any highlighting.
 @findex gnus-article-remove-cr
 Remove CR (@code{gnus-article-remove-cr}).
 
-@item W L
-@kindex W L (Summary)
-@findex gnus-article-remove-trailing-blank-lines
-Remove all blank lines at the end of the article
-(@code{gnus-article-remove-trailing-blank-lines}).
-
 @item W q
 @kindex W q (Summary)
 @findex gnus-article-de-quoted-unreadable
@@ -5458,6 +5480,31 @@ Add clickable buttons to the article (@code{gnus-article-add-buttons}).
 Add clickable buttons to the article headers
 (@code{gnus-article-add-buttons-to-head}).  
 
+@item W E l
+@kindex W E l (Summary)
+@findex gnus-article-strip-leading-blank-lines
+Remove all blank lines from the beginning of the article
+(@code{gnus-article-strip-leading-blank-lines}).
+
+@item W E m
+@kindex W E m (Summary)
+@findex gnus-article-strip-multiple-blank-lines
+Replace all blank lines with empty lines and then all multiple empty
+lines with a single empty line.
+(@code{gnus-article-strip-multiple-blank-lines}).
+
+@item W E t
+@kindex W E t (Summary)
+@findex gnus-article-remove-trailing-blank-lines
+Remove all blank lines at the end of the article
+(@code{gnus-article-remove-trailing-blank-lines}).
+
+@item W E a
+@kindex W E a (Summary)
+@findex gnus-article-strip-blank-lines
+Do all the three commands above
+(@code{gnus-article-strip-blank-lines}).
+
 @end table
 
 
@@ -5693,6 +5740,13 @@ can just press @kbd{^} or @kbd{A r}
 you'll get the parent.  If the parent is already displayed in the
 summary buffer, point will just move to this article.
 
+If given a positive numerical prefix, fetch that many articles back into
+the ancestry.  If given a negative numerical prefix, fetch just that
+ancestor.  So if you say @kbd{3 ^}, Gnus will fetch the parent, the
+grandparent and the grandgrandparent of the current article.  If you say
+@kbd{-3 ^}, Gnus will only fetch the grandgrandparent of the current
+article. 
+
 @findex gnus-summary-refer-references
 @kindex A R (Summary)
 You can have Gnus fetch all articles mentioned in the @code{References}
@@ -6075,6 +6129,21 @@ editing and make the changes permanent, type @kbd{C-c C-c}
 If you want to re-spool an article, you might be curious as to what group
 the article will end up in before you do the re-spooling.  This command
 will tell you (@code{gnus-summary-respool-query}). 
+
+@item B p
+@kindex B p (Summary)
+@findex gnus-summary-article-posted-p
+Some people have a tendency to send you "courtesy" copies when they
+follow up to articles you have posted.  These usually have a
+@code{Newsgroups} header in them, but not always.  This command
+(@code{gnus-summary-article-posted-p}) will try to fetch the current
+article from your news server (or rather, from
+@code{gnus-refer-article-method} or @code{gnus-select-method}) and will
+report back whether it found the article or not.  Even if it says that
+it didn't find the article, it may have been posted anyway---mail
+propagation is much faster than news propagation, and the news copy may
+just not have arrived yet.
+
 @end table
 
 @vindex gnus-move-split-methods
@@ -7579,9 +7648,28 @@ server:
 @code{nntp-server-opened-hook} is run after a connection has been made.
 It can be used to send commands to the @sc{nntp} server after it has
 been contacted.  By default is sends the command @code{MODE READER} to
-the server with the @code{nntp-send-mode-reader} function.  Another
-popular function is @code{nntp-send-authinfo}, which will prompt you for
-an @sc{nntp} password and stuff.
+the server with the @code{nntp-send-mode-reader} function. 
+
+@item nntp-authinfo-function 
+@vindex nntp-authinfo-function 
+This function will be used to send @samp{AUTHINFO} to the @sc{nntp}
+server.  Available functions include:
+
+@table @code
+@item nntp-send-authinfo
+@findex nntp-send-authinfo
+This function will used you current login name as the user name and will
+prompt you for the password.  This is the default.
+
+@item nntp-send-nosy-authinfo
+@findex nntp-send-nosy-authinfo
+This function will prompt you for both user name and password.
+
+@item nntp-send-authinfo-from-file
+@findex nntp-send-authinfo-from-file
+This function will use your current login name as the user name and will
+read the @sc{nntp} password from @file{~/.nntp-authinfo}.
+@end table
 
 @item nntp-server-action-alist 
 @vindex nntp-server-action-alist 
@@ -7893,6 +7981,10 @@ something beginning with @samp{mail}, by the way), and the second
 element is a regular expression used on the header of each mail to
 determine if it belongs in this mail group.
 
+If the first element is the special symbol @code{junk}, then messages
+that match the regexp will disappear into the aether.  Use with
+extreme caution. 
+
 The second element can also be a function.  In that case, it will be
 called narrowed to the headers with the first element of the rule as the
 argument.  It should return a non-@code{nil} value if it thinks that the
@@ -8000,6 +8092,17 @@ other spool files.
 This is run in a buffer that holds all the new incoming mail, and can be
 used for, well, anything, really.
 
+@vindex nnmail-split-hook
+@item nnmail-split-hook
+@findex article-decode-rfc1522
+@findex RFC1522 decoding
+Hook run in the buffer where the mail headers of each message is kept
+just before the splitting based on these headers is done.  The hook is
+free to modify the buffer contents in any way it sees fit---the buffer
+is discarded after the splitting has been done, and no changes perfromed
+in the buffer will show up in any files.  @code{article-decode-rfc1522}
+is one likely function to add to this hook.
+
 @vindex nnmail-pre-get-new-mail-hook
 @vindex nnmail-post-get-new-mail-hook
 @item nnmail-pre-get-new-mail-hook
@@ -8072,7 +8175,7 @@ Function called to delete files.  It is @code{delete-file} by default.
 If the rather simple, standard method for specifying how to split mail
 doesn't allow you to do what you want, you can set
 @code{nnmail-split-methods} to @code{nnmail-split-fancy}.  Then you can
-play with the @code{nnmail-split-fancy} variable. 
+play with the @code{nnmail-split-fancy} variable.
 
 Let's look at an example value of this variable first:
 
@@ -8098,7 +8201,7 @@ Let's look at an example value of this variable first:
 
 This variable has the format of a @dfn{split}.  A split is a (possibly)
 recursive structure where each split may contain other splits.  Here are
-the four possible split syntaxes:
+the five possible split syntaxes:
 
 @table @dfn
 
@@ -8119,6 +8222,9 @@ more groups.
 @item (& SPLIT...)
 If the split is a list, and the first element is @code{&}, then process
 all SPLITs in the list.
+
+@item junk
+Junk this article.
 @end table
 
 In these splits, FIELD must match a complete field name.  VALUE must
@@ -8662,7 +8768,7 @@ newsgroups.
 * Anything Groups::       Dired?  Who needs dired?
 * Document Groups::       Single files can be the basis of a group.
 * SOUP::                  Reading @sc{SOUP} packets ``offline''.
-* DejaNews Searches::     Creating groups from articles that match a string.
+* Web Searches::          Creating groups from articles that match a string.
 * Mail-To-News Gateways:: Posting articles via mail-to-news gateways.
 @end menu
 
@@ -9210,10 +9316,12 @@ system you just use the first line.  If you only want mail to be
 @sc{soup}ed you use the second.
 
 
-@node DejaNews Searches
-@subsection DejaNews Searches
-@cindex nndejagnus
+@node Web Searches
+@subsection Web Searches
+@cindex nnweb
 @cindex DejaNews
+@cindex Alta Vista
+@cindex InReference
 @cindex Usenet searches
 @cindex searching the Usenet
 
@@ -9223,42 +9331,76 @@ those, like, Web browsers, and you, like, have to, rilly, like, look at
 the commercials, so, like, with Gnus you can do @emph{rad}, rilly,
 searches without having to use a browser.
 
-The @code{nndejagnus} (hey, I wonder if they're going to sue me over
-copyright infringement?) backend allows an easy interface to the mighty
-search engine.  You create an @code{nndejagnus} group, enter a search
-pattern, and then enter the group and read the articles like you would
-any normal group.  The @kbd{G n} command in the group buffer
-(@pxref{Foreign Groups}) will do this in an easy-to-use fashion.
+The @code{nnweb} backend allows an easy interface to the mighty search
+engine.  You create an @code{nnweb} group, enter a search pattern, and
+then enter the group and read the articles like you would any normal
+group.  The @kbd{G n} command in the group buffer (@pxref{Foreign
+Groups}) will do this in an easy-to-use fashion.
 
-@code{nndejagnus} groups don't really lend themselves to being solid
+@code{nnweb} groups don't really lend themselves to being solid
 groups---they have a very fleeting idea of article numbers.  In fact,
-each time you enter an @code{nndejagnus} group (not changing the search
+each time you enter an @code{nnweb} group (not even changing the search
 pattern), you are likely to get the articles ordered in a different
 manner.  Not even using duplicate suppression (@code{Duplicate
-Suppression}) will help, since @code{nndejagnus} doesn't even know the
-@code{Message-ID} of the articles before reading them.  The only
-possible way to keep track of which articles you've read is by scoring
-on the @code{Date} header---mark all articles that were posted before
-the last date you read the group as read.
+Suppression}) will help, since @code{nnweb} doesn't even know the
+@code{Message-ID} of the articles before reading them using some search
+engines (DejaNews, for instance).  The only possible way to keep track
+of which articles you've read is by scoring on the @code{Date}
+header---mark all articles that were posted before the last date you
+read the group as read.
+
+If the search engine changes its output substantially, @code{nnweb}
+won't be able to parse it and will fail.  One could hardly fault the Web
+providers if they were to do this---their @emph{raison d'etre} is to
+make money off of advertisements, not to provide services to the
+community.  Since @code{nnweb} washes the ads off all the articles, one
+might think that the providers might be somewhat miffed.  We'll see.
 
 You must have the @code{url} and @code{w3} package installed to be able
-to use @code{nndejagnus}.
+to use @code{nnweb}.
 
 Virtual server variables:
 
 @table @code
-@item nndejagnus-address
-@vindex nndejagnus-address
-The address of the DejaNews search engine.  The default is
-@samp{http://www.dejagnus.com}. 
+@item nnweb-type
+@vindex nnweb-type
+What search engine type is being used.  The currently supported types
+are @code{dejanews}, @code{altavista} and @code{reference}.
+
+@item nnweb-search
+@vindex nnweb-search
+The search string to feed to the search engine.
+
+@item nnweb-max-hits
+@vindex nnweb-max-hits
+Advisory maximum number of hits per search to display.  The default is
+100.
+
+@item nnweb-type-definition
+@vindex nnweb-type-definition
+Type-to-definition alist.  This alist says what @code{nnweb} should do
+with the various search engine types.  The following elements must be
+present: 
+
+@table @code
+@item article
+Function to decode the article and provide something that Gnus
+understands. 
+
+@item map
+Function to create an article number to message header and URL alist. 
 
-@item nndejagnus-search
-@vindex nndejagnus-search
-The search string to feed to DejaNews.
+@item search
+Function to send the search string to the search engine.
+
+@item address
+The address the aforementioned function should send the search string
+to. 
+
+@item id
+Format string URL to fetch an article by @code{Message-ID}.
+@end table
 
-@item nndejagnus-max-hits
-@vindex nndejagnus-max-hits
-Maximum number of hits per search to display.  The default is 100.
 @end table
 
 
@@ -10269,9 +10411,16 @@ word that appears in subjects of articles that are marked with
 @code{gnus-read-mark} will result in a score rule that increase the
 score with 30 points.
 
+@vindex gnus-default-ignored-adaptive-words
 @vindex gnus-ignored-adaptive-words
-Words that appear in the @code{gnus-ignored-adaptive-words} list will be
-ignored.
+Words that appear in the @code{gnus-default-ignored-adaptive-words} list
+will be ignored.  If you wish to add more words to be ignored, use the
+@code{gnus-ignored-adaptive-words} list instead.
+
+@vindex gnus-adaptive-word-syntax-table
+When the scoring is done, @code{gnus-adaptive-word-syntax-table} is the
+syntax table in effect.  It is similar to the standard syntax table, but
+it considers numbers to be non-word-consituant characters.
 
 After using this scheme for a while, it might be nice to write a
 @code{gnus-psychoanalyze-user} command to go through the rules and see